Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -3181,6 +3181,10 @@ } llvm::Value *Callee = EmitScalarExpr(E->getCallee()); + + if (isa(Callee)) + return RValue::get(Callee); + return EmitCall(E->getCallee()->getType(), Callee, E, ReturnValue, TargetDecl); } Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -1666,6 +1666,21 @@ Ty = getTypes().ConvertType(cast(GD.getDecl())->getType()); StringRef MangledName = getMangledName(GD); + + // Check that there are no declarations with the same mangled name. This check + // is valid only if one of declarations is a C++ method. + GlobalDecl OldGD; + if (lookupRepresentativeDecl(MangledName, OldGD) && + (isa(GD.getDecl()) || + isa(OldGD.getDecl())) && + GD.getCanonicalDecl().getDecl() != OldGD.getCanonicalDecl().getDecl()) { + getDiags().Report(GD.getDecl()->getLocation(), + diag::err_duplicate_mangled_name); + getDiags().Report(OldGD.getDecl()->getLocation(), + diag::note_previous_definition); + return llvm::UndefValue::get(VoidPtrTy); + } + return GetOrCreateLLVMFunction(MangledName, Ty, GD, ForVTable, DontDefer); } @@ -2401,6 +2416,9 @@ llvm::Constant *C = GetAddrOfFunction(GD, Ty, /*ForVTable=*/false, /*DontDefer*/ true); + if (isa(C)) + return; + // Strip off a bitcast if we got one back. if (auto *CE = dyn_cast(C)) { assert(CE->getOpcode() == llvm::Instruction::BitCast); Index: test/CodeGenCXX/duplicate-mangled-name.cpp =================================================================== --- test/CodeGenCXX/duplicate-mangled-name.cpp +++ test/CodeGenCXX/duplicate-mangled-name.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -verify +// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only -DTEST1 %s -verify +// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only -DTEST2 %s -verify // rdar://15522601 +#ifdef TEST1 class MyClass { static void meth(); }; @@ -8,3 +10,22 @@ extern "C" { void _ZN7MyClass4methEv() { } // expected-error {{definition with same mangled name as another definition}} } + +#elif TEST2 + +extern "C" void _ZN1TD1Ev(); // expected-error {{definition with same mangled name as another definition}} +struct T { + ~T() {} // expected-note {{previous}} +}; + +int main() { + _ZN1TD1Ev(); + T t; +} + +#else + +#error Unknown test mode + +#endif +