aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/testsuite/gcc.dg/pr104506-1.c12
-rw-r--r--gcc/testsuite/gcc.dg/pr104506-2.c11
-rw-r--r--gcc/testsuite/gcc.dg/pr104506-3.c11
-rw-r--r--gcc/tree-ssa.cc20
4 files changed, 47 insertions, 7 deletions
diff --git a/gcc/testsuite/gcc.dg/pr104506-1.c b/gcc/testsuite/gcc.dg/pr104506-1.c
new file mode 100644
index 0000000..5eb7191
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr104506-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu11" } */
+/* PR c/104506: we used to ICE after the error of
+ changing the type. */
+
+void
+foo (double x)
+/* { dg-message "note: previous definition" "previous definition" { target *-*-* } .-1 } */
+{
+ (void)x;
+ int x; /* { dg-error "redeclared as different kind of symbol" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr104506-2.c b/gcc/testsuite/gcc.dg/pr104506-2.c
new file mode 100644
index 0000000..3c3aaaa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr104506-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu11" } */
+/* PR c/104506: we used to ICE after the error of
+ changing the type. */
+void
+foo (double x)
+/* { dg-message "note: previous definition" "previous definition" { target *-*-* } .-1 } */
+{
+ x;
+ int x; /* { dg-error "redeclared as different kind of symbol" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr104506-3.c b/gcc/testsuite/gcc.dg/pr104506-3.c
new file mode 100644
index 0000000..b14deb5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr104506-3.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* PR c/104506: we used to ICE after the error of
+ changing the type. */
+double x;
+/* { dg-message "note: previous declaration" "previous declaration" { target *-*-* } .-1 } */
+void
+foo (void)
+{
+ x;
+}
+int x; /* { dg-error "conflicting types" } */
diff --git a/gcc/tree-ssa.cc b/gcc/tree-ssa.cc
index 430875a..423dd87 100644
--- a/gcc/tree-ssa.cc
+++ b/gcc/tree-ssa.cc
@@ -1256,18 +1256,24 @@ delete_tree_ssa (struct function *fn)
bool
tree_ssa_useless_type_conversion (tree expr)
{
+ tree outer_type, inner_type;
+
/* If we have an assignment that merely uses a NOP_EXPR to change
the top of the RHS to the type of the LHS and the type conversion
is "safe", then strip away the type conversion so that we can
enter LHS = RHS into the const_and_copies table. */
- if (CONVERT_EXPR_P (expr)
- || TREE_CODE (expr) == VIEW_CONVERT_EXPR
- || TREE_CODE (expr) == NON_LVALUE_EXPR)
- return useless_type_conversion_p
- (TREE_TYPE (expr),
- TREE_TYPE (TREE_OPERAND (expr, 0)));
+ if (!CONVERT_EXPR_P (expr)
+ && TREE_CODE (expr) != VIEW_CONVERT_EXPR
+ && TREE_CODE (expr) != NON_LVALUE_EXPR)
+ return false;
- return false;
+ outer_type = TREE_TYPE (expr);
+ inner_type = TREE_TYPE (TREE_OPERAND (expr, 0));
+
+ if (inner_type == error_mark_node)
+ return false;
+
+ return useless_type_conversion_p (outer_type, inner_type);
}
/* Strip conversions from EXP according to