Author: abataev Date: Fri Oct 14 07:43:59 2016 New Revision: 284229 URL: http://llvm.org/viewvc/llvm-project?rev=284229&view=rev Log: Fix for PR30632: Name mangling issue.
There was a bug in the implementation of captured statements. If it has a lambda expression in it and the same lambda expression is used outside the captured region, clang produced an error: ``` error: definition with same mangled name as another definition ``` Here is an example: ``` struct A { template <typename L> void g(const L&) { } }; template<typename T> void f() { { A().g([](){}); } A().g([](){}); } int main() { f<void>(); } ``` Error report: ``` main.cpp:3:10: error: definition with same mangled name as another definition void g(const L&) { } ^ main.cpp:3:10: note: previous definition is here ``` Patch fixes this bug. Modified: cfe/trunk/lib/Sema/SemaLambda.cpp cfe/trunk/test/CodeGenCXX/captured-statements.cpp cfe/trunk/test/OpenMP/target_map_codegen.cpp Modified: cfe/trunk/lib/Sema/SemaLambda.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=284229&r1=284228&r2=284229&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaLambda.cpp (original) +++ cfe/trunk/lib/Sema/SemaLambda.cpp Fri Oct 14 07:43:59 2016 @@ -311,18 +311,20 @@ Sema::getCurrentMangleNumberContext(cons bool IsInNonspecializedTemplate = !ActiveTemplateInstantiations.empty() || CurContext->isDependentContext(); switch (Kind) { - case Normal: + case Normal: { // -- the bodies of non-exported nonspecialized template functions // -- the bodies of inline functions + auto *CD = dyn_cast<CapturedDecl>(CurContext); if ((IsInNonspecializedTemplate && !(ManglingContextDecl && isa<ParmVarDecl>(ManglingContextDecl))) || - isInInlineFunction(CurContext)) { + isInInlineFunction(CurContext) || CD) { ManglingContextDecl = nullptr; - return &Context.getManglingNumberContext(DC); + return &Context.getManglingNumberContext(CD ? CD->getParent() : DC); } ManglingContextDecl = nullptr; return nullptr; + } case StaticDataMember: // -- the initializers of nonspecialized static members of template classes Modified: cfe/trunk/test/CodeGenCXX/captured-statements.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/captured-statements.cpp?rev=284229&r1=284228&r2=284229&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/captured-statements.cpp (original) +++ cfe/trunk/test/CodeGenCXX/captured-statements.cpp Fri Oct 14 07:43:59 2016 @@ -78,6 +78,7 @@ void test3(int x) { { x = [=]() { return x + 1; } (); } + x = [=]() { return x + 1; }(); // CHECK-3: %[[Capture:struct\.anon[\.0-9]*]] = type { i32* } Modified: cfe/trunk/test/OpenMP/target_map_codegen.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/target_map_codegen.cpp?rev=284229&r1=284228&r2=284229&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/target_map_codegen.cpp (original) +++ cfe/trunk/test/OpenMP/target_map_codegen.cpp Fri Oct 14 07:43:59 2016 @@ -4104,7 +4104,9 @@ int explicit_maps_with_inner_lambda(int // CK25: [[VAL1:%.+]] = load i32*, i32** [[VALADDR]], // CK25: [[VALADDR1:%.+]] = getelementptr inbounds [[CA01]], [[CA01]]* [[CA:%[^,]+]], i32 0, i32 0 // CK25: store i32* [[VAL1]], i32** [[VALADDR1]], -// CK25: call void {{.*}}[[LAMBDA]]{{.*}}([[CA01]]* [[CA]]) +// CK25: call void {{.*}}[[LAMBDA2:@.+]]{{.*}}([[CA01]]* [[CA]]) + +// CK25: define {{.+}}[[LAMBDA2]] #endif ///==========================================================================/// // RUN: %clang_cc1 -DCK26 -std=c++11 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK26 --check-prefix CK26-64 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits