summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2016-11-15 14:30:48 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2016-11-15 14:30:48 +0000
commit2f4cac2cc3a35c51ebb5a48c8b34c55aa11f1fc0 (patch)
tree2d138cc4bef0cfd73b28c1247c460710f435451e
parenta3283d64fef21d0ba999679b21ecfaecde3a5376 (diff)
downloadclang-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.cpp5
-rw-r--r--test/CodeGenCXX/captured-statements.cpp1
-rw-r--r--test/OpenMP/for_lastprivate_codegen.cpp9
-rw-r--r--test/OpenMP/target_map_codegen.cpp4
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