This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[RFA] Multiple fixes for PR c/27489
- From: Volker Reichelt <reichelt at igpm dot rwth-aachen dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: pinskia at gcc dot gnu dot org
- Date: Tue, 09 May 2006 15:28:04 +0200 (CEST)
- Subject: [RFA] Multiple fixes for PR c/27489
Currently, the C frontend ICEs on the following invalid testcase:
void foo()
{
switch (,) { }
}
PR27489.c: In function 'foo':
PR27489.c:3: error: expected expression before ',' token
PR27489.c:3: internal compiler error: tree check: expected class 'type', have 'exceptional' (error_mark) in c_start_case, at c-typeck.c:7035
Please submit a full bug report, [etc.]
Andrew Pinksi suggested the following patch which avoids creating
invalid COMPOUND_EXPRs. Btw, the patch also fixes PR27490 where
the compiler trips over "sizeof(,)":
===================================================================
--- c-typeck.c (revision 113594)
+++ c-typeck.c (working copy)
@@ -3379,6 +3379,9 @@ build_compound_expr (tree expr1, tree ex
else if (warn_unused_value)
warn_if_unused_value (expr1, input_location);
+ if (TREE_CODE (expr2) == ERROR_MARK)
+ return error_mark_node;
+
return build2 (COMPOUND_EXPR, TREE_TYPE (expr2), expr1, expr2);
}
===================================================================
I'd prefer checking "expr == error_mark_node"", but otherwise this
makes sense to me.
However, the logic in c_start_case where the ICE actually happens is
also broken. We explicitly check "code != ERROR_MARK" for a case
that would handle the error_mark_node gracefully and instead choose
the case that will inevitably crash under this condition. Ouch.
The patch below just removes the bogus test and cleans up the code
a little (removing unused variables and superfluous computations).
Which patches should go in 4.1, 4.2, and 4.3 once we enter stage 1 again?
Regards,
Volker
2006-05-09 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c/27489
* c-typeck.c (c_start_case): Handle invalid orig_type correctly.
Clean up.
===================================================================
--- gcc/gcc/c-typeck.c 2006-05-08 22:57:52 +0200
+++ gcc/gcc/c-typeck.c 2006-05-08 22:57:59 +0200
@@ -7017,17 +7017,14 @@ struct c_switch *c_switch_stack;
tree
c_start_case (tree exp)
{
- enum tree_code code;
- tree type, orig_type = error_mark_node;
+ tree orig_type = error_mark_node;
struct c_switch *cs;
if (exp != error_mark_node)
{
- code = TREE_CODE (TREE_TYPE (exp));
orig_type = TREE_TYPE (exp);
- if (!INTEGRAL_TYPE_P (orig_type)
- && code != ERROR_MARK)
+ if (!INTEGRAL_TYPE_P (orig_type))
{
error ("switch quantity not an integer");
exp = integer_zero_node;
@@ -7035,7 +7032,7 @@ c_start_case (tree exp)
}
else
{
- type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
+ tree type = TYPE_MAIN_VARIANT (orig_type);
if (!in_system_header
&& (type == long_integer_type_node
@@ -7044,7 +7041,6 @@ c_start_case (tree exp)
"converted to %<int%> in ISO C");
exp = default_conversion (exp);
- type = TREE_TYPE (exp);
}
}
===================================================================