When calling a static member function we still need to evaluate an explicit object argument. But we don't want to force a load of the entire object if the argument is volatile, so we take its address. If as a result it no longer has any side-effects, we don't need to evaluate it after all.
Tested x86_64-pc-linux-gnu, applying to trunk. gcc/cp/ChangeLog: PR c++/80456 * call.c (build_new_method_call_1): Check again for side-effects with a volatile object. gcc/testsuite/ChangeLog: PR c++/80456 * g++.dg/cpp0x/constexpr-volatile3.C: New test. --- gcc/cp/call.c | 3 ++- gcc/testsuite/g++.dg/cpp0x/constexpr-volatile3.C | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-volatile3.C diff --git a/gcc/cp/call.c b/gcc/cp/call.c index c9a8c0d305f..678e120a165 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -10793,7 +10793,8 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args, tree a = instance; if (TREE_THIS_VOLATILE (a)) a = build_this (a); - call = build2 (COMPOUND_EXPR, TREE_TYPE (call), a, call); + if (TREE_SIDE_EFFECTS (a)) + call = build2 (COMPOUND_EXPR, TREE_TYPE (call), a, call); } else if (call != error_mark_node && DECL_DESTRUCTOR_P (cand->fn) diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-volatile3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-volatile3.C new file mode 100644 index 00000000000..5c1e865e0ac --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-volatile3.C @@ -0,0 +1,15 @@ +// PR c++/80456 +// { dg-do compile { target c++11 } } + +struct A { + static constexpr bool test() noexcept { return true; } + + void f() volatile { + constexpr bool b = test(); + } +}; + +void g() { + A a; + a.f(); +} base-commit: 2efbbba16a0630fac8cadcd6d9e0ffaabfadb79f -- 2.27.0