summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@apple.com>2015-07-02 22:15:41 +0000
committerAkira Hatanaka <ahatanaka@apple.com>2015-07-02 22:15:41 +0000
commit85365cd72a9d57c97a96dc845031068ced5aaf18 (patch)
tree7d401e422b776052a9c212a5ae49e1f44c4c1c6d
parent56c70441dca2687bf019d96428728a8ab064a885 (diff)
downloadbcm5719-llvm-85365cd72a9d57c97a96dc845031068ced5aaf18.tar.gz
bcm5719-llvm-85365cd72a9d57c97a96dc845031068ced5aaf18.zip
Attach attribute "trap-func-name" to call sites of llvm.trap and llvm.debugtrap.
This is needed to use clang's command line option "-ftrap-function" for LTO and enable changing the trap function name on a per-call-site basis. rdar://problem/21225723 Differential Revision: http://reviews.llvm.org/D10831 llvm-svn: 241306
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp1
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp12
-rw-r--r--clang/lib/CodeGen/CGCall.cpp2
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp15
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp5
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h4
-rw-r--r--clang/test/CodeGenCXX/trap-fnattr.cpp36
7 files changed, 62 insertions, 13 deletions
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 801b49f04c8..0bccad0570d 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -536,7 +536,6 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
Options.UnsafeFPMath = CodeGenOpts.UnsafeFPMath;
Options.StackAlignmentOverride = CodeGenOpts.StackAlignment;
- Options.TrapFuncName = CodeGenOpts.TrapFuncName;
Options.PositionIndependentExecutable = LangOpts.PIELevel != 0;
Options.FunctionSections = CodeGenOpts.FunctionSections;
Options.DataSections = CodeGenOpts.DataSections;
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 8bd80085e65..2ec909b9aac 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -543,14 +543,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Value *F = CGM.getIntrinsic(Intrinsic::clear_cache);
return RValue::get(Builder.CreateCall(F, {Begin, End}));
}
- case Builtin::BI__builtin_trap: {
- Value *F = CGM.getIntrinsic(Intrinsic::trap);
- return RValue::get(Builder.CreateCall(F, {}));
- }
- case Builtin::BI__debugbreak: {
- Value *F = CGM.getIntrinsic(Intrinsic::debugtrap);
- return RValue::get(Builder.CreateCall(F, {}));
- }
+ case Builtin::BI__builtin_trap:
+ return RValue::get(EmitTrapCall(Intrinsic::trap));
+ case Builtin::BI__debugbreak:
+ return RValue::get(EmitTrapCall(Intrinsic::debugtrap));
case Builtin::BI__builtin_unreachable: {
if (SanOpts.has(SanitizerKind::Unreachable)) {
SanitizerScope SanScope(this);
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 142966e7c01..0535c05da5d 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1452,6 +1452,8 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
// Attributes that should go on the call site only.
if (!CodeGenOpts.SimplifyLibCalls)
FuncAttrs.addAttribute(llvm::Attribute::NoBuiltin);
+ if (!CodeGenOpts.TrapFuncName.empty())
+ FuncAttrs.addAttribute("trap-func-name", CodeGenOpts.TrapFuncName);
} else {
// Attributes that should go on the function, but not the call site.
if (!CodeGenOpts.DisableFPElim) {
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 1a76afaf115..175763c4e81 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -2403,8 +2403,7 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked) {
TrapBB = createBasicBlock("trap");
Builder.CreateCondBr(Checked, Cont, TrapBB);
EmitBlock(TrapBB);
- llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::trap);
- llvm::CallInst *TrapCall = Builder.CreateCall(F, {});
+ llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
TrapCall->setDoesNotReturn();
TrapCall->setDoesNotThrow();
Builder.CreateUnreachable();
@@ -2415,6 +2414,18 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked) {
EmitBlock(Cont);
}
+llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID) {
+ llvm::CallInst *TrapCall =
+ Builder.CreateCall(CGM.getIntrinsic(IntrID), {});
+
+ if (!CGM.getCodeGenOpts().TrapFuncName.empty())
+ TrapCall->addAttribute(llvm::AttributeSet::FunctionIndex,
+ "trap-func-name",
+ CGM.getCodeGenOpts().TrapFuncName);
+
+ return TrapCall;
+}
+
/// isSimpleArrayDecayOperand - If the specified expr is a simple decay from an
/// array to pointer, return the array subexpression.
static const Expr *isSimpleArrayDecayOperand(const Expr *E) {
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index f1fc8c45f1e..1fca466e924 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -930,8 +930,9 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
EmitCheck(std::make_pair(IsFalse, SanitizerKind::Return),
"missing_return", EmitCheckSourceLocation(FD->getLocation()),
None);
- } else if (CGM.getCodeGenOpts().OptimizationLevel == 0)
- Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::trap), {});
+ } else if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
+ EmitTrapCall(llvm::Intrinsic::trap);
+ }
Builder.CreateUnreachable();
Builder.ClearInsertionPoint();
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index cc427c9c889..fac71bf8a6c 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -2875,6 +2875,10 @@ public:
/// conditional branch to it, for the -ftrapv checks.
void EmitTrapCheck(llvm::Value *Checked);
+ /// \brief Emit a call to trap or debugtrap and attach function attribute
+ /// "trap-func-name" if specified.
+ llvm::CallInst *EmitTrapCall(llvm::Intrinsic::ID IntrID);
+
/// \brief Create a check for a function parameter that may potentially be
/// declared as non-null.
void EmitNonNullArgCheck(RValue RV, QualType ArgType, SourceLocation ArgLoc,
diff --git a/clang/test/CodeGenCXX/trap-fnattr.cpp b/clang/test/CodeGenCXX/trap-fnattr.cpp
new file mode 100644
index 00000000000..d9d6f81599c
--- /dev/null
+++ b/clang/test/CodeGenCXX/trap-fnattr.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -O0 -emit-llvm -ftrapv -ftrap-function=mytrap %s -o - | FileCheck %s -check-prefix=TRAPFUNC
+// RUN: %clang_cc1 -O0 -emit-llvm -ftrapv %s -o - | FileCheck %s -check-prefix=NOOPTION
+
+// TRAPFUNC-LABEL: define void @_Z12test_builtinv
+// TRAPFUNC: call void @llvm.trap() [[ATTR0:#[0-9]+]]
+
+// NOOPTION-LABEL: define void @_Z12test_builtinv
+// NOOPTION: call void @llvm.trap(){{$}}
+
+void test_builtin(void) {
+ __builtin_trap();
+}
+
+// TRAPFUNC-LABEL: define i32 @_Z13test_noreturnv
+// TRAPFUNC: call void @llvm.trap() [[ATTR0]]
+
+// NOOPTION-LABEL: define i32 @_Z13test_noreturnv
+// NOOPTION: call void @llvm.trap(){{$}}
+
+int test_noreturn(void) {
+}
+
+// TRAPFUNC-LABEL: define i32 @_Z17test_add_overflowii
+// TRAPFUNC: call void @llvm.trap() [[ATTR1:#[0-9]+]]
+
+// NOOPTION-LABEL: define i32 @_Z17test_add_overflowii
+// NOOPTION: call void @llvm.trap() [[ATTR2:#[0-9]+]]
+
+int test_add_overflow(int a, int b) {
+ return a + b;
+}
+
+// TRAPFUNC: attributes [[ATTR0]] = { {{.*}}"trap-func-name"="mytrap" }
+// TRAPFUNC: attributes [[ATTR1]] = { {{.*}}"trap-func-name"="mytrap" }
+
+// NOOPTION-NOT: attributes [[ATTR2]] = { {{.*}}"trap-func-name"="mytrap" }
OpenPOWER on IntegriCloud