This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[lto] Remove excessively strict check for nothrow
- From: Diego Novillo <dnovillo at google dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 4 Dec 2008 10:07:46 -0500
- Subject: [lto] Remove excessively strict check for nothrow
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);