[lto] Remove excessively strict check for nothrow

Diego Novillo dnovillo@google.com
Thu Dec 4 15:08:00 GMT 2008


When we are merging two function declarations that contain mixed
nothrow attributes, two things can happen

1- The prevailing definition is marked nothrow and the other
   isn't.  In this case, we simply add the prevailing definition
   to the list of decls that will need to be fixed up in
   pass_ipa_lto_wpa_fixup (which essentially just cleans up
   the CFG for call sites that used to be inside EH regions).

2- If the prevailing definition was considered throwing and the
   overridden is nothrow, we used to emit an error.  The
   rationale was that the code that considered it nothrow would
   not have EH regions around its call sites.
   
   This is too strict, as it commonly happens when one TU sees an
   external call which it conservatively considers throwing, but
   in another TU we may have the complete definition which is not
   throwing  (as the testcase shows).

   The other way that this may happen is due to user error, where
   the declaration is marked nothrow but the definition actually
   throws.  In this case, we could emit a warning, but it would
   trigger many false positives.


Tested on x86_64.

Diego.

lto/ChangeLog

	* lto/lto.c (lto_fixup_tree): Do not emit an error when
	PREVAILING throw but T doesn't.

testsuite/ChangeLog.lto

	* g++.dg/lto/20081203_0.C: New.
	* g++.dg/lto/20081203_1.C: New.

Index: testsuite/g++.dg/lto/20081203_0.C
===================================================================
--- testsuite/g++.dg/lto/20081203_0.C	(revision 0)
+++ testsuite/g++.dg/lto/20081203_0.C	(revision 0)
@@ -0,0 +1,5 @@
+extern void f();
+extern void g();
+struct Foo { static inline void Bar() { f(); } };
+static void Func() { Foo::Bar(); }
+int main() { g (); Func(); return 0; }
Index: testsuite/g++.dg/lto/20081203_1.C
===================================================================
--- testsuite/g++.dg/lto/20081203_1.C	(revision 0)
+++ testsuite/g++.dg/lto/20081203_1.C	(revision 0)
@@ -0,0 +1,4 @@
+void f () {}
+struct Foo { static inline void Bar() { f(); } };
+static void Func() { Foo::Bar(); }
+void g () { Func (); }
Index: lto/lto.c
===================================================================
--- lto/lto.c	(revision 142405)
+++ lto/lto.c	(working copy)
@@ -1085,21 +1085,16 @@ lto_fixup_tree (tree *tp, int *walk_subt
 		 the call to PREVAILING was generated assuming that
 		 the function didn't throw, which means that CFG
 		 cleanup may have removed surrounding try/catch
-		 regions.  In that case, emit an error.
+		 regions.
 
 		 Note that we currently accept these cases even when
 		 they occur within a single file.  It's certainly a
 		 user error, but we silently allow the compiler to
 		 remove surrounding try/catch regions.  Perhaps we
-		 could demote this to a warning instead.  */
+		 could emit a warning here, instead of silently
+		 accepting the conflicting declaration.  */
 	      if (TREE_NOTHROW (prevailing))
 		lto_mark_nothrow_fndecl (prevailing);
-	      else if (!TREE_NO_WARNING (prevailing))
-		{
-		  error ("%J%qD declared as nothrow, but it really throws", t,
-			 prevailing);
-		  TREE_NO_WARNING (prevailing) = 1;
-		}
 	    }
 
 	  pointer_set_insert (fixup_data->free_list, t);



More information about the Gcc-patches mailing list