aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/c/gimple-parser.cc10
-rw-r--r--gcc/testsuite/gcc.dg/gimplefe-error-15.c13
-rw-r--r--gcc/tree-cfg.cc16
-rw-r--r--gcc/tree-cfg.h4
4 files changed, 35 insertions, 8 deletions
diff --git a/gcc/c/gimple-parser.cc b/gcc/c/gimple-parser.cc
index 5a2da2c..18ed4d4 100644
--- a/gcc/c/gimple-parser.cc
+++ b/gcc/c/gimple-parser.cc
@@ -364,6 +364,16 @@ c_parser_parse_gimple_body (c_parser *cparser, char *gimple_pass,
cgraph_node::get_create (cfun->decl);
cgraph_edge::rebuild_edges ();
}
+
+ /* Perform IL validation and if any error is found abort compilation
+ of this function by zapping its body. */
+ if ((cfun->curr_properties & PROP_cfg)
+ && verify_gimple_in_cfg (cfun, false, false))
+ init_empty_tree_cfg ();
+ else if (!(cfun->curr_properties & PROP_cfg)
+ && verify_gimple_in_seq (gimple_body (current_function_decl), false))
+ gimple_set_body (current_function_decl, NULL);
+
dump_function (TDI_gimple, current_function_decl);
}
diff --git a/gcc/testsuite/gcc.dg/gimplefe-error-15.c b/gcc/testsuite/gcc.dg/gimplefe-error-15.c
new file mode 100644
index 0000000..066cd84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-error-15.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fgimple" } */
+
+unsigned a;
+static double *d;
+static _Bool b;
+__GIMPLE int
+foo (int n)
+{
+ b = __builtin_add_overflow (n, *d, &a);
+} /* { dg-error "invalid argument" } */
+
+/* { dg-message "" "" { target *-*-* } 0 } */
diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
index 9b2c0f6..d982988 100644
--- a/gcc/tree-cfg.cc
+++ b/gcc/tree-cfg.cc
@@ -5300,13 +5300,15 @@ verify_gimple_transaction (gtransaction *stmt)
/* Verify the GIMPLE statements inside the statement list STMTS. */
-DEBUG_FUNCTION void
-verify_gimple_in_seq (gimple_seq stmts)
+DEBUG_FUNCTION bool
+verify_gimple_in_seq (gimple_seq stmts, bool ice)
{
timevar_push (TV_TREE_STMT_VERIFY);
- if (verify_gimple_in_seq_2 (stmts))
+ bool res = verify_gimple_in_seq_2 (stmts);
+ if (res && ice)
internal_error ("%<verify_gimple%> failed");
timevar_pop (TV_TREE_STMT_VERIFY);
+ return res;
}
/* Return true when the T can be shared. */
@@ -5496,8 +5498,8 @@ collect_subblocks (hash_set<tree> *blocks, tree block)
/* Verify the GIMPLE statements in the CFG of FN. */
-DEBUG_FUNCTION void
-verify_gimple_in_cfg (struct function *fn, bool verify_nothrow)
+DEBUG_FUNCTION bool
+verify_gimple_in_cfg (struct function *fn, bool verify_nothrow, bool ice)
{
basic_block bb;
bool err = false;
@@ -5652,11 +5654,13 @@ verify_gimple_in_cfg (struct function *fn, bool verify_nothrow)
eh_table->traverse<hash_set<gimple *> *, verify_eh_throw_stmt_node>
(&visited_throwing_stmts);
- if (err || eh_error_found)
+ if (ice && (err || eh_error_found))
internal_error ("verify_gimple failed");
verify_histograms ();
timevar_pop (TV_TREE_STMT_VERIFY);
+
+ return (err || eh_error_found);
}
diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h
index 95ec93e..8c22c3d 100644
--- a/gcc/tree-cfg.h
+++ b/gcc/tree-cfg.h
@@ -63,8 +63,8 @@ extern gphi *get_virtual_phi (basic_block);
extern gimple *first_stmt (basic_block);
extern gimple *last_stmt (basic_block);
extern gimple *last_and_only_stmt (basic_block);
-extern void verify_gimple_in_seq (gimple_seq);
-extern void verify_gimple_in_cfg (struct function *, bool);
+extern bool verify_gimple_in_seq (gimple_seq, bool = true);
+extern bool verify_gimple_in_cfg (struct function *, bool, bool = true);
extern tree gimple_block_label (basic_block);
extern void add_phi_args_after_copy_bb (basic_block);
extern void add_phi_args_after_copy (basic_block *, unsigned, edge);