From: Jason Merrill Date: Fri, 16 Feb 2018 21:34:57 +0000 (-0500) Subject: PR c++/84151 - unnecessary volatile load with static member. X-Git-Tag: releases/gcc-6.5.0~520 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c58d0290217b12c6a5e775e9f5103cdd3e73ccf6;p=thirdparty%2Fgcc.git PR c++/84151 - unnecessary volatile load with static member. * call.c (build_new_method_call_1): Avoid loading from a volatile lvalue used as the object argument for a static member function. From-SVN: r257768 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 807ed4604823..9f396c338aef 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2018-02-16 Jason Merrill + + PR c++/84151 - unnecessary volatile load with static member. + * call.c (build_new_method_call_1): Avoid loading from a volatile + lvalue used as the object argument for a static member function. + 2017-09-15 Jakub Jelinek Backported from mainline diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 8090dbf29e6f..9dbb274b3ad2 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -8437,8 +8437,14 @@ build_new_method_call_1 (tree instance, tree fns, vec **args, if (TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE && !is_dummy_object (instance) && TREE_SIDE_EFFECTS (instance)) - call = build2 (COMPOUND_EXPR, TREE_TYPE (call), - instance, call); + { + /* But avoid the implicit lvalue-rvalue conversion when 'a' + is volatile. */ + tree a = instance; + if (TREE_THIS_VOLATILE (a)) + a = build_this (a); + call = build2 (COMPOUND_EXPR, TREE_TYPE (call), a, call); + } else if (call != error_mark_node && DECL_DESTRUCTOR_P (cand->fn) && !VOID_TYPE_P (TREE_TYPE (call))) diff --git a/gcc/testsuite/g++.dg/tree-ssa/volatile1.C b/gcc/testsuite/g++.dg/tree-ssa/volatile1.C new file mode 100644 index 000000000000..00f04a07d846 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/volatile1.C @@ -0,0 +1,28 @@ +// PR c++/84151 +// { dg-additional-options "-fdump-tree-gimple" } +// { dg-final { scan-tree-dump-not {\*this} "gimple" } } + +struct A { + static int& bar(int& a) { + return a; + } + static int i; + + int foo() volatile { + int v = c; + return i + bar(v); + } + + int c; +}; + +int A::i = 0; + +A a; + +int main() { + a.c = 2; + a.foo(); + + return 0; +}