Update for llvm api change.
Now that llvm cannot represent alias cycles, we have to diagnose erros just before trying to close the cycle. This degrades the errors a bit. The real solution is what it was before: if we want to provide good errors for these cases, we have to be able to find a clang level decl given a mangled name and produce the error from Sema. llvm-svn: 209008
This commit is contained in:
@@ -238,46 +238,18 @@ void CodeGenModule::checkAliases() {
|
||||
llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
|
||||
auto *Alias = cast<llvm::GlobalAlias>(Entry);
|
||||
llvm::GlobalValue *GV = Alias->getAliasedGlobal();
|
||||
if (!GV) {
|
||||
Error = true;
|
||||
Diags.Report(AA->getLocation(), diag::err_cyclic_alias);
|
||||
} else if (GV->isDeclaration()) {
|
||||
if (GV->isDeclaration()) {
|
||||
Error = true;
|
||||
Diags.Report(AA->getLocation(), diag::err_alias_to_undefined);
|
||||
}
|
||||
|
||||
llvm::Constant *Aliasee = Alias->getAliasee();
|
||||
llvm::GlobalValue *AliaseeGV;
|
||||
if (auto CE = dyn_cast<llvm::ConstantExpr>(Aliasee)) {
|
||||
assert((CE->getOpcode() == llvm::Instruction::BitCast ||
|
||||
CE->getOpcode() == llvm::Instruction::AddrSpaceCast) &&
|
||||
"Unsupported aliasee");
|
||||
AliaseeGV = cast<llvm::GlobalValue>(CE->getOperand(0));
|
||||
} else {
|
||||
AliaseeGV = cast<llvm::GlobalValue>(Aliasee);
|
||||
}
|
||||
|
||||
llvm::GlobalObject *Aliasee = Alias->getAliasee();
|
||||
if (const SectionAttr *SA = D->getAttr<SectionAttr>()) {
|
||||
StringRef AliasSection = SA->getName();
|
||||
if (AliasSection != AliaseeGV->getSection())
|
||||
if (AliasSection != Aliasee->getSection())
|
||||
Diags.Report(SA->getLocation(), diag::warn_alias_with_section)
|
||||
<< AliasSection;
|
||||
}
|
||||
|
||||
// We have to handle alias to weak aliases in here. LLVM itself disallows
|
||||
// this since the object semantics would not match the IL one. For
|
||||
// compatibility with gcc we implement it by just pointing the alias
|
||||
// to its aliasee's aliasee. We also warn, since the user is probably
|
||||
// expecting the link to be weak.
|
||||
if (auto GA = dyn_cast<llvm::GlobalAlias>(AliaseeGV)) {
|
||||
if (GA->mayBeOverridden()) {
|
||||
Diags.Report(AA->getLocation(), diag::warn_alias_to_weak_alias)
|
||||
<< GA->getAliasedGlobal()->getName() << GA->getName();
|
||||
Aliasee = llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(
|
||||
GA->getAliasee(), Alias->getType());
|
||||
Alias->setAliasee(Aliasee);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!Error)
|
||||
return;
|
||||
@@ -2246,6 +2218,29 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD,
|
||||
AddGlobalAnnotations(D, Fn);
|
||||
}
|
||||
|
||||
static llvm::GlobalObject &getGlobalObjectInExpr(DiagnosticsEngine &Diags,
|
||||
const AliasAttr *AA,
|
||||
llvm::Constant *C) {
|
||||
if (auto *GO = dyn_cast<llvm::GlobalObject>(C))
|
||||
return *GO;
|
||||
|
||||
auto *GA = dyn_cast<llvm::GlobalAlias>(C);
|
||||
if (GA) {
|
||||
if (GA->mayBeOverridden()) {
|
||||
Diags.Report(AA->getLocation(), diag::warn_alias_to_weak_alias)
|
||||
<< GA->getAliasee()->getName() << GA->getName();
|
||||
}
|
||||
|
||||
return *GA->getAliasee();
|
||||
}
|
||||
|
||||
auto *CE = cast<llvm::ConstantExpr>(C);
|
||||
assert(CE->getOpcode() == llvm::Instruction::BitCast ||
|
||||
CE->getOpcode() == llvm::Instruction::GetElementPtr ||
|
||||
CE->getOpcode() == llvm::Instruction::AddrSpaceCast);
|
||||
return *cast<llvm::GlobalObject>(CE->getOperand(0));
|
||||
}
|
||||
|
||||
void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
|
||||
const auto *D = cast<ValueDecl>(GD.getDecl());
|
||||
const AliasAttr *AA = D->getAttr<AliasAttr>();
|
||||
@@ -2276,9 +2271,15 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
|
||||
// Create the new alias itself, but don't set a name yet.
|
||||
auto *GA = new llvm::GlobalAlias(
|
||||
cast<llvm::PointerType>(Aliasee->getType())->getElementType(),
|
||||
llvm::Function::ExternalLinkage, "", Aliasee, &getModule());
|
||||
llvm::Function::ExternalLinkage, "",
|
||||
&getGlobalObjectInExpr(Diags, AA, Aliasee), &getModule());
|
||||
|
||||
if (Entry) {
|
||||
if (GA->getAliasee() == Entry) {
|
||||
Diags.Report(AA->getLocation(), diag::err_cyclic_alias);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(Entry->isDeclaration());
|
||||
|
||||
// If there is a declaration in the module, then we had an extern followed
|
||||
@@ -3196,9 +3197,9 @@ void CodeGenModule::EmitStaticExternCAliases() {
|
||||
IdentifierInfo *Name = I->first;
|
||||
llvm::GlobalValue *Val = I->second;
|
||||
if (Val && !getModule().getNamedValue(Name->getName()))
|
||||
addUsedGlobal(new llvm::GlobalAlias(Val->getType()->getElementType(),
|
||||
Val->getLinkage(), Name->getName(),
|
||||
Val, &getModule()));
|
||||
addUsedGlobal(new llvm::GlobalAlias(
|
||||
Val->getType()->getElementType(), Val->getLinkage(), Name->getName(),
|
||||
cast<llvm::GlobalObject>(Val), &getModule()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user