From: Douglas Gregor Date: Wed, 9 Feb 2011 02:03:05 +0000 (+0000) Subject: When IRgen refers to a function declaration that is not a definition, X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a29bf41b8f49578207ce36f6b21ff9bb7ee77bab;p=clang 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 --- 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); +}