Index: lib/CodeGen/CGAtomic.cpp =================================================================== --- lib/CodeGen/CGAtomic.cpp +++ lib/CodeGen/CGAtomic.cpp @@ -300,16 +300,15 @@ return TempAlloca; } -static RValue emitAtomicLibcall(CodeGenFunction &CGF, - StringRef fnName, - QualType resultType, - CallArgList &args) { +static RValue emitAtomicLibcall(CodeGenFunction &CGF, StringRef fnName, + QualType resultType, CallArgList &args) { const CGFunctionInfo &fnInfo = CGF.CGM.getTypes().arrangeBuiltinFunctionCall(resultType, args); llvm::FunctionType *fnTy = CGF.CGM.getTypes().GetFunctionType(fnInfo); llvm::Constant *fn = CGF.CGM.CreateRuntimeFunction(fnTy, fnName); auto callee = CGCallee::forDirect(fn); - return CGF.EmitCall(fnInfo, callee, ReturnValueSlot(), args); + return CGF.EmitCall(fnInfo, callee, ReturnValueSlot(), args, + SourceLocation()); } /// Does a store of the given IR type modify the full expected width? Index: lib/CodeGen/CGBlocks.cpp =================================================================== --- lib/CodeGen/CGBlocks.cpp +++ lib/CodeGen/CGBlocks.cpp @@ -1162,7 +1162,7 @@ CGCallee Callee(CGCalleeInfo(), Func); // And call the block. - return EmitCall(FnInfo, Callee, ReturnValue, Args); + return EmitCall(FnInfo, Callee, ReturnValue, Args, E->getExprLoc()); } Address CodeGenFunction::GetAddrOfBlockDecl(const VarDecl *variable, Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -823,7 +823,7 @@ CGM.getTypes().arrangeBuiltinFunctionCall(Ctx.VoidTy, Args); llvm::Function *F = CodeGenFunction(CGM).generateBuiltinOSLogHelperFunction( Layout, BufAddr.getAlignment()); - EmitCall(FI, CGCallee::forDirect(F), ReturnValueSlot(), Args); + EmitCall(FI, CGCallee::forDirect(F), ReturnValueSlot(), Args, E.getExprLoc()); // Push a clang.arc.use cleanup for each object in RetainableOperands. The // cleanup will cause the use to appear after the final log call, keeping @@ -1218,14 +1218,7 @@ case Builtin::BI__debugbreak: return RValue::get(EmitTrapCall(Intrinsic::debugtrap)); case Builtin::BI__builtin_unreachable: { - if (SanOpts.has(SanitizerKind::Unreachable)) { - SanitizerScope SanScope(this); - EmitCheck(std::make_pair(static_cast(Builder.getFalse()), - SanitizerKind::Unreachable), - SanitizerHandler::BuiltinUnreachable, - EmitCheckSourceLocation(E->getExprLoc()), None); - } else - Builder.CreateUnreachable(); + EmitUnreachable(E->getExprLoc()); // We do need to preserve an insertion point. EmitBlock(createBasicBlock("unreachable.cont")); @@ -1858,8 +1851,8 @@ CGM.getTypes().arrangeBuiltinFunctionCall(E->getType(), Args); llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo); llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName); - return EmitCall(FuncInfo, CGCallee::forDirect(Func), - ReturnValueSlot(), Args); + return EmitCall(FuncInfo, CGCallee::forDirect(Func), ReturnValueSlot(), + Args, SourceLocation()); } case Builtin::BI__atomic_test_and_set: { Index: lib/CodeGen/CGCall.cpp =================================================================== --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -3713,6 +3713,7 @@ const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &CallArgs, + SourceLocation Loc, llvm::Instruction **callOrInvoke) { // FIXME: We no longer need the types from CallArgs; lift up and simplify. @@ -4236,7 +4237,7 @@ EmitLifetimeEnd(llvm::ConstantInt::get(Int64Ty, UnusedReturnSize), SRetPtr.getPointer()); - Builder.CreateUnreachable(); + EmitUnreachable(Loc); Builder.ClearInsertionPoint(); // FIXME: For now, emit a dummy basic block because expr emitters in Index: lib/CodeGen/CGClass.cpp =================================================================== --- lib/CodeGen/CGClass.cpp +++ lib/CodeGen/CGClass.cpp @@ -2099,7 +2099,7 @@ const CGFunctionInfo &Info = CGM.getTypes().arrangeCXXConstructorCall( Args, D, Type, ExtraArgs.Prefix, ExtraArgs.Suffix, PassPrototypeArgs); CGCallee Callee = CGCallee::forDirect(CalleePtr, D); - EmitCall(Info, Callee, ReturnValueSlot(), Args); + EmitCall(Info, Callee, ReturnValueSlot(), Args, SourceLocation()); // Generate vtable assumptions if we're constructing a complete object // with a vtable. We don't do this for base subobjects for two reasons: @@ -2773,7 +2773,8 @@ // Now emit our call. auto callee = CGCallee::forDirect(calleePtr, callOperator); - RValue RV = EmitCall(calleeFnInfo, callee, returnSlot, callArgs); + RValue RV = + EmitCall(calleeFnInfo, callee, returnSlot, callArgs, SourceLocation()); // If necessary, copy the returned value into the slot. if (!resultType->isVoidType() && returnSlot.isNull()) Index: lib/CodeGen/CGDecl.cpp =================================================================== --- lib/CodeGen/CGDecl.cpp +++ lib/CodeGen/CGDecl.cpp @@ -558,7 +558,7 @@ Args.add(RValue::get(Arg), CGF.getContext().getPointerType(Var.getType())); auto Callee = CGCallee::forDirect(CleanupFn); - CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args); + CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args, SourceLocation()); } }; } // end anonymous namespace Index: lib/CodeGen/CGException.cpp =================================================================== --- lib/CodeGen/CGException.cpp +++ lib/CodeGen/CGException.cpp @@ -1442,7 +1442,7 @@ CGM.getTypes().arrangeBuiltinFunctionCall(Context.VoidTy, Args); auto Callee = CGCallee::forDirect(OutlinedFinally); - CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args); + CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args, SourceLocation()); } }; } // end anonymous namespace Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -3050,6 +3050,19 @@ EmitBlock(Cont); } +void CodeGenFunction::EmitUnreachable(SourceLocation Loc) { + if (SanOpts.has(SanitizerKind::Unreachable) && Loc.isValid()) { + SanitizerScope SanScope(this); + EmitCheck(std::make_pair(static_cast(Builder.getFalse()), + SanitizerKind::Unreachable), + SanitizerHandler::BuiltinUnreachable, + EmitCheckSourceLocation(Loc), None); + } + + // Ensure that the current block has a terminator. + Builder.CreateUnreachable(); +} + llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID) { llvm::CallInst *TrapCall = Builder.CreateCall(CGM.getIntrinsic(IntrID)); @@ -4577,7 +4590,7 @@ Callee.setFunctionPointer(CalleePtr); } - return EmitCall(FnInfo, Callee, ReturnValue, Args); + return EmitCall(FnInfo, Callee, ReturnValue, Args, E->getExprLoc()); } LValue CodeGenFunction:: Index: lib/CodeGen/CGExprCXX.cpp =================================================================== --- lib/CodeGen/CGExprCXX.cpp +++ lib/CodeGen/CGExprCXX.cpp @@ -89,7 +89,8 @@ *this, MD, This, ImplicitParam, ImplicitParamTy, CE, Args, RtlArgs); auto &FnInfo = CGM.getTypes().arrangeCXXMethodCall( Args, FPT, CallInfo.ReqArgs, CallInfo.PrefixSize); - return EmitCall(FnInfo, Callee, ReturnValue, Args); + return EmitCall(FnInfo, Callee, ReturnValue, Args, + CE ? CE->getExprLoc() : SourceLocation()); } RValue CodeGenFunction::EmitCXXDestructorCall( @@ -100,7 +101,7 @@ commonEmitCXXMemberOrOperatorCall(*this, DD, This, ImplicitParam, ImplicitParamTy, CE, Args, nullptr); return EmitCall(CGM.getTypes().arrangeCXXStructorDeclaration(DD, Type), - Callee, ReturnValueSlot(), Args); + Callee, ReturnValueSlot(), Args, SourceLocation()); } RValue CodeGenFunction::EmitCXXPseudoDestructorExpr( @@ -444,7 +445,7 @@ EmitCallArgs(Args, FPT, E->arguments()); return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required, /*PrefixSize=*/0), - Callee, ReturnValue, Args); + Callee, ReturnValue, Args, E->getExprLoc()); } RValue @@ -1267,10 +1268,10 @@ llvm::Instruction *CallOrInvoke; llvm::Constant *CalleePtr = CGF.CGM.GetAddrOfFunction(CalleeDecl); CGCallee Callee = CGCallee::forDirect(CalleePtr, CalleeDecl); - RValue RV = - CGF.EmitCall(CGF.CGM.getTypes().arrangeFreeFunctionCall( - Args, CalleeType, /*chainCall=*/false), - Callee, ReturnValueSlot(), Args, &CallOrInvoke); + RValue RV = CGF.EmitCall(CGF.CGM.getTypes().arrangeFreeFunctionCall( + Args, CalleeType, /*chainCall=*/false), + Callee, ReturnValueSlot(), Args, SourceLocation(), + &CallOrInvoke); /// C++1y [expr.new]p10: /// [In a new-expression,] an implementation is allowed to omit a call Index: lib/CodeGen/CGExprComplex.cpp =================================================================== --- lib/CodeGen/CGExprComplex.cpp +++ lib/CodeGen/CGExprComplex.cpp @@ -627,7 +627,8 @@ CGCallee Callee = CGCallee::forDirect(Func, FQTy->getAs()); llvm::Instruction *Call; - RValue Res = CGF.EmitCall(FuncInfo, Callee, ReturnValueSlot(), Args, &Call); + RValue Res = CGF.EmitCall(FuncInfo, Callee, ReturnValueSlot(), Args, + SourceLocation(), &Call); cast(Call)->setCallingConv(CGF.CGM.getBuiltinCC()); return Res.getComplexVal(); } Index: lib/CodeGen/CGObjC.cpp =================================================================== --- lib/CodeGen/CGObjC.cpp +++ lib/CodeGen/CGObjC.cpp @@ -606,7 +606,7 @@ llvm::Constant *fn = CGF.CGM.getObjCRuntime().GetGetStructFunction(); CGCallee callee = CGCallee::forDirect(fn); CGF.EmitCall(CGF.getTypes().arrangeBuiltinFunctionCall(Context.VoidTy, args), - callee, ReturnValueSlot(), args); + callee, ReturnValueSlot(), args, SourceLocation()); } /// Determine whether the given architecture supports unaligned atomic @@ -872,7 +872,7 @@ CGCallee callee = CGCallee::forDirect(copyCppAtomicObjectFn); CGF.EmitCall( CGF.getTypes().arrangeBuiltinFunctionCall(CGF.getContext().VoidTy, args), - callee, ReturnValueSlot(), args); + callee, ReturnValueSlot(), args, SourceLocation()); } void @@ -970,9 +970,9 @@ // FIXME: We shouldn't need to get the function info here, the // runtime already should have computed it to build the function. llvm::Instruction *CallInstruction; - RValue RV = EmitCall( - getTypes().arrangeBuiltinFunctionCall(propType, args), - callee, ReturnValueSlot(), args, &CallInstruction); + RValue RV = + EmitCall(getTypes().arrangeBuiltinFunctionCall(propType, args), callee, + ReturnValueSlot(), args, SourceLocation(), &CallInstruction); if (llvm::CallInst *call = dyn_cast(CallInstruction)) call->setTailCall(); @@ -1088,7 +1088,7 @@ CGCallee callee = CGCallee::forDirect(fn); CGF.EmitCall( CGF.getTypes().arrangeBuiltinFunctionCall(CGF.getContext().VoidTy, args), - callee, ReturnValueSlot(), args); + callee, ReturnValueSlot(), args, SourceLocation()); } /// emitCPPObjectAtomicSetterCall - Call the runtime function to store @@ -1125,7 +1125,7 @@ CGCallee callee = CGCallee::forDirect(fn); CGF.EmitCall( CGF.getTypes().arrangeBuiltinFunctionCall(CGF.getContext().VoidTy, args), - callee, ReturnValueSlot(), args); + callee, ReturnValueSlot(), args, SourceLocation()); } @@ -1256,7 +1256,7 @@ args.add(RValue::get(ivarOffset), getContext().getPointerDiffType()); CGCallee callee = CGCallee::forDirect(setOptimizedPropertyFn); EmitCall(getTypes().arrangeBuiltinFunctionCall(getContext().VoidTy, args), - callee, ReturnValueSlot(), args); + callee, ReturnValueSlot(), args, SourceLocation()); } else { args.add(RValue::get(ivarOffset), getContext().getPointerDiffType()); args.add(RValue::get(arg), getContext().getObjCIdType()); @@ -1268,7 +1268,7 @@ // already should have computed it to build the function. CGCallee callee = CGCallee::forDirect(setPropertyFn); EmitCall(getTypes().arrangeBuiltinFunctionCall(getContext().VoidTy, args), - callee, ReturnValueSlot(), args); + callee, ReturnValueSlot(), args, SourceLocation()); } return; @@ -1627,8 +1627,8 @@ // FIXME: We shouldn't need to get the function info here, the runtime already // should have computed it to build the function. EmitCall( - CGM.getTypes().arrangeBuiltinFunctionCall(getContext().VoidTy, Args2), - EnumerationMutationFn, ReturnValueSlot(), Args2); + CGM.getTypes().arrangeBuiltinFunctionCall(getContext().VoidTy, Args2), + EnumerationMutationFn, ReturnValueSlot(), Args2, SourceLocation()); // Otherwise, or if the mutation function returns, just continue. EmitBlock(WasNotMutatedBB); Index: lib/CodeGen/CGObjCGNU.cpp =================================================================== --- lib/CodeGen/CGObjCGNU.cpp +++ lib/CodeGen/CGObjCGNU.cpp @@ -1349,7 +1349,8 @@ CGCallee callee(CGCalleeInfo(), imp); llvm::Instruction *call; - RValue msgRet = CGF.EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call); + RValue msgRet = CGF.EmitCall(MSI.CallInfo, callee, Return, ActualArgs, + SourceLocation(), &call); call->setMetadata(msgSendMDKind, node); return msgRet; } @@ -1462,10 +1463,10 @@ llvm::Instruction *call; CGCallee callee(CGCalleeInfo(), imp); - RValue msgRet = CGF.EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call); + RValue msgRet = CGF.EmitCall(MSI.CallInfo, callee, Return, ActualArgs, + SourceLocation(), &call); call->setMetadata(msgSendMDKind, node); - if (!isPointerSizedReturn) { messageBB = CGF.Builder.GetInsertBlock(); CGF.Builder.CreateBr(continueBB); Index: lib/CodeGen/CGObjCMac.cpp =================================================================== --- lib/CodeGen/CGObjCMac.cpp +++ lib/CodeGen/CGObjCMac.cpp @@ -2167,7 +2167,7 @@ Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType); CGCallee Callee = CGCallee::forDirect(Fn); RValue rvalue = CGF.EmitCall(MSI.CallInfo, Callee, Return, ActualArgs, - &CallSite); + SourceLocation(), &CallSite); // Mark the call as noreturn if the method is marked noreturn and the // receiver cannot be null. @@ -7092,7 +7092,8 @@ calleePtr = CGF.Builder.CreateBitCast(calleePtr, MSI.MessengerType); CGCallee callee(CGCalleeInfo(), calleePtr); - RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args); + RValue result = + CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args, SourceLocation()); return nullReturn.complete(CGF, returnSlot, result, resultType, formalArgs, requiresnullCheck ? method : nullptr); } Index: lib/CodeGen/CGVTables.cpp =================================================================== --- lib/CodeGen/CGVTables.cpp +++ lib/CodeGen/CGVTables.cpp @@ -357,7 +357,8 @@ // Now emit our call. llvm::Instruction *CallOrInvoke; CGCallee Callee = CGCallee::forDirect(CalleePtr, MD); - RValue RV = EmitCall(*CurFnInfo, Callee, Slot, CallArgs, &CallOrInvoke); + RValue RV = EmitCall(*CurFnInfo, Callee, Slot, CallArgs, SourceLocation(), + &CallOrInvoke); // Consider return adjustment if we have ThunkInfo. if (Thunk && !Thunk->Return.isEmpty()) Index: lib/CodeGen/CodeGenFunction.h =================================================================== --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -3278,6 +3278,7 @@ /// LLVM arguments and the types they were derived from. RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, + SourceLocation Loc, llvm::Instruction **callOrInvoke = nullptr); RValue EmitCall(QualType FnType, const CGCallee &Callee, const CallExpr *E, @@ -3740,6 +3741,10 @@ /// conditional branch to it, for the -ftrapv checks. void EmitTrapCheck(llvm::Value *Checked); + /// If the unreachable sanitizer is disabled or \p Loc is invalid, simply + /// emit an UnreachableInst. Otherwise, emit a runtime trap. + void EmitUnreachable(SourceLocation Loc); + /// \brief Emit a call to trap or debugtrap and attach function attribute /// "trap-func-name" if specified. llvm::CallInst *EmitTrapCall(llvm::Intrinsic::ID IntrID); Index: lib/CodeGen/MicrosoftCXXABI.cpp =================================================================== --- lib/CodeGen/MicrosoftCXXABI.cpp +++ lib/CodeGen/MicrosoftCXXABI.cpp @@ -3941,7 +3941,7 @@ CGCallee Callee = CGCallee::forDirect(CalleePtr, CD); const CGFunctionInfo &CalleeInfo = CGM.getTypes().arrangeCXXConstructorCall( Args, CD, Ctor_Complete, ExtraArgs.Prefix, ExtraArgs.Suffix); - CGF.EmitCall(CalleeInfo, Callee, ReturnValueSlot(), Args); + CGF.EmitCall(CalleeInfo, Callee, ReturnValueSlot(), Args, SourceLocation()); Cleanups.ForceCleanup(); Index: test/CodeGenCXX/ubsan-unreachable.cpp =================================================================== --- /dev/null +++ test/CodeGenCXX/ubsan-unreachable.cpp @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=unreachable | FileCheck %s + +extern void __attribute__((noreturn)) abort(); + +// CHECK-LABEL: define void @_Z14calls_noreturnv +void calls_noreturn() { + abort(); + + // CHECK: __ubsan_handle_builtin_unreachable + // CHECK: unreachable +} + +struct A { + // Test regular members. + void __attribute__((noreturn)) does_not_return1() { + abort(); + } + + // CHECK-LABEL: define linkonce_odr void @_ZN1A5call1Ev + void call1() { + does_not_return1(); + + // CHECK: __ubsan_handle_builtin_unreachable + // CHECK: unreachable + } + + // Test static members. + static void __attribute__((noreturn)) does_not_return2() { + abort(); + } + + // CHECK-LABEL: define linkonce_odr void @_ZN1A5call2Ev + void call2() { + does_not_return2(); + + // CHECK: __ubsan_handle_builtin_unreachable + // CHECK: unreachable + } + + // Test calls through pointers to non-static member functions. + typedef void __attribute__((noreturn)) (A::*MemFn)(); + + // CHECK-LABEL: define linkonce_odr void @_ZN1A5call3Ev + void call3() { + MemFn MF = &A::does_not_return1; + (this->*MF)(); + + // CHECK: __ubsan_handle_builtin_unreachable + // CHECK: unreachable + } +}; + +void force_irgen() { + A a; + a.call1(); + a.call2(); + a.call3(); +}