Strange CPP failures

Neil Booth neil@daikokuya.co.uk
Tue Jul 16 14:27:00 GMT 2002


Jason R Thorpe wrote:-

> Well, in this particular case:
> 
> #if (+1 - 2) > 0        
> # error one
> #endif
> 
> #if (+1U - 2) < 0
> # error two
> #endif
> 
> ...produces:
> 
> yeah-baby:thorpej 448$ /usr/local/gnu/bin/gcc -E foo.c 
> # 1 "foo.c"
> # 1 "<built-in>"
> # 1 "<command line>"
> # 1 "foo.c"
> foo.c:6:3: #error two
> yeah-baby:thorpej 449$ 
> 
> ...so the result is somehow not ending up as unsigned.

...and that is because 2.95.3 is miscompiling the function
cpp_interpret_integer() [in debugging this, I noticed a slip
with -Wtraditional which no-one has noticed; I'll send a
patch soon.]

Here is a testcase, copied from cppexp.c, with much irrelevant
gunk eliminated:

typedef unsigned int cpp_num_part;
typedef struct cpp_num cpp_num;
typedef char _Bool;
typedef bool _Bool;
struct cpp_num
{
  cpp_num_part high;
  cpp_num_part low;
  bool unsignedp;  /* True if value should be treated as unsigned.  */
  bool overflow;   /* True if the most recent calculation overflowed.
*/
};

cpp_num
cpp_interpret_integer (type)
     unsigned int type;
{
  cpp_num result;

  result.low = 0;
  result.high = 0;
  result.unsignedp = type & 4096;  <----!!
  result.overflow = 0;

  return result;
}

int main ()
{
  cpp_num n = cpp_interpret_integer (4369);
  if (!n.unsignedp) abort ();
  return 0;
}

which dutifully aborts.

<scratches head, examines assembler>.  This is actually a bug
in our bool typedef I think (which would explain a lot of the
random errors, and why recompiling with later compilers, which
contain a correct _Bool, fixes them).

See the marked line above?  This is correct code with C99's
_Bool semantics (which I believe GCC's "bool" semantics intend
to match).  However, if the bootstrap compiler doesn't
support _Bool, we use "char" instead.  By modular arithmetic,
assigning 4096 assigns 0, rather than one as intended.

Joseph - what to do about this?  I don't think adding "!= 0"
is a good fix - the typedef to char is fundamentally broken.
I don't see how a typedef to anything can really work in these
cases.

Neil.



More information about the Gcc-bugs mailing list