[gcc(refs/users/marxin/heads/marxin-gcc-benchmark-branch)] c++: Avoid calls in non-evaluated contexts affect whether function can or can't throw [PR94326]

Martin Liska marxin@gcc.gnu.org
Mon Mar 30 11:09:26 GMT 2020


https://gcc.gnu.org/g:2eea00c518d5a72d0bdbc810ae675e7ad5fee414

commit 2eea00c518d5a72d0bdbc810ae675e7ad5fee414
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Fri Mar 27 10:04:31 2020 +0100

    c++: Avoid calls in non-evaluated contexts affect whether function can or can't throw [PR94326]
    
    The following testcase FAILs -fcompare-debug, because if we emit a
    -Wreturn-local-addr warning, we tsubst decltype in order to print the
    warning and as that function could throw, set_flags_from_callee during that
    sets cp_function_chain->can_throw and later on we don't set TREE_NOTHROW
    on foo.  While with -w or -Wno-return-local-addr, tsubst isn't called during
    the warning_at, cp_function_chain->can_throw is kept clear and TREE_NOTHROW
    is set on foo.
    It isn't just a matter of the warning though, in
    int foo ();
    int bar () { return sizeof (foo ()); }
    int baz () { return sizeof (int); }
    I don't really see why we should mark only baz as TREE_NOTHROW and not bar
    too, when neither can really throw.
    
    2020-03-27  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/94326
            * call.c (set_flags_from_callee): Don't update
            cp_function_chain->can_throw or current_function_returns_abnormally
            if cp_unevaluated_operand.
    
            * g++.dg/other/pr94326.C: New test.

Diff:
---
 gcc/cp/ChangeLog                     |  5 +++++
 gcc/cp/call.c                        | 11 +++++++----
 gcc/testsuite/ChangeLog              |  3 +++
 gcc/testsuite/g++.dg/other/pr94326.C | 19 +++++++++++++++++++
 4 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 46208b2d756..5b8c5e329db 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,10 @@
 2020-03-27  Jakub Jelinek  <jakub@redhat.com>
 
+	PR c++/94326
+	* call.c (set_flags_from_callee): Don't update
+	cp_function_chain->can_throw or current_function_returns_abnormally
+	if cp_unevaluated_operand.
+
 	PR c++/94339
 	* cvt.c (ocp_convert): Handle COMPOUND_EXPR by recursion on the second
 	operand and creating a new COMPOUND_EXPR if anything changed.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index bae4b2c0f52..02220ffb3a1 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -333,11 +333,14 @@ set_flags_from_callee (tree call)
 	   && internal_fn_flags (CALL_EXPR_IFN (call)) & ECF_NOTHROW)
     nothrow = true;
 
-  if (!nothrow && at_function_scope_p () && cfun && cp_function_chain)
-    cp_function_chain->can_throw = 1;
+  if (cfun && cp_function_chain && !cp_unevaluated_operand)
+    {
+      if (!nothrow && at_function_scope_p ())
+	cp_function_chain->can_throw = 1;
 
-  if (decl && TREE_THIS_VOLATILE (decl) && cfun && cp_function_chain)
-    current_function_returns_abnormally = 1;
+      if (decl && TREE_THIS_VOLATILE (decl))
+	current_function_returns_abnormally = 1;
+    }
 
   TREE_NOTHROW (call) = nothrow;
 }
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f0b1b5f006b..5f9b164d486 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
 2020-03-27  Jakub Jelinek  <jakub@redhat.com>
 
+	PR c++/94326
+	* g++.dg/other/pr94326.C: New test.
+
 	PR c++/94339
 	* g++.dg/other/pr94339.C: New test.
 	* g++.dg/ext/attr-copy-2.C: Comment out failing tests due to PR94346.
diff --git a/gcc/testsuite/g++.dg/other/pr94326.C b/gcc/testsuite/g++.dg/other/pr94326.C
new file mode 100644
index 00000000000..4069c038d52
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/pr94326.C
@@ -0,0 +1,19 @@
+// PR c++/94326
+// { dg-do compile { target c++11 } }
+// { dg-options "-fcompare-debug" }
+
+template <typename = int> struct A {
+  const int &foo() { return 0; }	// { dg-warning "returning reference to temporary" }
+  template <typename _Kt> void bar(_Kt) { foo(); }
+};
+struct B {
+  A<> b;
+  template <typename _Kt> auto baz(_Kt p1) -> decltype(b.bar(p1)) {
+    b.bar(p1);
+  }
+};
+struct C {};
+void operator<(C, int) {
+  B a;
+  a.baz(C{});
+}


More information about the Gcc-cvs mailing list