From a29bf41b8f49578207ce36f6b21ff9bb7ee77bab Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 9 Feb 2011 02:03:05 +0000 Subject: [PATCH] When IRgen refers to a function declaration that is not a definition, and we later find the definition, make sure that we add the definition (not the declaration) to the list of deferred definitions to emit. Fixes PR8864. Thanks to Nick Lewycky for testing this patch out git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125157 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CodeGenModule.cpp | 4 ++-- lib/CodeGen/GlobalDecl.h | 6 ++++++ test/CodeGenCXX/friend-redecl.cpp | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 test/CodeGenCXX/friend-redecl.cpp 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(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); +} -- 2.50.1