aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/call.c10
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/volatile1.C28
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;
+}