aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2002-03-15 13:31:55 -0500
committerJason Merrill <jason@gcc.gnu.org>2002-03-15 13:31:55 -0500
commit6da794e83532c526345040d6251acf12147d4231 (patch)
tree5bf7381d37be615ff3e1be31fe56f3a90cad3f02 /gcc
parentb3b77addd069e3f4010f482942af55b2a8c0e9c5 (diff)
downloadgcc-6da794e83532c526345040d6251acf12147d4231.zip
gcc-6da794e83532c526345040d6251acf12147d4231.tar.gz
gcc-6da794e83532c526345040d6251acf12147d4231.tar.bz2
re PR c++/5857 (C++ duplicate_decls shouldn't use common_type)
PR c++/5857 * decl.c (duplicate_decls): Use merge_types instead of common_type. * typeck.c (common_type): Just hand off to type_after_usual_arithmetic_conversions and composite_pointer_type. (merge_types): New fn. (commonparms): Use it instead of common_type. (type_after_usual_arithmetic_conversions): Also handle COMPLEX_TYPE. (composite_pointer_type): Also handle attributes. * cp-tree.h: Declare merge_types. From-SVN: r50820
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl.c6
-rw-r--r--gcc/cp/typeck.c258
-rw-r--r--gcc/testsuite/g++.dg/other/redecl1.C10
5 files changed, 129 insertions, 157 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4608f11..111edcc 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,16 @@
2002-03-15 Jason Merrill <jason@redhat.com>
+ PR c++/5857
+ * decl.c (duplicate_decls): Use merge_types instead of common_type.
+ * typeck.c (common_type): Just hand off to
+ type_after_usual_arithmetic_conversions and
+ composite_pointer_type.
+ (merge_types): New fn.
+ (commonparms): Use it instead of common_type.
+ (type_after_usual_arithmetic_conversions): Also handle COMPLEX_TYPE.
+ (composite_pointer_type): Also handle attributes.
+ * cp-tree.h: Declare merge_types.
+
* decl.c (make_rtl_for_nonlocal_decl): Also defer COMDAT
variables.
* decl2.c (maybe_make_one_only): Also mark the decl as needed.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 33e09e3..5f58ef6 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4355,6 +4355,7 @@ extern tree pfn_from_ptrmemfunc PARAMS ((tree));
extern tree type_after_usual_arithmetic_conversions PARAMS ((tree, tree));
extern tree composite_pointer_type PARAMS ((tree, tree, tree, tree,
const char*));
+extern tree merge_types PARAMS ((tree, tree));
extern tree check_return_expr PARAMS ((tree));
#define cp_build_binary_op(code, arg1, arg2) \
build_binary_op(code, arg1, arg2, 1)
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 758524b..d76c6a5 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -3515,16 +3515,16 @@ duplicate_decls (newdecl, olddecl)
tree newtype;
/* Merge the data types specified in the two decls. */
- newtype = common_type (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
+ newtype = merge_types (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
- /* If common_type produces a non-typedef type, just use the old type. */
+ /* If merge_types produces a non-typedef type, just use the old type. */
if (TREE_CODE (newdecl) == TYPE_DECL
&& newtype == DECL_ORIGINAL_TYPE (newdecl))
newtype = oldtype;
if (TREE_CODE (newdecl) == VAR_DECL)
DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl);
- /* Do this after calling `common_type' so that default
+ /* Do this after calling `merge_types' so that default
parameters don't confuse us. */
else if (TREE_CODE (newdecl) == FUNCTION_DECL
&& (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (newdecl))
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index b14687b..a8a424a 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -285,7 +285,7 @@ commonparms (p1, p2)
if (TREE_VALUE (p1) != TREE_VALUE (p2))
{
any_change = 1;
- TREE_VALUE (n) = common_type (TREE_VALUE (p1), TREE_VALUE (p2));
+ TREE_VALUE (n) = merge_types (TREE_VALUE (p1), TREE_VALUE (p2));
}
else
TREE_VALUE (n) = TREE_VALUE (p1);
@@ -330,16 +330,38 @@ type_after_usual_arithmetic_conversions (t1, t2)
/* FIXME: Attributes. */
my_friendly_assert (ARITHMETIC_TYPE_P (t1)
+ || TREE_CODE (t1) == COMPLEX_TYPE
|| TREE_CODE (t1) == ENUMERAL_TYPE,
19990725);
my_friendly_assert (ARITHMETIC_TYPE_P (t2)
+ || TREE_CODE (t2) == COMPLEX_TYPE
|| TREE_CODE (t2) == ENUMERAL_TYPE,
19990725);
- /* In what follows, we slightly generalize the rules given in [expr]
- so as to deal with `long long'. First, merge the attributes. */
+ /* In what follows, we slightly generalize the rules given in [expr] so
+ as to deal with `long long' and `complex'. First, merge the
+ attributes. */
attributes = (*targetm.merge_type_attributes) (t1, t2);
+ /* If one type is complex, form the common type of the non-complex
+ components, then make that complex. Use T1 or T2 if it is the
+ required type. */
+ if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
+ {
+ tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
+ tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
+ tree subtype
+ = type_after_usual_arithmetic_conversions (subtype1, subtype2);
+
+ if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
+ return build_type_attribute_variant (t1, attributes);
+ else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
+ return build_type_attribute_variant (t2, attributes);
+ else
+ return build_type_attribute_variant (build_complex_type (subtype),
+ attributes);
+ }
+
/* If only one is real, use it as the result. */
if (code1 == REAL_TYPE && code2 != REAL_TYPE)
return build_type_attribute_variant (t1, attributes);
@@ -439,6 +461,7 @@ composite_pointer_type (t1, t2, arg1, arg2, location)
const char* location;
{
tree result_type;
+ tree attributes;
/* [expr.rel]
@@ -456,6 +479,9 @@ composite_pointer_type (t1, t2, arg1, arg2, location)
if (TYPE_PTRMEMFUNC_P (t2))
t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
+ /* Merge the attributes. */
+ attributes = (*targetm.merge_type_attributes) (t1, t2);
+
/* We have:
[expr.rel]
@@ -504,21 +530,18 @@ composite_pointer_type (t1, t2, arg1, arg2, location)
}
}
- return result_type;
+ return build_type_attribute_variant (result_type, attributes);
}
-/* Return the common type of two types.
+/* Return the merged type of two types.
We assume that comptypes has already been done and returned 1;
if that isn't so, this may crash.
- This is the type for the result of most arithmetic operations
- if the operands have the given two types.
-
- We do not deal with enumeral types here because they have already been
- converted to integer types. */
+ This just combines attributes and default arguments; any other
+ differences would cause the two types to compare unalike. */
tree
-common_type (t1, t2)
+merge_types (t1, t2)
tree t1, t2;
{
register enum tree_code code1;
@@ -528,9 +551,7 @@ common_type (t1, t2)
/* Save time if the two types are the same. */
if (t1 == t2)
return t1;
- t1 = original_type (t1);
- t2 = original_type (t2);
- if (t1 == t2)
+ if (original_type (t1) == original_type (t2))
return t1;
/* If one type is nonsense, use the other. */
@@ -539,20 +560,11 @@ common_type (t1, t2)
if (t2 == error_mark_node)
return t1;
- if ((ARITHMETIC_TYPE_P (t1) || TREE_CODE (t1) == ENUMERAL_TYPE)
- && (ARITHMETIC_TYPE_P (t2) || TREE_CODE (t2) == ENUMERAL_TYPE))
- return type_after_usual_arithmetic_conversions (t1, t2);
-
/* Merge the attributes. */
attributes = (*targetm.merge_type_attributes) (t1, t2);
/* Treat an enum type as the unsigned integer type of the same width. */
- if (TREE_CODE (t1) == ENUMERAL_TYPE)
- t1 = type_for_size (TYPE_PRECISION (t1), 1);
- if (TREE_CODE (t2) == ENUMERAL_TYPE)
- t2 = type_for_size (TYPE_PRECISION (t2), 1);
-
if (TYPE_PTRMEMFUNC_P (t1))
t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
if (TYPE_PTRMEMFUNC_P (t2))
@@ -561,82 +573,13 @@ common_type (t1, t2)
code1 = TREE_CODE (t1);
code2 = TREE_CODE (t2);
- /* If one type is complex, form the common type of the non-complex
- components, then make that complex. Use T1 or T2 if it is the
- required type. */
- if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
- {
- tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
- tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
- tree subtype = common_type (subtype1, subtype2);
-
- if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
- return build_type_attribute_variant (t1, attributes);
- else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
- return build_type_attribute_variant (t2, attributes);
- else
- return build_type_attribute_variant (build_complex_type (subtype),
- attributes);
- }
-
switch (code1)
{
- case INTEGER_TYPE:
- case REAL_TYPE:
- /* We should have called type_after_usual_arithmetic_conversions
- above. */
- abort ();
- break;
-
case POINTER_TYPE:
case REFERENCE_TYPE:
- /* For two pointers, do this recursively on the target type,
- and combine the qualifiers of the two types' targets. */
- /* This code was turned off; I don't know why.
- But ISO C++ specifies doing this with the qualifiers.
- So I turned it on again. */
+ /* For two pointers, do this recursively on the target type. */
{
- tree tt1 = TREE_TYPE (t1);
- tree tt2 = TREE_TYPE (t2);
- tree b1, b2;
- int type_quals;
- tree target;
-
- if (TREE_CODE (tt1) == OFFSET_TYPE)
- {
- b1 = TYPE_OFFSET_BASETYPE (tt1);
- b2 = TYPE_OFFSET_BASETYPE (tt2);
- tt1 = TREE_TYPE (tt1);
- tt2 = TREE_TYPE (tt2);
- }
- else
- b1 = b2 = NULL_TREE;
-
- type_quals = (cp_type_quals (tt1) | cp_type_quals (tt2));
- tt1 = TYPE_MAIN_VARIANT (tt1);
- tt2 = TYPE_MAIN_VARIANT (tt2);
-
- if (tt1 == tt2)
- target = tt1;
- else if (VOID_TYPE_P (tt1) || VOID_TYPE_P (tt2))
- target = void_type_node;
- else if (tt1 == unknown_type_node)
- target = tt2;
- else if (tt2 == unknown_type_node)
- target = tt1;
- else
- target = common_type (tt1, tt2);
-
- target = cp_build_qualified_type (target, type_quals);
-
- if (b1)
- {
- if (same_type_p (b1, b2)
- || (DERIVED_FROM_P (b1, b2) && binfo_or_else (b1, b2)))
- target = build_offset_type (b2, target);
- else if (binfo_or_else (b2, b1))
- target = build_offset_type (b1, target);
- }
+ tree target = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
if (code1 == POINTER_TYPE)
t1 = build_pointer_type (target);
@@ -650,9 +593,17 @@ common_type (t1, t2)
return t1;
}
+ case OFFSET_TYPE:
+ {
+ tree base = TYPE_OFFSET_BASETYPE (t1);
+ tree target = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
+ t1 = build_offset_type (base, target);
+ break;
+ }
+
case ARRAY_TYPE:
{
- tree elt = common_type (TREE_TYPE (t1), TREE_TYPE (t2));
+ tree elt = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
/* Save space: see if the result is identical to one of the args. */
if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
return build_type_attribute_variant (t1, attributes);
@@ -661,14 +612,14 @@ common_type (t1, t2)
/* Merge the element types, and have a size if either arg has one. */
t1 = build_cplus_array_type
(elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
- return build_type_attribute_variant (t1, attributes);
+ break;
}
case FUNCTION_TYPE:
/* Function types: prefer the one that specified arg types.
If both do, merge the arg types. Also merge the return types. */
{
- tree valtype = common_type (TREE_TYPE (t1), TREE_TYPE (t2));
+ tree valtype = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
tree p1 = TYPE_ARG_TYPES (t1);
tree p2 = TYPE_ARG_TYPES (t2);
tree rval, raises;
@@ -697,73 +648,72 @@ common_type (t1, t2)
}
rval = build_function_type (valtype, commonparms (p1, p2));
- rval = build_exception_variant (rval, raises);
- return build_type_attribute_variant (rval, attributes);
+ t1 = build_exception_variant (rval, raises);
+ break;
}
- case RECORD_TYPE:
- case UNION_TYPE:
- t1 = TYPE_MAIN_VARIANT (t1);
- t2 = TYPE_MAIN_VARIANT (t2);
+ case METHOD_TYPE:
+ {
+ /* Get this value the long way, since TYPE_METHOD_BASETYPE
+ is just the main variant of this. */
+ tree basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t2)));
+ tree raises = TYPE_RAISES_EXCEPTIONS (t1);
+ tree t3;
+
+ /* If this was a member function type, get back to the
+ original type of type member function (i.e., without
+ the class instance variable up front. */
+ t1 = build_function_type (TREE_TYPE (t1),
+ TREE_CHAIN (TYPE_ARG_TYPES (t1)));
+ t2 = build_function_type (TREE_TYPE (t2),
+ TREE_CHAIN (TYPE_ARG_TYPES (t2)));
+ t3 = merge_types (t1, t2);
+ t3 = build_cplus_method_type (basetype, TREE_TYPE (t3),
+ TYPE_ARG_TYPES (t3));
+ t1 = build_exception_variant (t3, raises);
+ break;
+ }
- if (DERIVED_FROM_P (t1, t2) && binfo_or_else (t1, t2))
- return build_type_attribute_variant (t1, attributes);
- else if (binfo_or_else (t2, t1))
- return build_type_attribute_variant (t2, attributes);
- else
- {
- compiler_error ("common_type called with uncommon aggregate types");
- return error_mark_node;
- }
+ default:;
+ }
+ return build_type_attribute_variant (t1, attributes);
+}
- case METHOD_TYPE:
- if (TREE_CODE (TREE_TYPE (t1)) == TREE_CODE (TREE_TYPE (t2)))
- {
- /* Get this value the long way, since TYPE_METHOD_BASETYPE
- is just the main variant of this. */
- tree basetype;
- tree raises, t3;
+/* Return the common type of two types.
+ We assume that comptypes has already been done and returned 1;
+ if that isn't so, this may crash.
- tree b1 = TYPE_OFFSET_BASETYPE (t1);
- tree b2 = TYPE_OFFSET_BASETYPE (t2);
+ This is the type for the result of most arithmetic operations
+ if the operands have the given two types. */
- if (same_type_p (b1, b2)
- || (DERIVED_FROM_P (b1, b2) && binfo_or_else (b1, b2)))
- basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t2)));
- else
- {
- if (binfo_or_else (b2, b1) == NULL_TREE)
- compiler_error ("common_type called with uncommon method types");
- basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t1)));
- }
+tree
+common_type (t1, t2)
+ tree t1, t2;
+{
+ enum tree_code code1;
+ enum tree_code code2;
- raises = TYPE_RAISES_EXCEPTIONS (t1);
-
- /* If this was a member function type, get back to the
- original type of type member function (i.e., without
- the class instance variable up front. */
- t1 = build_function_type (TREE_TYPE (t1),
- TREE_CHAIN (TYPE_ARG_TYPES (t1)));
- t2 = build_function_type (TREE_TYPE (t2),
- TREE_CHAIN (TYPE_ARG_TYPES (t2)));
- t3 = common_type (t1, t2);
- t3 = build_cplus_method_type (basetype, TREE_TYPE (t3),
- TYPE_ARG_TYPES (t3));
- t1 = build_exception_variant (t3, raises);
- }
- else
- compiler_error ("common_type called with uncommon method types");
+ /* If one type is nonsense, bail. */
+ if (t1 == error_mark_node || t2 == error_mark_node)
+ return error_mark_node;
- return build_type_attribute_variant (t1, attributes);
+ code1 = TREE_CODE (t1);
+ code2 = TREE_CODE (t2);
- case OFFSET_TYPE:
- /* Pointers to members should now be handled by the POINTER_TYPE
- case above. */
- abort ();
+ if ((ARITHMETIC_TYPE_P (t1) || code1 == ENUMERAL_TYPE
+ || code1 == COMPLEX_TYPE)
+ && (ARITHMETIC_TYPE_P (t2) || code2 == ENUMERAL_TYPE
+ || code2 == COMPLEX_TYPE))
+ return type_after_usual_arithmetic_conversions (t1, t2);
- default:
- return build_type_attribute_variant (t1, attributes);
- }
+ else if ((TYPE_PTR_P (t1) && TYPE_PTR_P (t2))
+ || (TYPE_PTRMEM_P (t1) && TYPE_PTRMEM_P (t2))
+ || (TYPE_PTRMEMFUNC_P (t1) && TYPE_PTRMEMFUNC_P (t2)))
+ return composite_pointer_type (t1, t2, error_mark_node, error_mark_node,
+ "conversion");
+
+ else
+ abort ();
}
/* Compare two exception specifier types for exactness or subsetness, if
diff --git a/gcc/testsuite/g++.dg/other/redecl1.C b/gcc/testsuite/g++.dg/other/redecl1.C
new file mode 100644
index 0000000..cfcf668
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/redecl1.C
@@ -0,0 +1,10 @@
+// PR c++/5857
+// This testcase failed because during duplicate_decls the type was promoted
+// to int.
+
+// { dg-do compile }
+
+typedef char baz;
+extern const char foo[];
+const baz foo[] = "xyz";
+const char bar[] = "abc";