aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2005-02-10 13:18:52 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2005-02-10 13:18:52 +0100
commitccf7f8806152d202c5ef8c222bba54dd7bc109cc (patch)
tree3de2bb26e3aa22fa9445518adfa866f637666dcc
parentb49900cc9356d771f3ef47ef7ed551f01e5c7fe5 (diff)
downloadgcc-ccf7f8806152d202c5ef8c222bba54dd7bc109cc.zip
gcc-ccf7f8806152d202c5ef8c222bba54dd7bc109cc.tar.gz
gcc-ccf7f8806152d202c5ef8c222bba54dd7bc109cc.tar.bz2
re PR c/19342 (ICE in common_type, at c-typeck.c:490)
PR c/19342 * c-typeck.c (common_type): New routine. Old common_type renamed to... (c_common_type): ...this. (build_conditional_expr, build_binary_op): Use c_common_type instead of common_type. * gcc.c-torture/execute/20050119-1.c: New test. From-SVN: r94803
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/c-typeck.c24
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20050119-1.c37
4 files changed, 69 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6e14ace..dfef24b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2005-02-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/19342
+ * c-typeck.c (common_type): New routine. Old common_type renamed
+ to...
+ (c_common_type): ...this.
+ (build_conditional_expr, build_binary_op): Use c_common_type instead
+ of common_type.
+
2005-02-10 Steven Bosscher <stevenb@suse.de>
* doc/md.texi: Replace @samp{length} with @code{length}.
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index f04ba73..3a20292 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -470,8 +470,8 @@ common_pointer_type (tree t1, tree t2)
This is the type for the result of most arithmetic operations
if the operands have the given two types. */
-tree
-common_type (tree t1, tree t2)
+static tree
+c_common_type (tree t1, tree t2)
{
enum tree_code code1;
enum tree_code code2;
@@ -522,7 +522,7 @@ common_type (tree t1, tree t2)
{
tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
- tree subtype = common_type (subtype1, subtype2);
+ tree subtype = c_common_type (subtype1, subtype2);
if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
return t1;
@@ -592,6 +592,18 @@ common_type (tree t1, tree t2)
return t2;
}
+/* Wrapper around c_common_type that is used by c-common.c. ENUMERAL_TYPEs
+ are allowed here and are converted to their compatible integer types. */
+tree
+common_type (tree t1, tree t2)
+{
+ if (TREE_CODE (t1) == ENUMERAL_TYPE)
+ t1 = c_common_type_for_size (TYPE_PRECISION (t1), 1);
+ if (TREE_CODE (t2) == ENUMERAL_TYPE)
+ t2 = c_common_type_for_size (TYPE_PRECISION (t2), 1);
+ return c_common_type (t1, t2);
+}
+
/* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
or various other operations. Return 2 if they are compatible
but a warning may be needed if you use them together. */
@@ -2893,7 +2905,7 @@ build_conditional_expr (tree ifexp, tree op1, tree op2)
&& (code2 == INTEGER_TYPE || code2 == REAL_TYPE
|| code2 == COMPLEX_TYPE))
{
- result_type = common_type (type1, type2);
+ result_type = c_common_type (type1, type2);
/* If -Wsign-compare, warn here if type1 and type2 have
different signedness. We'll promote the signed to unsigned
@@ -7461,7 +7473,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
if (shorten || common || short_compare)
- result_type = common_type (type0, type1);
+ result_type = c_common_type (type0, type1);
/* For certain operations (which identify themselves by shorten != 0)
if both args were extended from the same smaller type,
@@ -7519,7 +7531,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
&& (unsigned0 || !uns))
result_type
= c_common_signed_or_unsigned_type
- (unsigned0, common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
+ (unsigned0, c_common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
else if (TREE_CODE (arg0) == INTEGER_CST
&& (unsigned1 || !uns)
&& (TYPE_PRECISION (TREE_TYPE (arg1))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e3fe037..b73d947 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2005-02-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/19342
+ * gcc.c-torture/execute/20050119-1.c: New test.
+
2005-02-09 Mark Mitchell <mark@codesourcery.com>
PR c++/19811
diff --git a/gcc/testsuite/gcc.c-torture/execute/20050119-1.c b/gcc/testsuite/gcc.c-torture/execute/20050119-1.c
new file mode 100644
index 0000000..55f33a0
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20050119-1.c
@@ -0,0 +1,37 @@
+/* PR c/19342 */
+typedef enum { A, B, C, D } E;
+
+struct S {
+ E __attribute__ ((mode (__byte__))) a;
+ E __attribute__ ((mode (__byte__))) b;
+ E __attribute__ ((mode (__byte__))) c;
+ E __attribute__ ((mode (__byte__))) d;
+};
+
+extern void abort (void);
+extern void exit (int);
+
+void
+foo (struct S *s)
+{
+ if (s->a != s->b)
+ abort ();
+ if (s->c != C)
+ abort ();
+}
+
+int
+main (void)
+{
+ struct S s[2];
+ s[0].a = B;
+ s[0].b = B;
+ s[0].c = C;
+ s[0].d = D;
+ s[1].a = D;
+ s[1].b = C;
+ s[1].c = B;
+ s[1].d = A;
+ foo (s);
+ exit (0);
+}