summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGCall.cpp
diff options
context:
space:
mode:
authorVedant Kumar <vsk@apple.com>2017-12-21 00:10:25 +0000
committerVedant Kumar <vsk@apple.com>2017-12-21 00:10:25 +0000
commit09b5bfdd85fa23a331ee565bda289b3c27c00fdf (patch)
treea5adff5e6bd5871fe32873bd2e3da642ba0f6247 /clang/lib/CodeGen/CGCall.cpp
parentfae4f7c6818343acc9ad54cacaadaf9fc6fcf52d (diff)
downloadbcm5719-llvm-09b5bfdd85fa23a331ee565bda289b3c27c00fdf.tar.gz
bcm5719-llvm-09b5bfdd85fa23a331ee565bda289b3c27c00fdf.zip
[ubsan] Diagnose noreturn functions which return
Diagnose 'unreachable' UB when a noreturn function returns. 1. Insert a check at the end of functions marked noreturn. 2. A decl may be marked noreturn in the caller TU, but not marked in the TU where it's defined. To diagnose this scenario, strip away the noreturn attribute on the callee and insert check after calls to it. Testing: check-clang, check-ubsan, check-ubsan-minimal, D40700 rdar://33660464 Differential Revision: https://reviews.llvm.org/D40698 llvm-svn: 321231
Diffstat (limited to 'clang/lib/CodeGen/CGCall.cpp')
-rw-r--r--clang/lib/CodeGen/CGCall.cpp19
1 files changed, 17 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index eea074e0307..38d7344572d 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -2758,6 +2758,12 @@ static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) {
void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
bool EmitRetDbgLoc,
SourceLocation EndLoc) {
+ if (FI.isNoReturn()) {
+ // Noreturn functions don't return.
+ EmitUnreachable(EndLoc);
+ return;
+ }
+
if (CurCodeDecl && CurCodeDecl->hasAttr<NakedAttr>()) {
// Naked functions don't have epilogues.
Builder.CreateUnreachable();
@@ -3718,7 +3724,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
const CGCallee &Callee,
ReturnValueSlot ReturnValue,
const CallArgList &CallArgs,
- llvm::Instruction **callOrInvoke) {
+ llvm::Instruction **callOrInvoke,
+ SourceLocation Loc) {
// FIXME: We no longer need the types from CallArgs; lift up and simplify.
assert(Callee.isOrdinary());
@@ -4241,7 +4248,15 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
EmitLifetimeEnd(llvm::ConstantInt::get(Int64Ty, UnusedReturnSize),
SRetPtr.getPointer());
- Builder.CreateUnreachable();
+ // Strip away the noreturn attribute to better diagnose unreachable UB.
+ if (SanOpts.has(SanitizerKind::Unreachable)) {
+ if (auto *F = CS.getCalledFunction())
+ F->removeFnAttr(llvm::Attribute::NoReturn);
+ CS.removeAttribute(llvm::AttributeList::FunctionIndex,
+ llvm::Attribute::NoReturn);
+ }
+
+ EmitUnreachable(Loc);
Builder.ClearInsertionPoint();
// FIXME: For now, emit a dummy basic block because expr emitters in
OpenPOWER on IntegriCloud