]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Honor noipa attribute for FE nothrow discovery [PR119518]
authorJakub Jelinek <jakub@redhat.com>
Mon, 31 Mar 2025 05:51:04 +0000 (07:51 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 31 Mar 2025 05:51:04 +0000 (07:51 +0200)
The following testcase has different code generation in bar depending on
whether foo is defined or just declared.
That is undesirable when it has noipa attribute, that attribute is
documented to be a black box between caller and callee, so the caller
shouldn't know about any implicitly determined properties of the callee
and callee shouldn't know about its callers.

E.g. the ipa-pure-const passes including nothrow discovery in there all
honor noipa attribute, but the FE did not.

2025-03-31  Jakub Jelinek  <jakub@redhat.com>

PR c++/119518
* decl.cc (finish_function): Don't set TREE_NOTHROW for
functions with "noipa" attribute even when we can prove
they can't throw.

* g++.dg/opt/pr119518.C: New test.

gcc/cp/decl.cc
gcc/testsuite/g++.dg/opt/pr119518.C [new file with mode: 0644]

index 7d10b228ec6284ffd943d6e0b1c4dea6b0df62ec..2ed94fd786ce7532da6a1bfb773cb640b274f7e5 100644 (file)
@@ -19454,7 +19454,8 @@ finish_function (bool inline_p)
       && !cp_function_chain->can_throw
       && !flag_non_call_exceptions
       && !decl_replaceable_p (fndecl,
-                             opt_for_fn (fndecl, flag_semantic_interposition)))
+                             opt_for_fn (fndecl, flag_semantic_interposition))
+      && !lookup_attribute ("noipa", DECL_ATTRIBUTES (fndecl)))
     TREE_NOTHROW (fndecl) = 1;
 
  cleanup:
diff --git a/gcc/testsuite/g++.dg/opt/pr119518.C b/gcc/testsuite/g++.dg/opt/pr119518.C
new file mode 100644 (file)
index 0000000..152b880
--- /dev/null
@@ -0,0 +1,20 @@
+// PR c++/119518
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-optimized" }
+// { dg-final { scan-tree-dump "S::~S \\\(&s\\\)" "optimized" } }
+
+[[gnu::noipa, noreturn]] void
+foo ()
+{
+  for (;;)
+    ;
+}
+
+struct S { ~S (); };
+
+void
+bar ()
+{
+  S s;
+  foo ();
+}