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.
This commit is contained in:
parent
72809d6fe8
commit
2eea00c518
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
19
gcc/testsuite/g++.dg/other/pr94326.C
Normal file
19
gcc/testsuite/g++.dg/other/pr94326.C
Normal file
@ -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{});
|
||||
}
|
Loading…
Reference in New Issue
Block a user