This patch is the compromise solution for the problem described in http://gcc.gnu.org/ml/gcc/2011-06/msg00213.html. We should not try to analyze the IL in the presence of syntax errors.
The full solution is simpler, but it changes diagnostic behaviour too much for the release branch, so this patch simply stops the faulty function return analysis from running. Tested on x86_64. Committed to google/gcc-4_6. Diego. ChangeLog.google-4_6 2011-06-27 Diego Novillo <dnovi...@google.com> Google ref 4487457. * tree-cfg.c (gate_warn_function_return): New. (pass_warn_function_return): Use it. testsuite/ChangeLog.google-4_6 2011-06-27 Diego Novillo <dnovi...@google.com> Google ref 4487457. * g++.dg/parse/cascading-errors.C: New. * g++.old-deja/g++.jason/report.C: Remove expected reachability warnings. Index: gcc/testsuite/g++.old-deja/g++.jason/report.C =================================================================== --- gcc/testsuite/g++.old-deja/g++.jason/report.C (revision 175523) +++ gcc/testsuite/g++.old-deja/g++.jason/report.C (working copy) @@ -72,6 +72,3 @@ int darg (char X::*p) { undef3 (1); // { dg-error "" } implicit declaration } // { dg-warning "no return statement" } - -// { dg-message "warning: control reaches end of non-void function" "" { target *-*-* } 36 } -// { dg-message "warning: control reaches end of non-void function" "" { target *-*-* } 65 } Index: gcc/testsuite/g++.dg/parse/cascading-errors.C =================================================================== --- gcc/testsuite/g++.dg/parse/cascading-errors.C (revision 0) +++ gcc/testsuite/g++.dg/parse/cascading-errors.C (revision 0) @@ -0,0 +1,34 @@ +// { dg-do compile } +// { dg-options "-Wall -Werror" } +// a.cc:11:3: error: 'B::B' names the constructor, not the type +// a.cc:11:8: error: expected ';' before 'f' +// a.cc:11:13: error: statement cannot resolve address of overloaded function +// a.cc:18:1: error: control reaches end of non-void function [-Werror=return-type] + + +// After a parsing error, the IL ends up in an inconsistent state. +// In this case, the parser never adds destructor calls, which causes +// B::~B to never be called, triggering the error 'control reaches end +// of non-void function' from the middle end. This second error is +// bogus and only confuses the user. + +int bar(int); + +struct B { + B(int); + ~B() __attribute__((noreturn)); +}; + + +int foo(void) +{ + B::B f(10); // { dg-error "names the constructor" } + // { dg-error "expected ';'" "" { target *-*-* } 25 } + // { dg-error "cannot resolve" "" { target *-*-* } 25 } + return 0; +} + +int bar(int j) +{ + B(10); +} Index: gcc/tree-cfg.c =================================================================== --- gcc/tree-cfg.c (revision 175523) +++ gcc/tree-cfg.c (working copy) @@ -7445,12 +7445,28 @@ extract_true_false_edges_from_block (bas } } +static bool +gate_warn_function_return (void) +{ + /* FIXME - Disable this warning if there were errors upstream + (Google ref 4487457). We should not even get this far down in + the optimization process after a syntax error in the parser. + However, bailing out right after parsing causes many regressions + in the testsuite, because tests expect more errors from the + compiler. + + To avoid invasive changes in 4.6, the trunk variant of this fix + is described in http://gcc.gnu.org/ml/gcc/2011-06/msg00213.html. */ + return !seen_error (); +} + + struct gimple_opt_pass pass_warn_function_return = { { GIMPLE_PASS, "*warn_function_return", /* name */ - NULL, /* gate */ + gate_warn_function_return, /* gate */ execute_warn_function_return, /* execute */ NULL, /* sub */ NULL, /* next */ -- This patch is available for review at http://codereview.appspot.com/4629076