diff options
author | Eric Christopher <echristo@redhat.com> | 2004-06-02 19:46:13 +0000 |
---|---|---|
committer | Eric Christopher <echristo@gcc.gnu.org> | 2004-06-02 19:46:13 +0000 |
commit | 3aeb3655cf89356c86726d49316dcb957859971f (patch) | |
tree | d36ee4bf09e2586b23075250a34462a295e2664c /gcc | |
parent | 03a4c969079e508d695f0b8b82bd573b54e01a3c (diff) | |
download | gcc-3aeb3655cf89356c86726d49316dcb957859971f.zip gcc-3aeb3655cf89356c86726d49316dcb957859971f.tar.gz gcc-3aeb3655cf89356c86726d49316dcb957859971f.tar.bz2 |
c-typeck.c (common_type): Don't lose type qualifiers when creating new variants.
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/c-typeck.c | 86 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/20040602-1.c | 5 |
4 files changed, 68 insertions, 34 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dd380f0..b70ac67 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index bf48094..cf01aa5 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ef9c9ad..da095bf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..8f751e3 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20040602-1.c @@ -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; |