[PR c++/82878] pass-by-invisiref in lambda
authorNathan Sidwell <nathan@acm.org>
Mon, 20 Nov 2017 14:39:00 +0000 (14:39 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Mon, 20 Nov 2017 14:39:00 +0000 (14:39 +0000)
https://gcc.gnu.org/ml/gcc-patches/2017-11/msg01115.html
PR c++/82878
PR c++/78495
* call.c (build_call_a): Don't set CALL_FROM_THUNK_P for inherited
ctor.
* cp-gimplify.c (cp_genericize_r): Restore THUNK dereference
inhibibition check removed in previous c++/78495 change.

PR c++/82878
* g++.dg/cpp0x/pr82878.C: New.
* g++.dg/cpp1z/inh-ctor38.C: Check moves too.

From-SVN: r254958

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-gimplify.c
gcc/cp/lambda.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-switch.C
gcc/testsuite/g++.dg/cpp0x/pr82878.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1z/inh-ctor38.C

index 6f4d30e1dfbe2177d5d5fc65d95c94545b7aebfb..e1e9d7238a68d35778df3b11f2b2e35bced3614e 100644 (file)
@@ -1,3 +1,12 @@
+2017-11-20  Nathan Sidwell  <nathan@acm.org>
+
+       PR c++/82878
+       PR c++/78495
+       * call.c (build_call_a): Don't set CALL_FROM_THUNK_P for inherited
+       ctor.
+       * cp-gimplify.c (cp_genericize_r): Restore THUNK dereference
+       inhibibition check removed in previous c++/78495 change.
+
 2017-11-20   Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/82781
index e09cf97920b553e32ee7b45aa02c226e2a0484a9..d242b07a06bcb4bf2a84fde860876a0983ded0b2 100644 (file)
@@ -376,18 +376,10 @@ build_call_a (tree function, int n, tree *argarray)
 
   TREE_HAS_CONSTRUCTOR (function) = (decl && DECL_CONSTRUCTOR_P (decl));
 
-  if (current_function_decl && decl
-      && flag_new_inheriting_ctors
-      && DECL_INHERITED_CTOR (current_function_decl)
-      && (DECL_INHERITED_CTOR (current_function_decl)
-         == DECL_CLONED_FUNCTION (decl)))
-    /* Pass arguments directly to the inherited constructor.  */
-    CALL_FROM_THUNK_P (function) = true;
-
   /* Don't pass empty class objects by value.  This is useful
      for tags in STL, which are used to control overload resolution.
      We don't need to handle other cases of copying empty classes.  */
-  else if (! decl || ! DECL_BUILT_IN (decl))
+  if (! decl || ! DECL_BUILT_IN (decl))
     for (i = 0; i < n; i++)
       {
        tree arg = CALL_EXPR_ARG (function, i);
index 8849f9d3735ed18d9bbf3ff47d8b311e74354b53..201a59505916269e16886bfb2fe63d88bcaa654d 100644 (file)
@@ -1078,6 +1078,14 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
       && omp_var_to_track (stmt))
     omp_cxx_notice_variable (wtd->omp_ctx, stmt);
 
+  /* Don't dereference parms in a thunk, pass the references through. */
+  if ((TREE_CODE (stmt) == CALL_EXPR && CALL_FROM_THUNK_P (stmt))
+      || (TREE_CODE (stmt) == AGGR_INIT_EXPR && AGGR_INIT_FROM_THUNK_P (stmt)))
+    {
+      *walk_subtrees = 0;
+      return NULL;
+    }
+
   /* Dereference invisible reference parms.  */
   if (wtd->handle_invisiref_parm_p && is_invisiref_parm (stmt))
     {
index 4480c67dc5f61814811bf9c79e5be9824340364a..76a839ce73046caf8b7f7a06f0e51541942fd34c 100644 (file)
@@ -1103,7 +1103,6 @@ maybe_add_lambda_conv_op (tree type)
       }
   }
 
-
   if (generic_lambda_p)
     {
       if (decltype_call)
index 85e4c71e8b5480d91c8bee28da61768ce48bf087..ba7426a38a44e9fbe8e293eb686951ece071926a 100644 (file)
@@ -1,3 +1,9 @@
+2017-11-20  Nathan Sidwell  <nathan@acm.org>
+
+       PR c++/82878
+       * g++.dg/cpp0x/pr82878.C: New.
+       * g++.dg/cpp1z/inh-ctor38.C: Check moves too.
+
 2017-11-20  Bin Cheng  <bin.cheng@arm.com>
 
        * gcc.dg/tree-ssa/predcom-dse-12.c: New test.
index 328410e29aa121e9d1f9fc53233a9016e895f328..d05c9760709a9fe23da38beb825d6e79384c0e9d 100644 (file)
@@ -20,7 +20,7 @@ main ()
            {
            case 3:             // { dg-error "case" }
              break;            // { dg-error "break" }
-           };
+           };          // { dg-warning "statement will never be executed" }
        }
     }
 }
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr82878.C b/gcc/testsuite/g++.dg/cpp0x/pr82878.C
new file mode 100644 (file)
index 0000000..c75e93b
--- /dev/null
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-O" }
+// pr 82878 erroneously unwrapped a reference parm in the lambda::_FUN
+// thunk.
+
+struct A {
+  ~A();
+  operator int ();
+};
+
+void baz ();
+
+void
+bar (A b)
+{
+  void (*lam) (A) = [](A) { baz (); };
+
+  if (auto c = b)
+    lam (c);
+}
index fbee8ca5c9edd896262ee61cdd6c43c9643b03db..356c36f5ff61d5041589dc0a999aa539c30b15a0 100644 (file)
@@ -1,17 +1,19 @@
 // { dg-do run { target c++11 } }
 // PR78495 failed to propagate pass-by-value struct to base ctor.
 
+static int moves = 0;
+
 struct Ptr {
   void *ptr = 0;
 
   Ptr() {}
   Ptr(Ptr const&) = delete;
-  Ptr(Ptr&& other) : ptr (other.ptr) {}
+  Ptr(Ptr&& other) : ptr (other.ptr) {moves++;}
 };
 
 struct Base {
   Ptr val;
-  Base(Ptr val_) : val(static_cast<Ptr&&>(val_)) {}
+  Base(Ptr val_);
 };
 
 struct Derived: Base {
@@ -27,5 +29,13 @@ void *Foo () {
 }
 
 int main () {
-  return Foo () != 0;
+  if (Foo ())
+    return 1;
+
+  if (moves != 2)
+    return 2;
+
+  return 0;
 }
+
+Base::Base(Ptr val_) : val(static_cast<Ptr&&>(val_)) {}