c-typeck.c (common_type): Don't lose type qualifiers when creating new variants.
authorEric Christopher <echristo@redhat.com>
Wed, 2 Jun 2004 19:46:13 +0000 (19:46 +0000)
committerEric Christopher <echristo@gcc.gnu.org>
Wed, 2 Jun 2004 19:46:13 +0000 (19:46 +0000)
2004-06-02  Eric Christopher  <echristo@redhat.com>

        * c-typeck.c (common_type): Don't lose type qualifiers
        when creating new variants.

2004-06-02  Eric Christopher  <echristo@redhat.com>

        * gcc.c-torture/compile/20040602-1.c: New.

From-SVN: r82577

gcc/ChangeLog
gcc/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/20040602-1.c [new file with mode: 0644]

index dd380f0b75ea63b6194140eb5b27b92cb4946476..b70ac67846fcb70b2564c2d0b97acc9bb31515a3 100644 (file)
@@ -1,3 +1,8 @@
+2004-06-02  Eric Christopher  <echristo@redhat.com>
+
+       * c-typeck.c (common_type): Don't lose type qualifiers
+       when creating new variants.
+
 2004-06-02  Andrew Pinski  <pinskia@physics.uc.edu>
 
        PR tree-optimization/14042
index bf480942b15f8831055c58d5cfa3d2ed733fc112..cf01aa5f60f2e307fcf72b10ae01db8c4a21555c 100644 (file)
@@ -279,45 +279,64 @@ common_type (tree t1, tree t2)
 
       /* Same precision.  Prefer long longs to longs to ints when the
         same precision, following the C99 rules on integer type rank
-        (which are equivalent to the C90 rules for C90 types).  */
+        (which are equivalent to the C90 rules for C90 types).
+        Make sure that we don't lose the type qualifications when
+        creating the new variant.  */
 
       if (TYPE_MAIN_VARIANT (t1) == long_long_unsigned_type_node
          || TYPE_MAIN_VARIANT (t2) == long_long_unsigned_type_node)
-       return build_type_attribute_variant (long_long_unsigned_type_node,
-                                            attributes);
+       {
+         t1 = build_qualified_type (long_long_unsigned_type_node,
+                                    TYPE_QUALS (t1));
+         return build_type_attribute_variant (t1, attributes);
+       }
 
       if (TYPE_MAIN_VARIANT (t1) == long_long_integer_type_node
          || TYPE_MAIN_VARIANT (t2) == long_long_integer_type_node)
        {
+         tree ntype;
+
          if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
-            t1 = long_long_unsigned_type_node;
+            ntype = long_long_unsigned_type_node;
          else
-            t1 = long_long_integer_type_node;
-         return build_type_attribute_variant (t1, attributes);
+            ntype = long_long_integer_type_node;
+
+         ntype = build_qualified_type (ntype, TYPE_QUALS (t1));
+         return build_type_attribute_variant (ntype, attributes);
        }
 
       if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node
          || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node)
-       return build_type_attribute_variant (long_unsigned_type_node,
-                                            attributes);
+       {
+         t1 = build_qualified_type (long_unsigned_type_node,
+                                    TYPE_QUALS (t1));
+         return build_type_attribute_variant (t1, attributes);
+       }
 
       if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node
          || TYPE_MAIN_VARIANT (t2) == long_integer_type_node)
        {
+         tree ntype;
+
          /* But preserve unsignedness from the other type,
             since long cannot hold all the values of an unsigned int.  */
          if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
-            t1 = long_unsigned_type_node;
+            ntype = long_unsigned_type_node;
          else
-            t1 = long_integer_type_node;
-         return build_type_attribute_variant (t1, attributes);
+            ntype = long_integer_type_node;
+
+         ntype = build_qualified_type (ntype, TYPE_QUALS (t1));
+         return build_type_attribute_variant (ntype, attributes);
        }
 
       /* Likewise, prefer long double to double even if same size.  */
       if (TYPE_MAIN_VARIANT (t1) == long_double_type_node
          || TYPE_MAIN_VARIANT (t2) == long_double_type_node)
