summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-10-22 13:51:06 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-10-22 13:51:06 +0000
commit0fad0d7724339d9397ad55ec6c9580a9236dad17 (patch)
treec51f274d1fa587baad76553c95711d6290a843ba /clang/lib/CodeGen/CodeGenModule.cpp
parentacf49f31b6d4fd1589bd47600ec7fc956e18750a (diff)
downloadbcm5719-llvm-0fad0d7724339d9397ad55ec6c9580a9236dad17.tar.gz
bcm5719-llvm-0fad0d7724339d9397ad55ec6c9580a9236dad17.zip
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
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp39
1 files changed, 38 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 96ae437ff46..2939b4a3d2c 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<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(),
OpenPOWER on IntegriCloud