vsk updated this revision to Diff 125221.
vsk edited the summary of this revision.
vsk added a comment.
- Diagnose in the scenario Eli pointed out, by stripping the 'noreturn'
attribute and emitting a check after the call.
- Test updates.
https://reviews.llvm.org/D40698
Files:
docs/UndefinedBehaviorSanitizer.rst
lib/CodeGen/CGAtomic.cpp
lib/CodeGen/CGBlocks.cpp
lib/CodeGen/CGBuiltin.cpp
lib/CodeGen/CGCall.cpp
lib/CodeGen/CGClass.cpp
lib/CodeGen/CGDecl.cpp
lib/CodeGen/CGException.cpp
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprCXX.cpp
lib/CodeGen/CGExprComplex.cpp
lib/CodeGen/CGObjC.cpp
lib/CodeGen/CGObjCGNU.cpp
lib/CodeGen/CGObjCMac.cpp
lib/CodeGen/CGVTables.cpp
lib/CodeGen/CodeGenFunction.h
lib/CodeGen/MicrosoftCXXABI.cpp
test/CodeGen/ubsan-noreturn.c
test/CodeGenCXX/ubsan-unreachable.cpp
Index: test/CodeGenCXX/ubsan-unreachable.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/ubsan-unreachable.cpp
@@ -0,0 +1,74 @@
+// 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 that there are no attributes on the call site.
+ // CHECK-NOT: call void @_Z5abortv{{.*}}#
+
+ // CHECK: __ubsan_handle_builtin_unreachable
+ // CHECK: unreachable
+}
+
+struct A {
+ // Test regular members.
+ void __attribute__((noreturn)) does_not_return1() {
+ // CHECK-NOT: call void @_Z5abortv(){{.*}}#
+ abort();
+ }
+
+ // CHECK: declare void @_Z5abortv{{.*}} [[ABORT_ATTR:#[0-9]+]]
+
+ // CHECK-LABEL: define linkonce_odr void @_ZN1A5call1Ev
+ void call1() {
+ // CHECK-NOT: call void @_ZN1A16does_not_return1Ev{{.*}}#
+ does_not_return1();
+
+ // CHECK: __ubsan_handle_builtin_unreachable
+ // CHECK: unreachable
+ }
+
+ // Test static members.
+ static void __attribute__((noreturn)) does_not_return2() {
+ // CHECK-NOT: call void @_Z5abortv{{.*}}#
+ abort();
+ }
+
+ // CHECK-LABEL: define linkonce_odr void @_ZN1A5call2Ev
+ void call2() {
+ // CHECK-NOT: call void @_ZN1A16does_not_return2Ev{{.*}}#
+ 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-NOT: call void %{{.*}}#
+ // CHECK: __ubsan_handle_builtin_unreachable
+ // CHECK: unreachable
+ }
+};
+
+// CHECK: define linkonce_odr void @_ZN1A16does_not_return1Ev{{.*}} [[DOES_NOT_RETURN_ATTR:#[0-9]+]]
+// CHECK: define linkonce_odr void @_ZN1A16does_not_return2Ev{{.*}} [[DOES_NOT_RETURN_ATTR]]
+
+void force_irgen() {
+ A a;
+ a.call1();
+ a.call2();
+ a.call3();
+}
+
+// CHECK-NOT: [[ABORT_ATTR]] = {{[^}]+}}noreturn
+// CHECK-NOT: [[DOES_NOT_RETURN_ATTR]] = {{[^}]+}}noreturn
Index: test/CodeGen/ubsan-noreturn.c
===================================================================
--- /dev/null
+++ test/CodeGen/ubsan-noreturn.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -emit-llvm -fsanitize=unreachable -o - | FileCheck %s
+
+// CHECK-LABEL: @f(
+void __attribute__((noreturn)) f() {
+ // CHECK: __ubsan_handle_builtin_unreachable
+ // CHECK: unreachable
+}
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: 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,
@@ -3736,6 +3737,10 @@
llvm::ConstantInt *TypeId, llvm::Value *Ptr,
ArrayRef<llvm::Constant *> StaticArgs);
+ /// Emit a reached-unreachable diagnostic if \p Loc is valid and runtime
+ /// checking is enabled. Otherwise, just emit an unreachable instruction.
+ void EmitUnreachable(SourceLocation Loc);
+
/// \brief Create a basic block that will call the trap intrinsic, and emit a
/// conditional branch to it, for the -ftrapv checks.
void EmitTrapCheck(llvm::Value *Checked);
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/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/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/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<llvm::CallInst>(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/CGExprComplex.cpp
===================================================================
--- lib/CodeGen/CGExprComplex.cpp
+++ lib/CodeGen/CGExprComplex.cpp
@@ -627,7 +627,8 @@
CGCallee Callee = CGCallee::forDirect(Func, FQTy->getAs<FunctionProtoType>());
llvm::Instruction *Call;
- RValue Res = CGF.EmitCall(FuncInfo, Callee, ReturnValueSlot(), Args, &Call);
+ RValue Res = CGF.EmitCall(FuncInfo, Callee, ReturnValueSlot(), Args,
+ SourceLocation(), &Call);
cast<llvm::CallInst>(Call)->setCallingConv(CGF.CGM.getBuiltinCC());
return Res.getComplexVal();
}
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/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -3030,6 +3030,17 @@
CGM.addUsedGlobal(F);
}
+void CodeGenFunction::EmitUnreachable(SourceLocation Loc) {
+ if (SanOpts.has(SanitizerKind::Unreachable)) {
+ SanitizerScope SanScope(this);
+ EmitCheck(std::make_pair(static_cast<llvm::Value *>(Builder.getFalse()),
+ SanitizerKind::Unreachable),
+ SanitizerHandler::BuiltinUnreachable,
+ EmitCheckSourceLocation(Loc), None);
+ }
+ Builder.CreateUnreachable();
+}
+
void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked) {
llvm::BasicBlock *Cont = createBasicBlock("cont");
@@ -4577,7 +4588,7 @@
Callee.setFunctionPointer(CalleePtr);
}
- return EmitCall(FnInfo, Callee, ReturnValue, Args);
+ return EmitCall(FnInfo, Callee, ReturnValue, Args, E->getExprLoc());
}
LValue CodeGenFunction::
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/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/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/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -2753,6 +2753,12 @@
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();
@@ -3713,6 +3719,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 +4243,15 @@
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
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<llvm::Value *>(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/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/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: docs/UndefinedBehaviorSanitizer.rst
===================================================================
--- docs/UndefinedBehaviorSanitizer.rst
+++ docs/UndefinedBehaviorSanitizer.rst
@@ -124,8 +124,8 @@
- ``-fsanitize=signed-integer-overflow``: Signed integer overflow,
including all the checks added by ``-ftrapv``, and checking for
overflow in signed division (``INT_MIN / -1``).
- - ``-fsanitize=unreachable``: If control flow reaches
- ``__builtin_unreachable``.
+ - ``-fsanitize=unreachable``: If control flow reaches an unreachable
+ program point.
- ``-fsanitize=unsigned-integer-overflow``: Unsigned integer
overflows. Note that unlike signed integer overflow, unsigned integer
is not undefined behavior. However, while it has well-defined semantics,
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits