aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2017-11-20 14:39:00 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2017-11-20 14:39:00 +0000
commit6aa80414a003b2cd9af254e4701838072a1f17dd (patch)
treeba5912c09897e80e79f8a222c41d3dfae9c08ccd
parent7b7b60c83047db2e4bde9e7f40ce3f1738694789 (diff)
downloadgcc-6aa80414a003b2cd9af254e4701838072a1f17dd.zip
gcc-6aa80414a003b2cd9af254e4701838072a1f17dd.tar.gz
gcc-6aa80414a003b2cd9af254e4701838072a1f17dd.tar.bz2
[PR c++/82878] pass-by-invisiref in lambda
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
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/call.c10
-rw-r--r--gcc/cp/cp-gimplify.c8
-rw-r--r--gcc/cp/lambda.c1
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-switch.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr82878.C20
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/inh-ctor38.C16
8 files changed, 58 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6f4d30e..e1e9d72 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index e09cf97..d242b07 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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);
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 8849f9d..201a595 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -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))
{
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 4480c67..76a839c 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -1103,7 +1103,6 @@ maybe_add_lambda_conv_op (tree type)
}
}
-
if (generic_lambda_p)
{
if (decltype_call)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 85e4c71..ba7426a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-switch.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-switch.C
index 328410e..d05c976 100644
--- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-switch.C
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-switch.C
@@ -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
index 0000000..c75e93b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr82878.C
@@ -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);
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/inh-ctor38.C b/gcc/testsuite/g++.dg/cpp1z/inh-ctor38.C
index fbee8ca..356c36f 100644
--- a/gcc/testsuite/g++.dg/cpp1z/inh-ctor38.C
+++ b/gcc/testsuite/g++.dg/cpp1z/inh-ctor38.C
@@ -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_)) {}