PR c++/84151 - unnecessary volatile load with static member.
authorJason Merrill <jason@redhat.com>
Fri, 16 Feb 2018 21:03:02 +0000 (16:03 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 16 Feb 2018 21:03:02 +0000 (16:03 -0500)
* 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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/testsuite/g++.dg/tree-ssa/volatile1.C [new file with mode: 0644]

index 07788c0d516325875abb8dc1fa52da3e8927faac..d4a9c67d2ec4eb67b70fa95f4fdd2876fe7889c7 100644 (file)
@@ -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.
 
index d3d0966f65ca66d93be7882240154c2e32cc3cba..7c93c6d8290a4d84e388aa6ca22a15e8273370d3 100644 (file)
@@ -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 (file)
index 0000000..00f04a0
--- /dev/null
@@ -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;
+}