delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2003/05/18/01:11:20

Message-ID: <002301c31cfb$6ebfabd0$0100a8c0@acp42g>
From: "Andrew Cottrell" <acottrel AT ihug DOT com DOT au>
To: <djgpp-workers AT delorie DOT com>
Subject: GCC 3.3 & LIBC warning 1st pass
Date: Sun, 18 May 2003 15:04:34 +1000
MIME-Version: 1.0
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 6.00.2800.1158
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
Reply-To: djgpp-workers AT delorie DOT com

All,

There are allot of the "dereferencing type-punned pointer will break
strict-aliasing rules" issues with the LIBC source when built with GCC 3.3.
There are a few others, but these are account for the vast majority. Below
is the info from GCC 3.3 on the subject and sample from doprint.c on two of
the warnings. I cannot see an easy way to fix this.

How do people want to fix this?

Please note that you need to delete the -Werror in order to build LIBC.

Andrew

========================= GCC 3.3 GCC.INFO info ==========================
Info from the GCC 3.3. gcc.info file:-
`-Wstrict-aliasing'
     This option is only active when `-fstrict-aliasing' is active.  It
     warns about code which might break the strict aliasing rules that
     the compiler is using for optimization. The warning does not catch
     all cases, but does attempt to catch the more common pitfalls. It
     is included in `-Wall'.
`-fstrict-aliasing'
     Allows the compiler to assume the strictest aliasing rules
     applicable to the language being compiled.  For C (and C++), this
     activates optimizations based on the type of expressions.  In
     particular, an object of one type is assumed never to reside at
     the same address as an object of a different type, unless the
     types are almost the same.  For example, an `unsigned int' can
     alias an `int', but not a `void*' or a `double'.  A character type
     may alias any other type.

     Pay special attention to code like this:
          union a_union {
            int i;
            double d;
          };

          int f() {
            a_union t;
            t.d = 3.0;
            return t.i;
          }
     The practice of reading from a different union member than the one
     most recently written to (called "type-punning") is common.  Even
     with `-fstrict-aliasing', type-punning is allowed, provided the
     memory is accessed through the union type.  So, the code above
     will work as expected.  However, this code might not:
          int f() {
            a_union t;
            int* ip;
            t.d = 3.0;
            ip = &t.i;
            return *ip;
          }
          }

     Every language that wishes to perform language-specific alias
     analysis should define a function that computes, given an `tree'
     node, an alias set for the node.  Nodes in different alias sets
     are not allowed to alias.  For an example, see the C front-end
     function `c_get_alias_set'.

     Enabled at levels `-O2', `-O3', `-Os'.

========================= PROBLEM  ==========================
gcc ... -c doprnt.c
doprnt.c: In function `_doprnt':
doprnt.c:282: warning: dereferencing type-punned pointer will break
strict-aliasing rules
doprnt.c: In function `isspeciall':
doprnt.c:900: warning: dereferencing type-punned pointer will break
strict-aliasing rules

 if (flags&LONGINT)
   prec = DEFLPREC;
 else
   prec = DEFPREC;
      }
      /*
       * softsign avoids negative 0 if _double is < 0 and
       * no significant digits will be shown
       */
      if (_ldouble < 0)
      {
 softsign = '-';
 _ldouble = -_ldouble;
 neg_ldouble = 1;
      }
      else
      {
 struct IEEExp {
   unsigned manl:32;
   unsigned manh:32;
   unsigned exp:15;
   unsigned sign:1;
LINE 282>>>>> } ip = *(struct IEEExp *)&_ldouble;

 if (ip.sign)
   neg_ldouble = 1;
 else
   neg_ldouble = 0;
 softsign = 0;
      }
      /*
       * cvt may have to round up past the "start" of the
       * buffer, i.e. ``intf("%.2f", (double)9.999);'';
       * if the first char isn't NULL, it did.
       */
      *buf = NULL;
      size = cvtl(_ldouble, prec, flags, &softsign, *fmt, buf,
    buf + sizeof(buf));
      /*
       * If the format specifier requested an explicit sign,
       * we print a negative sign even if no significant digits
       * will be shown, and we also print a sign for a NaN.  In
       * other words, "%+f" might print -0.000000, +NaN and -NaN.
       */

static int
isspeciall(long double d, char *bufp)
{
  struct IEEExp {
    unsigned manl:32;
    unsigned manh:32;
    unsigned exp:15;
    unsigned sign:1;
LINE 900>>>>>  } *ip = (struct IEEExp *)&d;

  nan_p = 0;  /* don't assume the static is 0 (emacs) */

  /* Unnormals: the MSB of mantissa is non-zero, but the exponent is
     not zero either.  */
  if ((ip->manh & 0x80000000U) == 0 && ip->exp != 0)
  {


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019