Commit ccf7f880 by Jakub Jelinek Committed by Jakub Jelinek

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
parent b49900cc
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> 2005-02-10 Steven Bosscher <stevenb@suse.de>
* doc/md.texi: Replace @samp{length} with @code{length}. * doc/md.texi: Replace @samp{length} with @code{length}.
......
...@@ -470,8 +470,8 @@ common_pointer_type (tree t1, tree t2) ...@@ -470,8 +470,8 @@ common_pointer_type (tree t1, tree t2)
This is the type for the result of most arithmetic operations This is the type for the result of most arithmetic operations
if the operands have the given two types. */ if the operands have the given two types. */
tree static tree
common_type (tree t1, tree t2) c_common_type (tree t1, tree t2)
{ {
enum tree_code code1; enum tree_code code1;
enum tree_code code2; enum tree_code code2;
...@@ -522,7 +522,7 @@ common_type (tree t1, tree t2) ...@@ -522,7 +522,7 @@ common_type (tree t1, tree t2)
{ {
tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1; tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2; 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) if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
return t1; return t1;
...@@ -592,6 +592,18 @@ common_type (tree t1, tree t2) ...@@ -592,6 +592,18 @@ common_type (tree t1, tree t2)
return 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 /* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
or various other operations. Return 2 if they are compatible or various other operations. Return 2 if they are compatible
but a warning may be needed if you use them together. */ but a warning may be needed if you use them together. */
...@@ -2893,7 +2905,7 @@ build_conditional_expr (tree ifexp, tree op1, tree op2) ...@@ -2893,7 +2905,7 @@ build_conditional_expr (tree ifexp, tree op1, tree op2)
&& (code2 == INTEGER_TYPE || code2 == REAL_TYPE && (code2 == INTEGER_TYPE || code2 == REAL_TYPE
|| code2 == COMPLEX_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 /* If -Wsign-compare, warn here if type1 and type2 have
different signedness. We'll promote the signed to unsigned 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, ...@@ -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); int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
if (shorten || common || short_compare) 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) /* For certain operations (which identify themselves by shorten != 0)
if both args were extended from the same smaller type, 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, ...@@ -7519,7 +7531,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
&& (unsigned0 || !uns)) && (unsigned0 || !uns))
result_type result_type
= c_common_signed_or_unsigned_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 else if (TREE_CODE (arg0) == INTEGER_CST
&& (unsigned1 || !uns) && (unsigned1 || !uns)
&& (TYPE_PRECISION (TREE_TYPE (arg1)) && (TYPE_PRECISION (TREE_TYPE (arg1))
......
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> 2005-02-09 Mark Mitchell <mark@codesourcery.com>
PR c++/19811 PR c++/19811
......
/* 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment