]> granicus.if.org Git - clang/commitdiff
Fix for PR30632: Name mangling issue.
authorAlexey Bataev <a.bataev@hotmail.com>
Fri, 14 Oct 2016 12:43:59 +0000 (12:43 +0000)
committerAlexey Bataev <a.bataev@hotmail.com>
Fri, 14 Oct 2016 12:43:59 +0000 (12:43 +0000)
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/trunk@284229 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaLambda.cpp
test/CodeGenCXX/captured-statements.cpp
test/OpenMP/target_map_codegen.cpp

index 0de501fc5e45a71d512acad0cabd0f8efb50324b..9be8fe51887cbdc511fa69e0514f57fa437fab57 100644 (file)
@@ -311,18 +311,20 @@ 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
+    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
index fdda24fcf30163d9342195055093a7e77aee4e1b..4b95503ad7b3941999af6071d99f6073197753b8 100644 (file)
@@ -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* }
 
index 92ed0abf9495bac7b3bd5fee8d40cda0bff35019..72c7257a0ea7212990dc24c6023979a884f01623 100644 (file)
@@ -4104,7 +4104,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