This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
prevent creation of improper static vars in gimplify_init_constructor
- From: Olivier Hainque <hainque at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: hainque at adacore dot com
- Date: Thu, 11 May 2006 11:41:51 +0200
- Subject: prevent creation of improper static vars in gimplify_init_constructor
Hello,
The patch below is a suggestion to fix an issue with
gimplify_init_constructor, which currently might create static
versions of the constructor that varasm:output_constructor doesn't
handle.
The problem is visible out of the Ada testcase below, featuring
the initialization with a constructor of a bitfield aggregate:
procedure P is
type Mod_64 is mod 2 ** 64;
for Mod_64'Size use 64;
type Uint_16 is range 0 .. 2 ** 16 - 1;
for Uint_16'Size use 16;
type Values_Type is record
M64 : Mod_64;
U16 : Uint_16;
end record;
for Values_Type use record
M64 at 0 range 0 .. 63;
U16 at 8 range 0 .. 15;
end record;
type Wrapper_Type is record
Values : Values_Type;
end record;
for Wrapper_Type use record
Values at 0 range 0 .. 79; -- bitfield aggregate
end record;
W : Wrapper_Type := (Values => (2, 4));
begin
null;
end;
This code is expected to compile silently, while on e.g. x86-linux we
get an spurious "invalid initial value for member 'values'" error from
output_constructor (a regression from GCC 3.4, btw)
gimplify_init_constructor currently guards the creation of static
versions with "num_nonconstant_elements == 0", num_nonconstant_elements
being set as
* how many scalar fields are set to non-constant values,
from categorize_ctor_elements. This is not restrictive enough to
prevent the error above because this looks through intermediate
aggregates among which there might be bitfields.
The suggested fix consists in replacing the "num_nonconstant_elements"
based guards by the outcome of "initializer_constant_valid_p" for the
constructor at hand.
Bootstrapped and regression tested on i686-pc-linux-gnu with
enable-languages=all,ada.
Olivier
2006-05-11 Olivier Hainque <hainque@adacore.com>
* gimplify.c (gimplify_init_constructor): Prevent the creation of
static versions of the constructor if it is not a valid constant
initializer.
*** gcc/gimplify.c.orig 2006-05-03 14:20:25.000000000 +0200
--- gcc/gimplify.c 2006-05-10 09:40:54.000000000 +0200
*************** gimplify_init_constructor (tree *expr_p,
*** 2885,2891 ****
struct gimplify_init_ctor_preeval_data preeval_data;
HOST_WIDE_INT num_type_elements, num_ctor_elements;
HOST_WIDE_INT num_nonzero_elements, num_nonconstant_elements;
! bool cleared;
/* Aggregate types must lower constructors to initialization of
individual elements. The exception is that a CONSTRUCTOR node
--- 2885,2891 ----
struct gimplify_init_ctor_preeval_data preeval_data;
HOST_WIDE_INT num_type_elements, num_ctor_elements;
HOST_WIDE_INT num_nonzero_elements, num_nonconstant_elements;
! bool cleared, ctor_is_valid_const_initializer;
/* Aggregate types must lower constructors to initialization of
individual elements. The exception is that a CONSTRUCTOR node
*************** gimplify_init_constructor (tree *expr_p,
*** 2897,2905 ****
&num_nonconstant_elements,
&num_ctor_elements, &cleared);
/* If a const aggregate variable is being initialized, then it
! should never be a lose to promote the variable to be static. */
! if (num_nonconstant_elements == 0
&& num_nonzero_elements > 1
&& TREE_READONLY (object)
&& TREE_CODE (object) == VAR_DECL)
--- 2897,2916 ----
&num_nonconstant_elements,
&num_ctor_elements, &cleared);
+ /* In some cases, making a static version of the constructor at hand
+ would be a win, and we must ensure that varasm will be able to
+ output it before doing so. num_nonconstant_elements == 0 is not
+ exactly what we need here, as it conveys information about embedded
+ scalar components, looking through intermediate constructors among
+ which there might be bitfield aggregates which output_constructor
+ doesn't handle. */
+ ctor_is_valid_const_initializer =
+ initializer_constant_valid_p (ctor, TREE_TYPE (ctor)) != NULL_TREE;
+
/* If a const aggregate variable is being initialized, then it
! should never be a lose to promote the variable to be static,
! as soon as we're able to output the associated value. */
! if (ctor_is_valid_const_initializer
&& num_nonzero_elements > 1
&& TREE_READONLY (object)
&& TREE_CODE (object) == VAR_DECL)
*************** gimplify_init_constructor (tree *expr_p,
*** 2956,2962 ****
for sparse arrays, though, as it's more efficient to follow
the standard CONSTRUCTOR behavior of memset followed by
individual element initialization. */
! if (num_nonconstant_elements == 0 && !cleared)
{
HOST_WIDE_INT size = int_size_in_bytes (type);
unsigned int align;
--- 2967,2973 ----
for sparse arrays, though, as it's more efficient to follow
the standard CONSTRUCTOR behavior of memset followed by
individual element initialization. */
! if (ctor_is_valid_const_initializer && !cleared)
{
HOST_WIDE_INT size = int_size_in_bytes (type);
unsigned int align;