aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Christopher <echristo@redhat.com>2004-06-02 19:46:13 +0000
committerEric Christopher <echristo@gcc.gnu.org>2004-06-02 19:46:13 +0000
commit3aeb3655cf89356c86726d49316dcb957859971f (patch)
treed36ee4bf09e2586b23075250a34462a295e2664c /gcc
parent03a4c969079e508d695f0b8b82bd573b54e01a3c (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/c-typeck.c86
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20040602-1.c5
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;