1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

Revert "[Sanitizers] UBSan unreachable incompatible with ASan in the presence of noreturn calls"

This reverts commit cea84ab93aeb079a358ab1c8aeba6d9140ef8b47.

llvm-svn: 352069
This commit is contained in:
Julian Lettner 2019-01-24 18:04:21 +00:00
parent 19969315fc
commit 86d339523f
15 changed files with 25 additions and 65 deletions

View File

@ -1458,10 +1458,6 @@ example:
This function attribute indicates that the function never returns This function attribute indicates that the function never returns
normally. This produces undefined behavior at runtime if the normally. This produces undefined behavior at runtime if the
function ever does dynamically return. function ever does dynamically return.
``expect_noreturn``
This function attribute indicates that the function is unlikely to return
normally, but that it still allowed to do so. This is useful in cases where
``noreturn`` is too strong a guarantee.
``norecurse`` ``norecurse``
This function attribute indicates that the function does not call itself This function attribute indicates that the function does not call itself
either directly or indirectly down any possible call path. This produces either directly or indirectly down any possible call path. This produces

View File

@ -603,7 +603,6 @@ enum AttributeKindCodes {
ATTR_KIND_OPT_FOR_FUZZING = 57, ATTR_KIND_OPT_FOR_FUZZING = 57,
ATTR_KIND_SHADOWCALLSTACK = 58, ATTR_KIND_SHADOWCALLSTACK = 58,
ATTR_KIND_SPECULATIVE_LOAD_HARDENING = 59, ATTR_KIND_SPECULATIVE_LOAD_HARDENING = 59,
ATTR_KIND_EXPECT_NO_RETURN = 60,
}; };
enum ComdatSelectionKindCodes { enum ComdatSelectionKindCodes {

View File

@ -106,10 +106,6 @@ def NoRedZone : EnumAttr<"noredzone">;
/// Mark the function as not returning. /// Mark the function as not returning.
def NoReturn : EnumAttr<"noreturn">; def NoReturn : EnumAttr<"noreturn">;
/// Mark the function as unlikely to return. This is useful in cases where
/// `noreturn` is too strong a guarantee.
def ExpectNoReturn : EnumAttr<"expect_noreturn">;
/// Disable Indirect Branch Tracking. /// Disable Indirect Branch Tracking.
def NoCfCheck : EnumAttr<"nocf_check">; def NoCfCheck : EnumAttr<"nocf_check">;

View File

@ -656,7 +656,6 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(nonnull); KEYWORD(nonnull);
KEYWORD(noredzone); KEYWORD(noredzone);
KEYWORD(noreturn); KEYWORD(noreturn);
KEYWORD(expect_noreturn);
KEYWORD(nocf_check); KEYWORD(nocf_check);
KEYWORD(nounwind); KEYWORD(nounwind);
KEYWORD(optforfuzzing); KEYWORD(optforfuzzing);

View File

@ -1248,8 +1248,6 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break; case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break;
case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break; case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break;
case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break; case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break;
case lltok::kw_expect_noreturn:
B.addAttribute(Attribute::ExpectNoReturn); break;
case lltok::kw_nocf_check: B.addAttribute(Attribute::NoCfCheck); break; case lltok::kw_nocf_check: B.addAttribute(Attribute::NoCfCheck); break;
case lltok::kw_norecurse: B.addAttribute(Attribute::NoRecurse); break; case lltok::kw_norecurse: B.addAttribute(Attribute::NoRecurse); break;
case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break; case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break;
@ -1613,7 +1611,6 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) {
case lltok::kw_nonlazybind: case lltok::kw_nonlazybind:
case lltok::kw_noredzone: case lltok::kw_noredzone:
case lltok::kw_noreturn: case lltok::kw_noreturn:
case lltok::kw_expect_noreturn:
case lltok::kw_nocf_check: case lltok::kw_nocf_check:
case lltok::kw_nounwind: case lltok::kw_nounwind:
case lltok::kw_optforfuzzing: case lltok::kw_optforfuzzing:
@ -1711,7 +1708,6 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
case lltok::kw_nonlazybind: case lltok::kw_nonlazybind:
case lltok::kw_noredzone: case lltok::kw_noredzone:
case lltok::kw_noreturn: case lltok::kw_noreturn:
case lltok::kw_expect_noreturn:
case lltok::kw_nocf_check: case lltok::kw_nocf_check:
case lltok::kw_nounwind: case lltok::kw_nounwind:
case lltok::kw_optforfuzzing: case lltok::kw_optforfuzzing:

View File

@ -200,7 +200,6 @@ enum Kind {
kw_nonnull, kw_nonnull,
kw_noredzone, kw_noredzone,
kw_noreturn, kw_noreturn,
kw_expect_noreturn,
kw_nocf_check, kw_nocf_check,
kw_nounwind, kw_nounwind,
kw_optforfuzzing, kw_optforfuzzing,

View File

@ -1186,8 +1186,8 @@ static uint64_t getRawAttributeMask(Attribute::AttrKind Val) {
case Attribute::NoCfCheck: return 1ULL << 57; case Attribute::NoCfCheck: return 1ULL << 57;
case Attribute::OptForFuzzing: return 1ULL << 58; case Attribute::OptForFuzzing: return 1ULL << 58;
case Attribute::ShadowCallStack: return 1ULL << 59; case Attribute::ShadowCallStack: return 1ULL << 59;
case Attribute::SpeculativeLoadHardening: return 1ULL << 60; case Attribute::SpeculativeLoadHardening:
case Attribute::ExpectNoReturn: return 1ULL << 61; return 1ULL << 60;
case Attribute::Dereferenceable: case Attribute::Dereferenceable:
llvm_unreachable("dereferenceable attribute not supported in raw format"); llvm_unreachable("dereferenceable attribute not supported in raw format");
break; break;
@ -1366,8 +1366,6 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
return Attribute::NoRedZone; return Attribute::NoRedZone;
case bitc::ATTR_KIND_NO_RETURN: case bitc::ATTR_KIND_NO_RETURN:
return Attribute::NoReturn; return Attribute::NoReturn;
case bitc::ATTR_KIND_EXPECT_NO_RETURN:
return Attribute::ExpectNoReturn;
case bitc::ATTR_KIND_NOCF_CHECK: case bitc::ATTR_KIND_NOCF_CHECK:
return Attribute::NoCfCheck; return Attribute::NoCfCheck;
case bitc::ATTR_KIND_NO_UNWIND: case bitc::ATTR_KIND_NO_UNWIND:

View File

@ -654,8 +654,6 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_NO_RED_ZONE; return bitc::ATTR_KIND_NO_RED_ZONE;
case Attribute::NoReturn: case Attribute::NoReturn:
return bitc::ATTR_KIND_NO_RETURN; return bitc::ATTR_KIND_NO_RETURN;
case Attribute::ExpectNoReturn:
return bitc::ATTR_KIND_EXPECT_NO_RETURN;
case Attribute::NoCfCheck: case Attribute::NoCfCheck:
return bitc::ATTR_KIND_NOCF_CHECK; return bitc::ATTR_KIND_NOCF_CHECK;
case Attribute::NoUnwind: case Attribute::NoUnwind:

View File

@ -298,8 +298,6 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
return "noredzone"; return "noredzone";
if (hasAttribute(Attribute::NoReturn)) if (hasAttribute(Attribute::NoReturn))
return "noreturn"; return "noreturn";
if (hasAttribute(Attribute::ExpectNoReturn))
return "expect_noreturn";
if (hasAttribute(Attribute::NoCfCheck)) if (hasAttribute(Attribute::NoCfCheck))
return "nocf_check"; return "nocf_check";
if (hasAttribute(Attribute::NoRecurse)) if (hasAttribute(Attribute::NoRecurse))

View File

@ -1477,7 +1477,6 @@ void Verifier::visitModuleFlagCGProfileEntry(const MDOperand &MDO) {
static bool isFuncOnlyAttr(Attribute::AttrKind Kind) { static bool isFuncOnlyAttr(Attribute::AttrKind Kind) {
switch (Kind) { switch (Kind) {
case Attribute::NoReturn: case Attribute::NoReturn:
case Attribute::ExpectNoReturn:
case Attribute::NoCfCheck: case Attribute::NoCfCheck:
case Attribute::NoUnwind: case Attribute::NoUnwind:
case Attribute::NoInline: case Attribute::NoInline:

View File

@ -41,7 +41,6 @@ static Attribute::AttrKind parseAttrKind(StringRef Kind) {
.Case("nonlazybind", Attribute::NonLazyBind) .Case("nonlazybind", Attribute::NonLazyBind)
.Case("noredzone", Attribute::NoRedZone) .Case("noredzone", Attribute::NoRedZone)
.Case("noreturn", Attribute::NoReturn) .Case("noreturn", Attribute::NoReturn)
.Case("expect_noreturn", Attribute::ExpectNoReturn)
.Case("nocf_check", Attribute::NoCfCheck) .Case("nocf_check", Attribute::NoCfCheck)
.Case("norecurse", Attribute::NoRecurse) .Case("norecurse", Attribute::NoRecurse)
.Case("nounwind", Attribute::NoUnwind) .Case("nounwind", Attribute::NoUnwind)

View File

@ -2568,8 +2568,7 @@ bool AddressSanitizer::runOnFunction(Function &F) {
if (CS) { if (CS) {
// A call inside BB. // A call inside BB.
TempsToInstrument.clear(); TempsToInstrument.clear();
if (CS.doesNotReturn() || CS.hasFnAttr(Attribute::ExpectNoReturn)) if (CS.doesNotReturn()) NoReturnCalls.push_back(CS.getInstruction());
NoReturnCalls.push_back(CS.getInstruction());
} }
if (CallInst *CI = dyn_cast<CallInst>(&Inst)) if (CallInst *CI = dyn_cast<CallInst>(&Inst))
maybeMarkSanitizerLibraryCallNoBuiltin(CI, TLI); maybeMarkSanitizerLibraryCallNoBuiltin(CI, TLI);

View File

@ -779,7 +779,6 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
case Attribute::NoBuiltin: case Attribute::NoBuiltin:
case Attribute::NoCapture: case Attribute::NoCapture:
case Attribute::NoReturn: case Attribute::NoReturn:
case Attribute::ExpectNoReturn:
case Attribute::None: case Attribute::None:
case Attribute::NonNull: case Attribute::NonNull:
case Attribute::ReadNone: case Attribute::ReadNone:

View File

@ -204,7 +204,7 @@ define void @f34()
; CHECK: define void @f34() ; CHECK: define void @f34()
{ {
call void @nobuiltin() nobuiltin call void @nobuiltin() nobuiltin
; CHECK: call void @nobuiltin() #37 ; CHECK: call void @nobuiltin() #36
ret void; ret void;
} }
@ -351,12 +351,6 @@ define void @f59() shadowcallstack
ret void ret void
} }
; CHECK: define void @f60() #36
define void @f60() expect_noreturn
{
ret void
}
; CHECK: attributes #0 = { noreturn } ; CHECK: attributes #0 = { noreturn }
; CHECK: attributes #1 = { nounwind } ; CHECK: attributes #1 = { nounwind }
; CHECK: attributes #2 = { readnone } ; CHECK: attributes #2 = { readnone }
@ -393,5 +387,4 @@ define void @f60() expect_noreturn
; CHECK: attributes #33 = { speculatable } ; CHECK: attributes #33 = { speculatable }
; CHECK: attributes #34 = { sanitize_hwaddress } ; CHECK: attributes #34 = { sanitize_hwaddress }
; CHECK: attributes #35 = { shadowcallstack } ; CHECK: attributes #35 = { shadowcallstack }
; CHECK: attributes #36 = { expect_noreturn } ; CHECK: attributes #36 = { nobuiltin }
; CHECK: attributes #37 = { nobuiltin }

View File

@ -1,45 +1,37 @@
; RUN: opt < %s -asan -S | FileCheck %s ; RUN: opt < %s -asan -asan-module -S | FileCheck %s
; AddressSanitizer must insert __asan_handle_no_return ; AddressSanitizer must insert __asan_handle_no_return
; before every noreturn call or invoke. ; before every noreturn call or invoke.
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-unknown-linux-gnu" target triple = "x86_64-unknown-linux-gnu"
declare void @NormalFunc() declare void @MyNoReturnFunc(i32) noreturn
declare void @NoReturnFunc() noreturn
; Instrument calls to noreturn functions (regardless of callsite) define i32 @Call1(i8* nocapture %arg) uwtable sanitize_address {
define i32 @Call1() sanitize_address { entry:
call void @NoReturnFunc() call void @MyNoReturnFunc(i32 1) noreturn ; The call insn has noreturn attr.
; CHECK: @Call1
; CHECK: call void @__asan_handle_no_return
; CHECK-NEXT: call void @MyNoReturnFunc
; CHECK-NEXT: unreachable
unreachable unreachable
} }
; CHECK-LABEL: @Call1
; CHECK: call void @__asan_handle_no_return
; CHECK-NEXT: call void @NoReturnFunc
; Instrument noreturn call sites (regardless of function) define i32 @Call2(i8* nocapture %arg) uwtable sanitize_address {
define i32 @Call2() sanitize_address { entry:
call void @NormalFunc() noreturn call void @MyNoReturnFunc(i32 1) ; No noreturn attribure on the call.
; CHECK: @Call2
; CHECK: call void @__asan_handle_no_return
; CHECK-NEXT: call void @MyNoReturnFunc
; CHECK-NEXT: unreachable
unreachable unreachable
} }
; CHECK-LABEL: @Call2
; CHECK: call void @__asan_handle_no_return
; CHECK-NEXT: call void @NormalFunc
; Also instrument expect_noreturn call sites
define i32 @Call3() sanitize_address {
call void @NormalFunc() expect_noreturn
ret i32 0
}
; CHECK-LABEL: @Call3
; CHECK: call void @__asan_handle_no_return
; CHECK-NEXT: call void @NormalFunc
declare i32 @__gxx_personality_v0(...) declare i32 @__gxx_personality_v0(...)
define i64 @Invoke1(i8** %esc) sanitize_address personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { define i64 @Invoke1(i8** %esc) nounwind uwtable ssp sanitize_address personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
entry: entry:
invoke void @NoReturnFunc() invoke void @MyNoReturnFunc(i32 1)
to label %invoke.cont unwind label %lpad to label %invoke.cont unwind label %lpad
invoke.cont: invoke.cont:
@ -50,8 +42,8 @@ lpad:
filter [0 x i8*] zeroinitializer filter [0 x i8*] zeroinitializer
ret i64 1 ret i64 1
} }
; CHECK-LABEL: @Invoke1 ; CHECK: @Invoke1
; CHECK: call void @__asan_handle_no_return ; CHECK: call void @__asan_handle_no_return
; CHECK-NEXT: invoke void @NoReturnFunc ; CHECK-NEXT: invoke void @MyNoReturnFunc
; CHECK: ret i64 0 ; CHECK: ret i64 0
; CHECK: ret i64 1 ; CHECK: ret i64 1