diff mbox

[C++] PR 71105 ("lambdas with default captures improperly have function pointer conversions")

Message ID 574A03C7.2020003@oracle.com
State New
Headers show

Commit Message

Paolo Carlini May 28, 2016, 8:47 p.m. UTC
Hi,

I think submitter is right that by the grammar even an alone 
capture-default counts as a lambda-capture, thus a conversion function 
to pointer to function should not be added. I don't see how this issue 
may count as a regression, but, assuming the analysis is correct, the 
fix should be safe enough for gcc-6-branch too.

Tested x86_64-linux.

Thanks,
Paolo.

/////////////////////////////////
/cp
2016-05-30  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/71105
	* lambda.c (maybe_add_lambda_conv_op): Early return also when
	LAMBDA_EXPR_DEFAULT_CAPTURE_MODE != CPLD_NONE.

/testsuite
2016-05-30  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/71105
	* g++.dg/cpp0x/lambda/lambda-conv11.C: New.
	* g++.dg/cpp1y/lambda-conv1.C: Likewise.

Comments

Jason Merrill May 29, 2016, 3:04 a.m. UTC | #1
OK for trunk and 6.

The regression is from another issue; this bug just prevents a simple 
workaround for that bug.

Jason
Paolo Carlini May 29, 2016, 7:59 a.m. UTC | #2
Hi,

On 29/05/2016 05:04, Jason Merrill wrote:
> OK for trunk and 6.
Thanks.
> The regression is from another issue; this bug just prevents a simple 
> workaround for that bug.
Ah now I see, I confused the test attached to the bug and the test 
provided inline at then end of Comment #0. I'm also adding a testcase 
reduced from the latter.

Thanks,
Paolo.
diff mbox

Patch

Index: cp/lambda.c
===================================================================
--- cp/lambda.c	(revision 236852)
+++ cp/lambda.c	(working copy)
@@ -872,8 +872,10 @@  maybe_add_lambda_conv_op (tree type)
   bool nested = (cfun != NULL);
   bool nested_def = decl_function_context (TYPE_MAIN_DECL (type));
   tree callop = lambda_function (type);
+  tree lam = CLASSTYPE_LAMBDA_EXPR (type);
 
-  if (LAMBDA_EXPR_CAPTURE_LIST (CLASSTYPE_LAMBDA_EXPR (type)) != NULL_TREE)
+  if (LAMBDA_EXPR_CAPTURE_LIST (lam) != NULL_TREE
+      || LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lam) != CPLD_NONE)
     return;
 
   if (processing_template_decl)
Index: testsuite/g++.dg/cpp0x/lambda/lambda-conv11.C
===================================================================
--- testsuite/g++.dg/cpp0x/lambda/lambda-conv11.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/lambda/lambda-conv11.C	(working copy)
@@ -0,0 +1,10 @@ 
+// PR c++/71105
+// { dg-do compile { target c++11 } }
+
+void foo()
+{
+  int i;
+  static_cast<void(*)()>([i]{});  // { dg-error "invalid static_cast" }
+  static_cast<void(*)()>([=]{});  // { dg-error "invalid static_cast" }
+  static_cast<void(*)()>([&]{});  // { dg-error "invalid static_cast" }
+}
Index: testsuite/g++.dg/cpp1y/lambda-conv1.C
===================================================================
--- testsuite/g++.dg/cpp1y/lambda-conv1.C	(revision 0)
+++ testsuite/g++.dg/cpp1y/lambda-conv1.C	(working copy)
@@ -0,0 +1,13 @@ 
+// PR c++/71105
+// { dg-do compile { target c++14 } }
+
+void foo()
+{
+  int i;
+  static_cast<void(*)(int)>([i](auto){});  // { dg-error "invalid static_cast" }
+  static_cast<void(*)(int)>([=](auto){});  // { dg-error "invalid static_cast" }
+  static_cast<void(*)(int)>([&](auto){});  // { dg-error "invalid static_cast" }
+  static_cast<float(*)(float)>([i](auto x){ return x; });  // { dg-error "invalid static_cast" }
+  static_cast<float(*)(float)>([=](auto x){ return x; });  // { dg-error "invalid static_cast" }
+  static_cast<float(*)(float)>([&](auto x){ return x; });  // { dg-error "invalid static_cast" }
+}