From 2f4cac2cc3a35c51ebb5a48c8b34c55aa11f1fc0 Mon Sep 17 00:00:00 2001 From: Alexey Bataev <a.bataev@hotmail.com> Date: Tue, 15 Nov 2016 14:30:48 +0000 Subject: [PATCH] Merging r284229: ------------------------------------------------------------------------ r284229 | abataev | 2016-10-14 12:43:59 +0000 (Fri, 14 Oct 2016) | 37 lines 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. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_39@286970 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaLambda.cpp | 5 ++++- test/CodeGenCXX/captured-statements.cpp | 1 + test/OpenMP/for_lastprivate_codegen.cpp | 9 ++++++--- test/OpenMP/target_map_codegen.cpp | 4 +++- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index 070c2fa2c71..0b3af262cd6 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -314,18 +314,21 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC, 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 if ((IsInNonspecializedTemplate && !(ManglingContextDecl && isa<ParmVarDecl>(ManglingContextDecl))) || isInInlineFunction(CurContext)) { ManglingContextDecl = nullptr; + while (auto *CD = dyn_cast<CapturedDecl>(DC)) + DC = CD->getParent(); return &Context.getManglingNumberContext(DC); } ManglingContextDecl = nullptr; return nullptr; + } case StaticDataMember: // -- the initializers of nonspecialized static members of template classes diff --git a/test/CodeGenCXX/captured-statements.cpp b/test/CodeGenCXX/captured-statements.cpp index fdda24fcf30..4b95503ad7b 100644 --- a/test/CodeGenCXX/captured-statements.cpp +++ b/test/CodeGenCXX/captured-statements.cpp @@ -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* } diff --git a/test/OpenMP/for_lastprivate_codegen.cpp b/test/OpenMP/for_lastprivate_codegen.cpp index 2b1d6c3cf97..75f59f7d406 100644 --- a/test/OpenMP/for_lastprivate_codegen.cpp +++ b/test/OpenMP/for_lastprivate_codegen.cpp @@ -41,7 +41,7 @@ struct SS { for (a = 0; a < 2; ++a) #ifdef LAMBDA [&]() { - ++this->a, --b, (this)->c /= 1; + --this->a, ++b, (this)->c *= 2; #pragma omp parallel #pragma omp for lastprivate(b) for (b = 0; b < 2; ++b) @@ -190,7 +190,7 @@ int main() { // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void // LAMBDA: call void @__kmpc_for_static_init_4( // LAMBDA-NOT: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 - // LAMBDA: call void {{.+}} [[SS_LAMBDA:@[^ ]+]] + // LAMBDA: call{{.*}} void [[SS_LAMBDA1:@[^ ]+]] // LAMBDA: call void @__kmpc_for_static_fini(% // LAMBDA: ret @@ -200,7 +200,7 @@ int main() { // LAMBDA: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 2 // LAMBDA: call void @__kmpc_for_static_init_4( // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* - // LAMBDA: call{{.*}} void + // LAMBDA: call{{.*}} void [[SS_LAMBDA:@[^ ]+]] // LAMBDA: call void @__kmpc_for_static_fini( // LAMBDA: br i1 // LAMBDA: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1 @@ -236,6 +236,9 @@ int main() { // LAMBDA: br label // LAMBDA: ret void + // LAMBDA: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}) + // LAMBDA: ret void + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) [[SIVAR:%.+]]) // LAMBDA: alloca i{{[0-9]+}}, // LAMBDA: alloca i{{[0-9]+}}, diff --git a/test/OpenMP/target_map_codegen.cpp b/test/OpenMP/target_map_codegen.cpp index 1a41c130c22..678e774566c 100644 --- a/test/OpenMP/target_map_codegen.cpp +++ b/test/OpenMP/target_map_codegen.cpp @@ -4074,7 +4074,9 @@ int explicit_maps_with_inner_lambda(int a){ // 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 -- GitLab