diff options
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/GlobalDecl.h | 6 | ||||
-rw-r--r-- | test/CodeGenCXX/friend-redecl.cpp | 18 |
3 files changed, 26 insertions, 2 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 89aeeb6fc7..56bc31a858 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -857,10 +857,10 @@ CodeGenModule::GetOrCreateLLVMFunction(llvm::StringRef MangledName, if (isa<CXXRecordDecl>(FD->getLexicalDeclContext())) { if (FD->isImplicit() && !ForVTable) { assert(FD->isUsed() && "Sema didn't mark implicit function as used!"); - DeferredDeclsToEmit.push_back(D); + DeferredDeclsToEmit.push_back(D.getWithDecl(FD)); break; } else if (FD->isThisDeclarationADefinition()) { - DeferredDeclsToEmit.push_back(D); + DeferredDeclsToEmit.push_back(D.getWithDecl(FD)); break; } } diff --git a/lib/CodeGen/GlobalDecl.h b/lib/CodeGen/GlobalDecl.h index ab3e2019a6..c2f36d210b 100644 --- a/lib/CodeGen/GlobalDecl.h +++ b/lib/CodeGen/GlobalDecl.h @@ -81,6 +81,12 @@ public: GD.Value.setFromOpaqueValue(P); return GD; } + + GlobalDecl getWithDecl(const Decl *D) { + GlobalDecl Result(*this); + Result.Value.setPointer(D); + return Result; + } }; } // end namespace CodeGen diff --git a/test/CodeGenCXX/friend-redecl.cpp b/test/CodeGenCXX/friend-redecl.cpp new file mode 100644 index 0000000000..18292cd171 --- /dev/null +++ b/test/CodeGenCXX/friend-redecl.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s +// PR8864 + +struct Foo { + friend bool TryFoo(Foo *f2) { return TryFoo(0, f2); } + +// CHECK: define{{.*}}Z6TryFooP3Foo +// CHECK-NOT: ret +// CHECK: call{{.*}}Z6TryFooiP3Foo +// CHECK: ret + + friend bool TryFoo(int, Foo *f3); +}; +bool TryFoo(Foo *f5); +int main(void) { + Foo f; + TryFoo(&f); +} |