PR c++/81420 - not extending temporary lifetime.
authorJason Merrill <jason@redhat.com>
Wed, 23 May 2018 03:52:56 +0000 (23:52 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 23 May 2018 03:52:56 +0000 (23:52 -0400)
* call.c (extend_ref_init_temps_1): Handle ARRAY_REF.
* class.c (build_base_path): Avoid redundant move of an rvalue.

From-SVN: r260563

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/testsuite/g++.dg/cpp0x/temp-extend1.C [new file with mode: 0644]

index ce22731..ee7361b 100644 (file)
@@ -1,5 +1,9 @@
 2018-05-22  Jason Merrill  <jason@redhat.com>
 
+       PR c++/81420 - not extending temporary lifetime.
+       * call.c (extend_ref_init_temps_1): Handle ARRAY_REF.
+       * class.c (build_base_path): Avoid redundant move of an rvalue.
+
        PR c++/85866 - error with .* in default template arg.
        * pt.c (tsubst_copy_and_build): Handle partial instantiation.
 
index 1df4d14..c100a92 100644 (file)
@@ -11061,7 +11061,9 @@ extend_ref_init_temps_1 (tree decl, tree init, vec<tree, va_gc> **cleanups)
   if (TREE_CODE (sub) != ADDR_EXPR)
     return init;
   /* Deal with binding to a subobject.  */
-  for (p = &TREE_OPERAND (sub, 0); TREE_CODE (*p) == COMPONENT_REF; )
+  for (p = &TREE_OPERAND (sub, 0);
+       (TREE_CODE (*p) == COMPONENT_REF
+       || TREE_CODE (*p) == ARRAY_REF); )
     p = &TREE_OPERAND (*p, 0);
   if (TREE_CODE (*p) == TARGET_EXPR)
     {
index a9a0fa9..25753d4 100644 (file)
@@ -426,7 +426,7 @@ build_base_path (enum tree_code code,
     {
       expr = cp_build_fold_indirect_ref (expr);
       expr = build_simple_base_path (expr, binfo);
-      if (rvalue)
+      if (rvalue && lvalue_p (expr))
        expr = move (expr);
       if (want_pointer)
        expr = build_address (expr);
diff --git a/gcc/testsuite/g++.dg/cpp0x/temp-extend1.C b/gcc/testsuite/g++.dg/cpp0x/temp-extend1.C
new file mode 100644 (file)
index 0000000..639f945
--- /dev/null
@@ -0,0 +1,19 @@
+// PR c++/81420
+// { dg-do run { target c++11 } }
+
+int d;
+
+struct A
+{
+  int i[2];
+  ~A() { ++d; };
+};
+
+struct B: A {};
+
+int main()
+{
+  const int &r = B().i[0];
+  if (d != 0)
+    __builtin_abort();
+}