]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/19916 (Segmentation fault in __static_initialization_and_destruction_0)
authorMark Mitchell <mark@codesourcery.com>
Wed, 2 Mar 2005 20:57:53 +0000 (20:57 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Wed, 2 Mar 2005 20:57:53 +0000 (20:57 +0000)
PR c++/19916
* varasm.c (initializer_constant_valid_p): Allow conversions
between OFFSET_TYPEs.  Tidy.

PR c++/19916
* g++.dg/init/ptrmem2.C: New test.

From-SVN: r95809

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/varasm.c

index 9aa82e790d692324be1b809410afd2d9aab4b8ad..15dc08ecf1216814a323249c40aaf14141a3d3c4 100644 (file)
@@ -1,3 +1,9 @@
+2005-03-02  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/19916
+       * varasm.c (initializer_constant_valid_p): Allow conversions
+       between OFFSET_TYPEs.  Tidy.
+
 2005-02-28  John David Anglin  <dave.anglin#nrc-cnrc.gc.ca>
 
        PR target/19819
index dca1f18ba35017608ff256acd31795c7b01e9751..8b6ee0dca2e9817ba90ebefdef5a42f5e37c2a1e 100644 (file)
@@ -1,3 +1,8 @@
+2005-03-02  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/19916
+       * g++.dg/init/ptrmem2.C: New test.
+
 2005-03-02  Alexandre Oliva  <aoliva@redhat.com>
 
        * g++.dg/overload/using2.C: New.
index 19afc3db832dd5f6b3164feee4f09a23e8b92825..33307e529a6bc8d7ba9f160f8474a9b493ff043a 100644 (file)
@@ -3556,63 +3556,61 @@ initializer_constant_valid_p (tree value, tree endtype)
 
     case CONVERT_EXPR:
     case NOP_EXPR:
-      /* Allow conversions between pointer types.  */
-      if (POINTER_TYPE_P (TREE_TYPE (value))
-         && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0))))
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
-      /* Allow conversions between real types.  */
-      if (FLOAT_TYPE_P (TREE_TYPE (value))
-         && FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0))))
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
-      /* Allow length-preserving conversions between integer types.  */
-      if (INTEGRAL_TYPE_P (TREE_TYPE (value))
-         && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0)))
-         && (TYPE_PRECISION (TREE_TYPE (value))
-             == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
-      /* Allow conversions between other integer types only if
-        explicit value.  */
-      if (INTEGRAL_TYPE_P (TREE_TYPE (value))
-         && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0))))
-       {
-         tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                                    endtype);
-         if (inner == null_pointer_node)
-           return null_pointer_node;
-         break;
-       }
+      {
+       tree src;
+       tree src_type;
+       tree dest_type;
+
+       src = TREE_OPERAND (value, 0);
+       src_type = TREE_TYPE (src);
+       dest_type = TREE_TYPE (value);
+
+       /* Allow conversions between pointer types, floating-point
+          types, and offset types.  */
+       if ((POINTER_TYPE_P (dest_type) && POINTER_TYPE_P (src_type))
+           || (FLOAT_TYPE_P (dest_type) && FLOAT_TYPE_P (src_type))
+           || (TREE_CODE (dest_type) == OFFSET_TYPE
+               && TREE_CODE (src_type) == OFFSET_TYPE))
+         return initializer_constant_valid_p (src, endtype);
+
+       /* Allow length-preserving conversions between integer types.  */
+       if (INTEGRAL_TYPE_P (dest_type) && INTEGRAL_TYPE_P (src_type)
+           && (TYPE_PRECISION (dest_type) == TYPE_PRECISION (src_type)))
+         return initializer_constant_valid_p (src, endtype);
+
+       /* Allow conversions between other integer types only if
+          explicit value.  */
+       if (INTEGRAL_TYPE_P (dest_type) && INTEGRAL_TYPE_P (src_type))
+         {
+           tree inner = initializer_constant_valid_p (src, endtype);
+           if (inner == null_pointer_node)
+             return null_pointer_node;
+           break;
+         }
 
-      /* Allow (int) &foo provided int is as wide as a pointer.  */
-      if (INTEGRAL_TYPE_P (TREE_TYPE (value))
-         && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0)))
-         && (TYPE_PRECISION (TREE_TYPE (value))
-             >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                            endtype);
-
-      /* Likewise conversions from int to pointers, but also allow
-        conversions from 0.  */
-      if ((POINTER_TYPE_P (TREE_TYPE (value))
-          || TREE_CODE (TREE_TYPE (value)) == OFFSET_TYPE)
-         && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0))))
-       {
-         if (integer_zerop (TREE_OPERAND (value, 0)))
-           return null_pointer_node;
-         else if (TYPE_PRECISION (TREE_TYPE (value))
-                  <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))
-           return initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                                endtype);
-       }
+       /* Allow (int) &foo provided int is as wide as a pointer.  */
+       if (INTEGRAL_TYPE_P (dest_type) && POINTER_TYPE_P (src_type)
+           && (TYPE_PRECISION (dest_type) >= TYPE_PRECISION (src_type)))
+         return initializer_constant_valid_p (src, endtype);
 
-      /* Allow conversions to struct or union types if the value
-        inside is okay.  */
-      if (TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE
-         || TREE_CODE (TREE_TYPE (value)) == UNION_TYPE)
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                            endtype);
+       /* Likewise conversions from int to pointers, but also allow
+          conversions from 0.  */
+       if ((POINTER_TYPE_P (dest_type)
+            || TREE_CODE (dest_type) == OFFSET_TYPE)
+           && INTEGRAL_TYPE_P (src_type))
+         {
+           if (integer_zerop (src))
+             return null_pointer_node;
+           else if (TYPE_PRECISION (dest_type) <= TYPE_PRECISION (src_type))
+             return initializer_constant_valid_p (src, endtype);
+         }
+
+       /* Allow conversions to struct or union types if the value
+          inside is okay.  */
+       if (TREE_CODE (dest_type) == RECORD_TYPE
+           || TREE_CODE (dest_type) == UNION_TYPE)
+         return initializer_constant_valid_p (src, endtype);
+      }
       break;
 
     case PLUS_EXPR: