varasm.c (initializer_constant_valid_p): Forbid view-conversions from aggregate to...
authorEric Botcazou <ebotcazou@adacore.com>
Wed, 17 Sep 2008 21:48:08 +0000 (21:48 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Wed, 17 Sep 2008 21:48:08 +0000 (21:48 +0000)
* varasm.c (initializer_constant_valid_p): Forbid view-conversions
from aggregate to non-aggregate type if the bit pattern is not fully
preserved afterwards.

From-SVN: r140432

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/specs/static_initializer3.ads [new file with mode: 0644]
gcc/varasm.c

index fc5263e..48b5f0e 100644 (file)
@@ -1,3 +1,9 @@
+2008-09-17  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * varasm.c (initializer_constant_valid_p): Forbid view-conversions
+       from aggregate to non-aggregate type if the bit pattern is not fully
+       preserved afterwards.
+
 2008-09-17  Richard Guenther  <rguenther@suse.de>
 
        * tree-cfg.c (verify_types_in_gimple_assign): Rename to ...
index 9933c79..ed9d1e3 100644 (file)
@@ -1,3 +1,7 @@
+2008-09-17  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/specs/static_initializer3.ads: New test.
+
 2008-09-17  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/37552
diff --git a/gcc/testsuite/gnat.dg/specs/static_initializer3.ads b/gcc/testsuite/gnat.dg/specs/static_initializer3.ads
new file mode 100644 (file)
index 0000000..42994f2
--- /dev/null
@@ -0,0 +1,27 @@
+with Unchecked_Conversion;
+
+package Static_Initializer3 is
+
+  type Byte is range 0 .. 16#FF#;
+  for Byte'Size use 8;
+
+  type Word is range 0 .. 16#FFFF# ;
+  for Word'Size use 16;
+
+  type R is record
+    b1 : Boolean;
+    b2 : Boolean;
+  end record;
+  for R use record
+    b1 at 0 range 0..3;
+    b2 at 0 range 4..7;
+  end record;
+  for R'Size use 8;
+
+  function Conv is new Unchecked_Conversion (R, Byte);
+
+  C1 : constant Byte := Conv ((true, false));
+
+  C2 : constant Word := Word(C1);
+
+end Static_Initializer3;
index 5728d19..e74adae 100644 (file)
@@ -4205,19 +4205,36 @@ initializer_constant_valid_p (tree value, tree endtype)
        return op0;
       }
 
-    case VIEW_CONVERT_EXPR:
     case NON_LVALUE_EXPR:
       return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
 
-    CASE_CONVERT:
+    case VIEW_CONVERT_EXPR:
       {
-       tree src;
-       tree src_type;
-       tree dest_type;
+       tree src = TREE_OPERAND (value, 0);
+       tree src_type = TREE_TYPE (src);
+       tree dest_type = TREE_TYPE (value);
+
+       /* Allow view-conversions from aggregate to non-aggregate type only
+          if the bit pattern is fully preserved afterwards; otherwise, the
+          RTL expander won't be able to apply a subsequent transformation
+          to the underlying constructor.  */
+       if (AGGREGATE_TYPE_P (src_type) && !AGGREGATE_TYPE_P (dest_type))
+         {
+           if (TYPE_MODE (endtype) == TYPE_MODE (dest_type))
+             return initializer_constant_valid_p (src, endtype);
+           else
+             return NULL_TREE;
+         }
+
+       /* Allow all other kinds of view-conversion.  */
+       return initializer_constant_valid_p (src, endtype);
+      }
 
-       src = TREE_OPERAND (value, 0);
-       src_type = TREE_TYPE (src);
-       dest_type = TREE_TYPE (value);
+    CASE_CONVERT:
+      {
+       tree src = TREE_OPERAND (value, 0);
+       tree src_type = TREE_TYPE (src);
+       tree dest_type = TREE_TYPE (value);
 
        /* Allow conversions between pointer types, floating-point
           types, and offset types.  */