aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/CodeGenModule.cpp4
-rw-r--r--lib/CodeGen/GlobalDecl.h6
-rw-r--r--test/CodeGenCXX/friend-redecl.cpp18
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);
+}