diff options
Diffstat (limited to 'clang/lib/CodeGen/CGCall.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 19 |
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 |