I am looking at an internally reported bug against 4.6 that starts with something like this:
$ cat a.cc int bar(int); struct B { B(int); ~B() __attribute__((noreturn)); }; int foo(void) { B::B f(10); return 0; } int bar(int j) { B(10); } $ ./cc1plus -Wall -Werror a.cc int foo() 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 int bar(int) Analyzing compilation unit a.cc: In function 'int bar(int)': a.cc:18:1: error: control reaches end of non-void function [-Werror=return-type] [ ... ] The parser diagnoses the syntax error and proceeds to not emit any destructor calls. So, when we run pass_warn_function_return in GIMPLE, the analysis never finds a call to B's destructor (which was marked noreturn). This causes the spurious warning/error that has nothing to do with the original syntax error. This causes confusion, clearly. Initially, I had thought of two possible solutions to address this: 1- Fix the parser so it adds the destructor calls. This may be tricky, as there may be other termination actions the parser does that may get confused because of the syntax error. 2- Gate pass_warn_function_return so that it doesn't run if there are errors in the code already. This is the easiest fix, though it may make us lose valid diagnostics if there were other errors in the code. Ian suggested an even broader solution. If there are syntax errors produced by the parser, let's quit right before we even enter the middle end in toplev.c:compile_file. That is, change if (flag_syntax_only || flag_wpa) return; to if (flag_syntax_only || flag_wpa || errorcount > 0) return; I don't see anything wrong with that. It avoids feeding bad IL to the middle-end if the parser decided to bail out early due to errors. It would cover all the front ends. Any reason why this would not be a sensible solution? This same problem exists in mainline. Thanks. Diego.