Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -1370,6 +1370,31 @@ /*DontDefer=*/false); return; } + + // Compute the function info and LLVM type. + const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD); + llvm::FunctionType *Ty = getTypes().GetFunctionType(FI); + llvm::GlobalValue *GV = nullptr; + + // Get or create the prototype for the function. + llvm::Constant *C = + GetAddrOfFunction(GD, Ty, /*ForVTable=*/false, /*DontDefer*/true); + + // Strip off a bitcast if we got one back. + if (auto *CE = dyn_cast(C)) { + assert(CE->getOpcode() == llvm::Instruction::BitCast); + GV = cast(CE->getOperand(0)); + } else { + GV = cast(C); + } + + if (!GV->isDeclaration()) { + getDiags().Report(FD->getLocation(), diag::err_duplicate_mangled_name); + GlobalDecl OldGD = Manglings.lookup(GV->getName()); + if (auto *Prev = OldGD.getDecl()) + getDiags().Report(Prev->getLocation(), diag::note_previous_definition); + return; + } } else { const auto *VD = cast(Global); assert(VD->isFileVarDecl() && "Cannot emit local var decl as global."); @@ -2412,14 +2437,6 @@ } } - if (!GV->isDeclaration()) { - getDiags().Report(D->getLocation(), diag::err_duplicate_mangled_name); - GlobalDecl OldGD = Manglings.lookup(GV->getName()); - if (auto *Prev = OldGD.getDecl()) - getDiags().Report(Prev->getLocation(), diag::note_previous_definition); - return; - } - if (GV->getType()->getElementType() != Ty) { // If the types mismatch then we have to rewrite the definition. assert(GV->isDeclaration() && "Shouldn't replace non-declaration"); Index: test/CodeGenCXX/duplicate-mangled-name2.cpp =================================================================== --- test/CodeGenCXX/duplicate-mangled-name2.cpp +++ test/CodeGenCXX/duplicate-mangled-name2.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -verify +// RUN: %clang_cc1 -triple %itanium_abi_triple -femit-all-decls -emit-llvm-only %s -verify + +void foo(void) __asm("_ZN1SC2Ev"); +void foo(void) { } // expected-note {{previous}} + +struct S { + S() {} // expected-error {{definition with same mangled name as another definition}} +} s; \ No newline at end of file