From 0fad0d7724339d9397ad55ec6c9580a9236dad17 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 22 Oct 2013 13:51:06 +0000 Subject: 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 --- clang/lib/CodeGen/CodeGenModule.cpp | 39 ++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'clang/lib/CodeGen/CodeGenModule.cpp') diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 96ae437..2939b4a 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -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(D.getDecl()); + if (Global->hasAttr()) { + 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()) - 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(GD.getDecl()); + const AliasAttr *AA = D->getAttr(); + 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(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(GD.getDecl()); const AliasAttr *AA = D->getAttr(); @@ -2100,6 +2125,18 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) { Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(), llvm::PointerType::getUnqual(DeclTy), 0); + llvm::GlobalValue *GV = dyn_cast(Aliasee); + if (!GV) { + llvm::ConstantExpr *CE = cast(Aliasee); + assert(CE->getOpcode() == llvm::Instruction::BitCast || + CE->getOpcode() == llvm::Instruction::GetElementPtr); + GV = cast(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(), -- cgit v1.1