This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] fix wrong gimple code with ptr to forward vla


Hello,

The attached patch fixes a problem whereby wrong gimple code is
emitted for a construct involving a pointer to a forward type which
later completion involves a variable length array. 

We first saw it on a Ada testcase then found a C counterpart
exhibiting the same behavior. Compiling the code below ...

   void foo ()
   {
     struct sequence;
     struct sequence * ptr;

     int size = 2;
     struct sequence { int values [size]; };

     struct sequence seq;

     seq.values [0] = 1;
   }

with -O2 -Wuninitialized on at least x86-linux yields

   t.c: In function 'foo':
   t.c:4: warning: 'size' is used uninitialized in this function

This is a regression compared to GCC 3.4.


The following gimple dump excerpt shows where this is coming from:

      ...
      size.0 = size;                     <== uninitialized use here
      D.1412 = size.0 - 1;               <== propagates all over ...
      D.1413 = (unsigned int) D.1412;
      size.1 = (unsigned int) size.0;
      D.1415 = (bit_size_type) size.1;
      D.1416 = D.1415 * 32;
      size.1 = (unsigned int) size.0;
      D.1417 = size.1 * 4;
      size.1 = (unsigned int) size.0;
      D.1415 = (bit_size_type) size.1;
      D.1416 = D.1415 * 32;
      size.1 = (unsigned int) size.0;
      D.1417 = size.1 * 4;

      size = 2;                         <== late initialization there
      size.1 = (unsigned int) size.0;
      D.1415 = (bit_size_type) size.1;
      D.1416 = D.1415 * 32;
      size.1 = (unsigned int) size.0;
      D.1417 = size.1 * 4;
      D.1419 = __builtin_alloca (D.1417);
      seq.2 = (struct sequence *) D.1419;
      seq.2->values[0] = 1;

Very wrong code indeed.

The uninitialized use is emitted by gimplify_type_sizes, from this
part of its processing:

  switch (TREE_CODE (type))
    {
    ...
    case POINTER_TYPE:
    case REFERENCE_TYPE:
      gimplify_type_sizes (TREE_TYPE (type), list_p);
      break;

This specific handling for pointer types was added for PR c/21536, and
it doesn't look quite right in light of the testcase above.

The attached patch fixes this by only gimplifying the designated type
sizes for anonymous types, in accordance with the rationale in the
comments:

      /* We must ensure that the designated type bounds/sizes are gimplified
	 before any possible use, and that the corresponding evaluation code
	 dominates all the uses.  This is expected to happen by construction
	 when the designated type is named, but is not guaranteed otherwise so
	 we force the evaluation here.

	 Note that forcing gimplification of bounds/sizes for a named type
	 here would not only be pointless.  It would actually be incorrect
	 because they might depend on variables only initialized after this
	 point when a forward declaration is involved.  */

It has been successfully bootstrapped and regression tested on
i686-pc-linux-gnu with languages=all,ada.

Thanks in advance,

Olivier

2006-09-01  Olivier Hainque  <hainque@adacore.com>

	* gimplify.c (gimplify_type_sizes): Only gimplify the sizes of
	of pointer designated type if it is anonymous.

	testsuite/
	* gnat.dg/forward_vla.adb: New case.
	* gcc.dg/forward-vla-1.c: New case.









Attachment: gimple-sizes.dif
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]