forked from OSchip/llvm-project
[clang] Fix linkage of nested lambdas.
patch from Philippe Daouadi <blastrock@free.fr> This is an attempt to fix [PR#44368](https://bugs.llvm.org/show_bug.cgi?id=44368) This effectively reverts [D1783](https://reviews.llvm.org/D1783). It doesn't break the current tests and fixes the test that this commit adds. We now decide of a lambda linkage only depending on the visibility of its parent context. Differential Revision: https://reviews.llvm.org/D73701
This commit is contained in:
parent
cbe0c8299e
commit
2926917f43
|
@ -1318,19 +1318,6 @@ LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D,
|
|||
LV.isVisibilityExplicit());
|
||||
}
|
||||
|
||||
static inline const CXXRecordDecl*
|
||||
getOutermostEnclosingLambda(const CXXRecordDecl *Record) {
|
||||
const CXXRecordDecl *Ret = Record;
|
||||
while (Record && Record->isLambda()) {
|
||||
Ret = Record;
|
||||
if (!Record->getParent()) break;
|
||||
// Get the Containing Class of this Lambda Class
|
||||
Record = dyn_cast_or_null<CXXRecordDecl>(
|
||||
Record->getParent()->getParent());
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
LinkageInfo LinkageComputer::computeLVForDecl(const NamedDecl *D,
|
||||
LVComputationKind computation,
|
||||
bool IgnoreVarTypeLinkage) {
|
||||
|
@ -1396,25 +1383,9 @@ LinkageInfo LinkageComputer::computeLVForDecl(const NamedDecl *D,
|
|||
return getInternalLinkageFor(D);
|
||||
}
|
||||
|
||||
// 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
|
||||
// This prevents infinite recursion in settings such as nested lambdas
|
||||
// used in NSDMI's, for e.g.
|
||||
// struct L {
|
||||
// int t{};
|
||||
// int t2 = ([](int a) { return [](int b) { return b; };})(t)(t);
|
||||
// };
|
||||
const CXXRecordDecl *OuterMostLambda =
|
||||
getOutermostEnclosingLambda(Record);
|
||||
if (OuterMostLambda->hasKnownLambdaInternalLinkage() ||
|
||||
!OuterMostLambda->getLambdaManglingNumber())
|
||||
return getInternalLinkageFor(D);
|
||||
|
||||
return getLVForClosure(
|
||||
OuterMostLambda->getDeclContext()->getRedeclContext(),
|
||||
OuterMostLambda->getLambdaContextDecl(), computation);
|
||||
Record->getDeclContext()->getRedeclContext(),
|
||||
Record->getLambdaContextDecl(), computation);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// 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 --check-prefixes=CHECK,CXX14 %s
|
||||
|
||||
// CHECK-LABEL: define void @_ZN19non_inline_function3fooEv()
|
||||
// CHECK-LABEL: define internal void @"_ZZN19non_inline_function3fooEvENK3$_0clEi"(%class.anon
|
||||
|
@ -51,3 +52,18 @@ inline int foo() {
|
|||
}
|
||||
int use = foo();
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201402L
|
||||
// CXX14-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(); }
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue