Results of a test mass rebuild of rawhide/x86_64 with gcc-4.8.0-0.1.fc19

Jakub Jelinek jakub at redhat.com
Mon Jan 7 16:11:54 UTC 2013


On Mon, Jan 07, 2013 at 03:50:01PM +0000, Petr Pisar wrote:
> > yap-6.2.2-4.fc18.src.rpm
> > 	similar to getdata bug:
> > 	LAST_FLAG = 23
> > 	...
> > 	#define NUMBER_OF_YAP_FLAGS  LAST_FLAG
> > 	...
> > 	#define yap_flags Yap_heap_regs->yap_flags_field
> > 	...
> > 	Int  yap_flags_field[NUMBER_OF_YAP_FLAGS];
> > 	...
> > 	/* This must be done before initialising predicates */
> > 	for (i = 0; i <= LAST_FLAG; i++) {
> > 	  yap_flags[i] = 0;
> > 	}
> >
> What's wrong with assigning 0 that fits into any intenger? C99 says:
> 
>   6.3.1.3 Signed and unsigned integers
>   1 When a value with integer type is converted to another integer type
>     other than _Bool, if the value can be represented by the new type,
>     it is unchanged.
> 
> The pre-precessed code is:
> 
>   for (i = 0; i <= LAST_FLAG; i++) {
>     ((all_heap_codes *)(0x10000000))->yap_flags_field[i] = 0;
>   }
> 
> Type of yap_flags_field is int[].

That's not correct, type of yap_flags_field is int[NUMBER_OF_YAP_FLAGS]
aka int[LAST_FLAG].  The undefined behavior happens in the last iteration,
where you do
  ((all_heap_codes *)(0x10000000))->yap_flags_field[LAST_FLAG] = 0;
ISO C99 6.5.2.1 says that this is equivalent to:
  (*((((all_heap_codes *)(0x10000000))->yap_flags_field)+(LAST_FLAG))) = 0;
and then 6.5.6/8 (last sentence) applies:
"If the result points one past the last element of the array object, it
shall not be used as the operand of a unary * operator that is evaluated."

Note the array is in a middle of a structure, not at the end, where is the
only place where flexible array members could be present and as an extension
GCC allows even non-flexible arrays to be treated similarly to flexible
arrays (case where people use say struct S { ...; int a[1]; }; as some kind
of pre-C99 flexible array members).

	Jakub


More information about the devel mailing list