-       return build_type_attribute_variant (long_double_type_node,
-                                            attributes);
+       {
+         t1 = build_qualified_type (long_double_type_node,
+                                    TYPE_QUALS (t1));
+         return build_type_attribute_variant (t1, attributes);
+       }
 
       /* Otherwise prefer the unsigned one.  */
 
@@ -425,7 +444,7 @@ common_type (tree t1, tree t2)
                tree memb;
                for (memb = TYPE_FIELDS (TREE_VALUE (p1));
                     memb; memb = TREE_CHAIN (memb))
-                 if (comptypes (TREE_TYPE (memb), TREE_VALUE (p2), 
+                 if (comptypes (TREE_TYPE (memb), TREE_VALUE (p2),
                                 COMPARE_STRICT))
                    {
                      TREE_VALUE (n) = TREE_VALUE (p2);
@@ -440,7 +459,7 @@ common_type (tree t1, tree t2)
                tree memb;
                for (memb = TYPE_FIELDS (TREE_VALUE (p2));
                     memb; memb = TREE_CHAIN (memb))
-                 if (comptypes (TREE_TYPE (memb), TREE_VALUE (p1), 
+                 if (comptypes (TREE_TYPE (memb), TREE_VALUE (p1),
                                 COMPARE_STRICT))
                    {
                      TREE_VALUE (n) = TREE_VALUE (p1);
@@ -506,7 +525,8 @@ comptypes (tree type1, tree type2, int flags)
 
   /* Different classes of types can't be compatible.  */
 
-  if (TREE_CODE (t1) != TREE_CODE (t2)) return 0;
+  if (TREE_CODE (t1) != TREE_CODE (t2))
+    return 0;
 
   /* Qualifiers must match.  */
 
@@ -686,7 +706,7 @@ tagged_types_tu_compatible_p (tree t1, tree t2, int flags)
 {
   tree s1, s2;
   bool needs_warning = false;
-  
+
   /* We have to verify that the tags of the types are the same.  This
      is harder than it looks because this may be a typedef, so we have
      to go look at the original type.  It may even be a typedef of a
@@ -706,33 +726,33 @@ tagged_types_tu_compatible_p (tree t1, tree t2, int flags)
   /* C90 didn't have the requirement that the two tags be the same.  */
   if (flag_isoc99 && TYPE_NAME (t1) != TYPE_NAME (t2))
     return 0;
-  
+
   /* C90 didn't say what happened if one or both of the types were
      incomplete; we choose to follow C99 rules here, which is that they
      are compatible.  */
   if (TYPE_SIZE (t1) == NULL
       || TYPE_SIZE (t2) == NULL)
     return 1;
-  
+
   {
     const struct tagged_tu_seen * tts_i;
     for (tts_i = tagged_tu_seen_base; tts_i != NULL; tts_i = tts_i->next)
       if (tts_i->t1 == t1 && tts_i->t2 == t2)
        return 1;
   }
-  
+
   switch (TREE_CODE (t1))
     {
     case ENUMERAL_TYPE:
       {
-      
+
         /* Speed up the case where the type values are in the same order.  */
         tree tv1 = TYPE_VALUES (t1);
         tree tv2 = TYPE_VALUES (t2);
-        
+
         if (tv1 == tv2)
           return 1;
-        
+
         for (;tv1 && tv2; tv1 = TREE_CHAIN (tv1), tv2 = TREE_CHAIN (tv2))
           {
             if (TREE_PURPOSE (tv1) != TREE_PURPOSE (tv2))
@@ -740,15 +760,15 @@ tagged_types_tu_compatible_p (tree t1, tree t2, int flags)
             if (simple_cst_equal (TREE_VALUE (tv1), TREE_VALUE (tv2)) != 1)
               return 0;
           }
-        
+
         if (tv1 == NULL_TREE && tv2 == NULL_TREE)
           return 1;
         if (tv1 == NULL_TREE || tv2 == NULL_TREE)
           return 0;
-        
+
        if (list_length (TYPE_VALUES (t1)) != list_length (TYPE_VALUES (t2)))
          return 0;
-       
+
        for (s1 = TYPE_VALUES (t1); s1; s1 = TREE_CHAIN (s1))
          {
            s2 = purpose_member (TREE_PURPOSE (s1), TYPE_VALUES (t2));
@@ -773,7 +793,7 @@ tagged_types_tu_compatible_p (tree t1, tree t2, int flags)
            tts.t1 = t1;
            tts.t2 = t2;
            tagged_tu_seen_base = &tts;
-       
+
            if (DECL_NAME (s1) != NULL)
              for (s2 = TYPE_VALUES (t2); s2; s2 = TREE_CHAIN (s2))
                if (DECL_NAME (s1) == DECL_NAME (s2))
@@ -784,7 +804,7 @@ tagged_types_tu_compatible_p (tree t1, tree t2, int flags)
                      break;
                    if (result == 2)
                      needs_warning = true;
-                   
+
                    if (TREE_CODE (s1) == FIELD_DECL
                        && simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1),
                                             DECL_FIELD_BIT_OFFSET (s2)) != 1)
@@ -803,13 +823,13 @@ tagged_types_tu_compatible_p (tree t1, tree t2, int flags)
     case RECORD_TYPE:
       {
        struct tagged_tu_seen tts;
-       
+
        tts.next = tagged_tu_seen_base;
        tts.t1 = t1;
        tts.t2 = t2;
        tagged_tu_seen_base = &tts;
-         
-       for (s1 = TYPE_FIELDS (t1), s2 = TYPE_FIELDS (t2); 
+
+       for (s1 = TYPE_FIELDS (t1), s2 = TYPE_FIELDS (t2);
             s1 && s2;
             s1 = TREE_CHAIN (s1), s2 = TREE_CHAIN (s2))
          {
@@ -822,7 +842,7 @@ tagged_types_tu_compatible_p (tree t1, tree t2, int flags)
              break;
            if (result == 2)
              needs_warning = true;
-           
+
            if (TREE_CODE (s1) == FIELD_DECL
                && simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1),
                                     DECL_FIELD_BIT_OFFSET (s2)) != 1)
@@ -4319,7 +4339,7 @@ finish_init (void)
 
   /* Pop back to the data of the outer initializer (if any).  */
   free (spelling_base);
-  
+
   constructor_decl = p->decl;
   constructor_asmspec = p->asmspec;
   require_constant_value = p->require_constant_value;
index ef9c9ad2ba0b883d04eb18c819deba27aebf2a67..da095bfcb52266229c1aa92fed2915eb2f502780 100644 (file)
@@ -1,3 +1,7 @@
+2004-06-02  Eric Christopher  <echristo@redhat.com>
+
+       * gcc.c-torture/compile/20040602-1.c: New.
+
 2004-06-02  Andrew Pinski  <pinskia@physics.uc.edu>
 
        * g++.dg/tree-ssa/ssa-sra-1.C: Fix comment.
@@ -5,7 +9,7 @@
 
        PR tree-optimization/14736
        * g++.dg/tree-ssa/ssa-cast-1.C: New Test.
-       
+
        PR tree-optimization/14042
        * g++.dg/tree-ssa/ssa-sra-1.C: New Test.
 
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040602-1.c b/gcc/testsuite/gcc.c-torture/compile/20040602-1.c
new file mode 100644 (file)
index 0000000..8f751e3
--- /dev/null
@@ -0,0 +1,5 @@
+/* Test type qualifiers.  These should as equal types.  */
+extern volatile unsigned long foo;
+typedef unsigned long ulong;
+extern volatile ulong foo;
+volatile ulong foo;