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