diff options
author | Jason Merrill <jason@redhat.com> | 2018-02-16 16:03:02 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2018-02-16 16:03:02 -0500 |
commit | 18afe4c9fcfef7d03832816581fb8804cde0aa4e (patch) | |
tree | 1da777f19f6dda74450c197d022f78fe8e819c05 /gcc | |
parent | 3664e317b8efce5e4b37aca4724b05945bcbbb4f (diff) | |
download | gcc-18afe4c9fcfef7d03832816581fb8804cde0aa4e.zip gcc-18afe4c9fcfef7d03832816581fb8804cde0aa4e.tar.gz gcc-18afe4c9fcfef7d03832816581fb8804cde0aa4e.tar.bz2 |
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: r257763
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/call.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tree-ssa/volatile1.C | 28 |
3 files changed, 40 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 07788c0..d4a9c67 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2018-02-16 Jason Merrill <jason@redhat.com> + 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. + PR c++/81853 - using-directive and constexpr. * constexpr.c (cxx_eval_constant_expression): Handle USING_STMT. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index d3d0966..7c93c6d 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -9284,8 +9284,14 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **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 0000000..00f04a0 --- /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; +} |