[IRGen] Detect duplicate definitions at the IR level

This commit is contained in:
Doug Gregor
2025-10-31 10:32:54 -07:00
parent 523b3b7ab7
commit 5d576470fd
5 changed files with 22 additions and 9 deletions

View File

@@ -117,5 +117,9 @@ NOTE(maybe_missing_parameter, none,
"%select{constraint|parameter}0",
(bool, const clang::NamedDecl *))
ERROR(ir_function_redefinition_external,none,
"multiple definitions of symbol '%0'",
(StringRef))
#define UNDEFINE_DIAGNOSTIC_MACROS
#include "DefineDiagnosticMacros.h"

View File

@@ -451,7 +451,7 @@ public:
llvm::DenseMap<SILInstruction *, llvm::SmallVector<StackPackAlloc, 2>>
StackPackAllocs;
IRGenSILFunction(IRGenModule &IGM, SILFunction *f);
IRGenSILFunction(IRGenModule &IGM, SILFunction *f, llvm::Function *llvmF);
~IRGenSILFunction();
/// Generate IR for the SIL Function.
@@ -1887,10 +1887,9 @@ llvm::Value *LoweredValue::getSingletonExplosion(IRGenFunction &IGF,
llvm_unreachable("bad kind");
}
IRGenSILFunction::IRGenSILFunction(IRGenModule &IGM, SILFunction *f)
: IRGenFunction(IGM,
IGM.getAddrOfSILFunction(f, ForDefinition,
f->isDynamicallyReplaceable()),
IRGenSILFunction::IRGenSILFunction(IRGenModule &IGM, SILFunction *f,
llvm::Function *llvmF)
: IRGenFunction(IGM, llvmF,
f->isPerformanceConstraint(),
f->getOptimizationMode(), f->getDebugScope(),
f->getLocation()),
@@ -2558,7 +2557,17 @@ void IRGenModule::emitSILFunction(SILFunction *f) {
noteUseOfMetadataByCXXInterop(IRGen, f, TypeExpansionContext(*f));
PrettyStackTraceSILFunction stackTrace("emitting IR", f);
IRGenSILFunction(*this, f).emitSILFunction();
// Get the LLVM function we will emit. If it has already been defined, error.
auto llvmF = getAddrOfSILFunction(f, ForDefinition,
f->isDynamicallyReplaceable());
if (!llvmF->empty()) {
auto &diags = Context.Diags;
diags.diagnose(f->getLocation().getSourceLoc(), diag::ir_function_redefinition_external, llvmF->getName());
return;
}
IRGenSILFunction(*this, f, llvmF).emitSILFunction();
}
void IRGenSILFunction::emitSILFunction() {

View File

@@ -443,7 +443,7 @@ bool SILFunction::hasForeignBody() const {
}
void SILFunction::setAsmName(StringRef value) {
assert((AsmName.empty() || value == AsmName) && "Cannot change asmname");
ASSERT((AsmName.empty() || value == AsmName) && "Cannot change asmname");
AsmName = value;
if (!value.empty()) {

View File

@@ -85,7 +85,7 @@ SILGlobalVariable::~SILGlobalVariable() {
}
void SILGlobalVariable::setAsmName(StringRef value) {
assert((AsmName.empty() || value == AsmName) && "Cannot change asmname");
ASSERT((AsmName.empty() || value == AsmName) && "Cannot change asmname");
AsmName = value;
if (!value.empty()) {

View File

@@ -4148,7 +4148,7 @@ SILGlobalVariable *SILDeserializer::lookupSILGlobalVariable(StringRef name,
SILGlobalVariable *SILDeserializer::readGlobalVar(StringRef Name,
bool byAsmName) {
// If we're looking up the function by its AsmName, check that table.
// If we're looking up the variable by its AsmName, check that table.
if (byAsmName) {
if (!AsmNameTable)
return nullptr;