diff mbox

[google] Do not execute pass_warn_function_return after a syntax error (issue4629076)

Message ID 20110627172958.BB791AE1D6@tobiano.tor.corp.google.com
State New
Headers show

Commit Message

Diego Novillo June 27, 2011, 5:29 p.m. UTC
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  <dnovillo@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  <dnovillo@google.com>

	Google ref 4487457.

	* g++.dg/parse/cascading-errors.C: New.
	* g++.old-deja/g++.jason/report.C: Remove expected reachability
	warnings.


--
This patch is available for review at http://codereview.appspot.com/4629076
diff mbox

Patch

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 */