blastrock created this revision.
blastrock added reviewers: rjmccall, hliao.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This is an attempt to fix https://bugs.llvm.org/show_bug.cgi?id=44368

I don't know why the comment said that we should take the linkage of the 
outermost lambda's parent. That would be the foo() function in the test, which 
has external linkage. But we want the symbol to have internal linkage because 
it is nested in an instantiation of the generic lambda with a template 
parameter that is a closure from a static function.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D73701

Files:
  clang/lib/AST/Decl.cpp
  clang/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp


Index: clang/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp
===================================================================
--- clang/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp
+++ clang/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fblocks -emit-llvm -o - 
%s -fexceptions -std=c++11 | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fblocks -emit-llvm -o - 
%s -fexceptions -std=c++14 | FileCheck %s
 
 // CHECK-LABEL: define void @_ZN19non_inline_function3fooEv()
 // CHECK-LABEL: define internal void 
@"_ZZN19non_inline_function3fooEvENK3$_0clEi"(%class.anon
@@ -51,3 +51,16 @@
 }
 int use = foo();
 }
+
+// CHECK-LABEL: define internal void 
@"_ZZZN32lambda_capture_in_generic_lambda3fooIiEEDavENKUlT_E_clIZNS_L1fEvE3$_1EEDaS1_ENKUlvE_clEv"
+namespace lambda_capture_in_generic_lambda {
+template <typename T> auto foo() {
+  return [](auto func) {
+    [func] { func(); }();
+  };
+}
+static void f() {
+  foo<int>()([] { });
+}
+void f1() { f(); }
+}
Index: clang/lib/AST/Decl.cpp
===================================================================
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -1399,7 +1399,7 @@
         // This lambda has its linkage/visibility determined:
         //  - either by the outermost lambda if that lambda has no mangling
         //    number.
-        //  - or by the parent of the outer most lambda
+        //  - or by the parent of the current lambda
         // This prevents infinite recursion in settings such as nested lambdas
         // used in NSDMI's, for e.g.
         //  struct L {
@@ -1413,8 +1413,8 @@
           return getInternalLinkageFor(D);
 
         return getLVForClosure(
-                  OuterMostLambda->getDeclContext()->getRedeclContext(),
-                  OuterMostLambda->getLambdaContextDecl(), computation);
+                  Record->getDeclContext()->getRedeclContext(),
+                  Record->getLambdaContextDecl(), computation);
       }
 
       break;


Index: clang/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp
===================================================================
--- clang/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp
+++ clang/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fblocks -emit-llvm -o - %s -fexceptions -std=c++11 | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fblocks -emit-llvm -o - %s -fexceptions -std=c++14 | FileCheck %s
 
 // CHECK-LABEL: define void @_ZN19non_inline_function3fooEv()
 // CHECK-LABEL: define internal void @"_ZZN19non_inline_function3fooEvENK3$_0clEi"(%class.anon
@@ -51,3 +51,16 @@
 }
 int use = foo();
 }
+
+// CHECK-LABEL: define internal void @"_ZZZN32lambda_capture_in_generic_lambda3fooIiEEDavENKUlT_E_clIZNS_L1fEvE3$_1EEDaS1_ENKUlvE_clEv"
+namespace lambda_capture_in_generic_lambda {
+template <typename T> auto foo() {
+  return [](auto func) {
+    [func] { func(); }();
+  };
+}
+static void f() {
+  foo<int>()([] { });
+}
+void f1() { f(); }
+}
Index: clang/lib/AST/Decl.cpp
===================================================================
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -1399,7 +1399,7 @@
         // This lambda has its linkage/visibility determined:
         //  - either by the outermost lambda if that lambda has no mangling
         //    number.
-        //  - or by the parent of the outer most lambda
+        //  - or by the parent of the current lambda
         // This prevents infinite recursion in settings such as nested lambdas
         // used in NSDMI's, for e.g.
         //  struct L {
@@ -1413,8 +1413,8 @@
           return getInternalLinkageFor(D);
 
         return getLVForClosure(
-                  OuterMostLambda->getDeclContext()->getRedeclContext(),
-                  OuterMostLambda->getLambdaContextDecl(), computation);
+                  Record->getDeclContext()->getRedeclContext(),
+                  Record->getLambdaContextDecl(), computation);
       }
 
       break;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to