diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2016-11-15 14:30:48 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2016-11-15 14:30:48 +0000 |
commit | 2f4cac2cc3a35c51ebb5a48c8b34c55aa11f1fc0 (patch) | |
tree | 2d138cc4bef0cfd73b28c1247c460710f435451e | |
parent | a3283d64fef21d0ba999679b21ecfaecde3a5376 (diff) | |
download | clang-2f4cac2cc3a35c51ebb5a48c8b34c55aa11f1fc0.tar.gz |
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
-rw-r--r-- | lib/Sema/SemaLambda.cpp | 5 | ||||
-rw-r--r-- | test/CodeGenCXX/captured-statements.cpp | 1 | ||||
-rw-r--r-- | test/OpenMP/for_lastprivate_codegen.cpp | 9 | ||||
-rw-r--r-- | 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 070c2fa2c7..0b3af262cd 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 fdda24fcf3..4b95503ad7 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 2b1d6c3cf9..75f59f7d40 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 1a41c130c2..678e774566 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 |