This patch causes clang to reject alias attributes that point to undefined
names. For example, with this patch we now reject
void f1(void) __attribute__((alias("g1")));
This patch is implemented in CodeGen. It is quiet a bit simpler and more
compatible with gcc than implementing it in Sema. The downside is that the
errors only fire during -emit-llvm.
llvm-svn: 193161
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "clang/Basic/Version.h"
|
||||
#include "clang/Frontend/CodeGenOptions.h"
|
||||
#include "clang/Sema/SemaDiagnostic.h"
|
||||
#include "llvm/ADT/APSInt.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/IR/CallingConv.h"
|
||||
@@ -933,6 +934,12 @@ void CodeGenModule::EmitDeferred() {
|
||||
GlobalDecl D = DeferredDeclsToEmit.back();
|
||||
DeferredDeclsToEmit.pop_back();
|
||||
|
||||
const ValueDecl *Global = cast<ValueDecl>(D.getDecl());
|
||||
if (Global->hasAttr<AliasAttr>()) {
|
||||
EmitAliasDefinition(D);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check to see if we've already emitted this. This is necessary
|
||||
// for a couple of reasons: first, decls can end up in the
|
||||
// deferred-decls queue multiple times, and second, decls can end
|
||||
@@ -1098,7 +1105,7 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
|
||||
// If this is an alias definition (which otherwise looks like a declaration)
|
||||
// emit it now.
|
||||
if (Global->hasAttr<AliasAttr>())
|
||||
return EmitAliasDefinition(GD);
|
||||
return scheduleAliasDefinitionEmission(GD);
|
||||
|
||||
// If this is CUDA, be selective about which declarations we emit.
|
||||
if (LangOpts.CUDA) {
|
||||
@@ -2075,6 +2082,24 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {
|
||||
AddGlobalAnnotations(D, Fn);
|
||||
}
|
||||
|
||||
void CodeGenModule::scheduleAliasDefinitionEmission(GlobalDecl GD) {
|
||||
const ValueDecl *D = cast<ValueDecl>(GD.getDecl());
|
||||
const AliasAttr *AA = D->getAttr<AliasAttr>();
|
||||
assert(AA && "Not an alias?");
|
||||
|
||||
// Schedule it.
|
||||
DeferredDeclsToEmit.push_back(GD);
|
||||
|
||||
llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType());
|
||||
|
||||
// Cause the aliasee emission to be scheduled.
|
||||
if (isa<llvm::FunctionType>(DeclTy))
|
||||
GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy, GD, /*ForVTable=*/false);
|
||||
else
|
||||
GetOrCreateLLVMGlobal(AA->getAliasee(),
|
||||
llvm::PointerType::getUnqual(DeclTy), 0);
|
||||
}
|
||||
|
||||
void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
|
||||
const ValueDecl *D = cast<ValueDecl>(GD.getDecl());
|
||||
const AliasAttr *AA = D->getAttr<AliasAttr>();
|
||||
@@ -2100,6 +2125,18 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
|
||||
Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
|
||||
llvm::PointerType::getUnqual(DeclTy), 0);
|
||||
|
||||
llvm::GlobalValue *GV = dyn_cast<llvm::GlobalValue>(Aliasee);
|
||||
if (!GV) {
|
||||
llvm::ConstantExpr *CE = cast<llvm::ConstantExpr>(Aliasee);
|
||||
assert(CE->getOpcode() == llvm::Instruction::BitCast ||
|
||||
CE->getOpcode() == llvm::Instruction::GetElementPtr);
|
||||
GV = cast<llvm::GlobalValue>(CE->getOperand(0));
|
||||
}
|
||||
if (GV->isDeclaration()) {
|
||||
getDiags().Report(AA->getLocation(), diag::err_alias_to_undefined);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the new alias itself, but don't set a name yet.
|
||||
llvm::GlobalValue *GA =
|
||||
new llvm::GlobalAlias(Aliasee->getType(),
|
||||
|
||||
Reference in New Issue
Block a user