]> granicus.if.org Git - clang/commitdiff
When IRgen refers to a function declaration that is not a definition,
authorDouglas Gregor <dgregor@apple.com>
Wed, 9 Feb 2011 02:03:05 +0000 (02:03 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 9 Feb 2011 02:03:05 +0000 (02:03 +0000)
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
lib/CodeGen/GlobalDecl.h
test/CodeGenCXX/friend-redecl.cpp [new file with mode: 0644]

index 89aeeb6fc79ffeffb37571bab0235254b8224a6e..56bc31a8587bf81de4a4c10dfad42003a4f3c04f 100644 (file)
@@ -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;
         }
       }
index ab3e2019a6a05a8e688b185b0b232bbd3a5281c5..c2f36d210bfcb68513882651185c3d45953bf437 100644 (file)
@@ -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 (file)
index 0000000..18292cd
--- /dev/null
@@ -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);
+}