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

This reverts commit cea84ab93aeb079a358ab1c8aeba6d9140ef8b47.

llvm-svn: 352069
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index bebefe5..a650493 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4401,16 +4401,12 @@
     if (UnusedReturnSizePtr)
       PopCleanupBlock();
 
-    // Replace the noreturn attribute to better diagnose unreachable UB.
+    // Strip away the noreturn attribute to better diagnose unreachable UB.
     if (SanOpts.has(SanitizerKind::Unreachable)) {
-      // Also remove from function since CS.hasFnAttr(..) also checks attributes
-      // of the called function.
       if (auto *F = CS.getCalledFunction())
         F->removeFnAttr(llvm::Attribute::NoReturn);
       CS.removeAttribute(llvm::AttributeList::FunctionIndex,
                          llvm::Attribute::NoReturn);
-      CS.addAttribute(llvm::AttributeList::FunctionIndex,
-                      llvm::Attribute::ExpectNoReturn);
     }
 
     EmitUnreachable(Loc);
diff --git a/clang/test/CodeGenCXX/ubsan-unreachable.cpp b/clang/test/CodeGenCXX/ubsan-unreachable.cpp
index 9ef613e..32a7804 100644
--- a/clang/test/CodeGenCXX/ubsan-unreachable.cpp
+++ b/clang/test/CodeGenCXX/ubsan-unreachable.cpp
@@ -2,35 +2,38 @@
 
 extern void __attribute__((noreturn)) abort();
 
-// CHECK-LABEL: define void @_Z14calls_noreturnv()
+// CHECK-LABEL: define void @_Z14calls_noreturnv
 void calls_noreturn() {
-  // CHECK: call void @_Z5abortv() [[CALL_SITE_ATTR:#[0-9]+]]
   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 {
-  // CHECK: declare void @_Z5abortv() [[EXTERN_FN_ATTR:#[0-9]+]]
+  // CHECK: declare void @_Z5abortv{{.*}} [[ABORT_ATTR:#[0-9]+]]
 
   // CHECK-LABEL: define linkonce_odr void @_ZN1A5call1Ev
   void call1() {
-    // CHECK: call void @_ZN1A16does_not_return2Ev({{.*}}) [[CALL_SITE_ATTR]]
+    // CHECK-NOT: call void @_ZN1A16does_not_return2Ev{{.*}}#
     does_not_return2();
 
     // CHECK: __ubsan_handle_builtin_unreachable
     // CHECK: unreachable
   }
 
-  // Test static members. Checks are below after `struct A` scope ends.
+  // Test static members.
   static void __attribute__((noreturn)) does_not_return1() {
+    // CHECK-NOT: call void @_Z5abortv{{.*}}#
     abort();
   }
 
   // CHECK-LABEL: define linkonce_odr void @_ZN1A5call2Ev
   void call2() {
-    // CHECK: call void @_ZN1A16does_not_return1Ev() [[CALL_SITE_ATTR]]
+    // CHECK-NOT: call void @_ZN1A16does_not_return1Ev{{.*}}#
     does_not_return1();
 
     // CHECK: __ubsan_handle_builtin_unreachable
@@ -43,18 +46,18 @@
   // CHECK-LABEL: define linkonce_odr void @_ZN1A5call3Ev
   void call3() {
     MemFn MF = &A::does_not_return2;
-    // CHECK: call void %{{[0-9]+\(.*}}) [[CALL_SITE_ATTR]]
     (this->*MF)();
 
+    // CHECK-NOT: call void %{{.*}}#
     // CHECK: __ubsan_handle_builtin_unreachable
     // CHECK: unreachable
   }
 
   // Test regular members.
   // CHECK-LABEL: define linkonce_odr void @_ZN1A16does_not_return2Ev({{.*}})
-  // CHECK-SAME: [[USER_FN_ATTR:#[0-9]+]]
+  // CHECK-SAME: [[DOES_NOT_RETURN_ATTR:#[0-9]+]]
   void __attribute__((noreturn)) does_not_return2() {
-    // CHECK: call void @_Z5abortv() [[CALL_SITE_ATTR]]
+    // CHECK-NOT: call void @_Z5abortv(){{.*}}#
     abort();
 
     // CHECK: call void @__ubsan_handle_builtin_unreachable
@@ -65,9 +68,7 @@
   }
 };
 
-// CHECK-LABEL: define linkonce_odr void @_ZN1A16does_not_return1Ev()
-// CHECK-SAME: [[USER_FN_ATTR]]
-// CHECK: call void @_Z5abortv() [[CALL_SITE_ATTR]]
+// CHECK: define linkonce_odr void @_ZN1A16does_not_return1Ev() [[DOES_NOT_RETURN_ATTR]]
 
 void force_irgen() {
   A a;
@@ -76,9 +77,5 @@
   a.call3();
 }
 
-// 1) 'noreturn' should be removed from functions and call sites
-// 2) 'expect_noreturn' added to call sites
-// CHECK-LABEL: attributes
-// CHECK: [[USER_FN_ATTR]] = { {{.*[^noreturn].*}} }
-// CHECK: [[EXTERN_FN_ATTR]] = { {{.*[^noreturn].*}} }
-// CHECK: [[CALL_SITE_ATTR]] = { expect_noreturn }
+// CHECK-NOT: [[ABORT_ATTR]] = {{[^}]+}}noreturn
+// CHECK-NOT: [[DOES_NOT_RETURN_ATTR]] = {{[^}]+}}noreturn
diff --git a/compiler-rt/test/ubsan/TestCases/Misc/unreachable_asan-compatibility.c b/compiler-rt/test/ubsan/TestCases/Misc/unreachable_asan-compatibility.c
deleted file mode 100644
index eaf7a6e..0000000
--- a/compiler-rt/test/ubsan/TestCases/Misc/unreachable_asan-compatibility.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// Ensure compatiblity of UBSan unreachable with ASan in the presence of
-// noreturn functions
-// RUN: %clang -O2 -fPIC -fsanitize=address,unreachable %s -emit-llvm -S -o - | FileCheck %s
-// REQUIRES: ubsan-asan, deactivate
-
-void bar(void) __attribute__((noreturn));
-
-void foo() {
-  bar();
-}
-// CHECK-LABEL: define void @foo()
-// CHECK:       call void @__asan_handle_no_return
-// CHECK-NEXT:  call void @bar
-// CHECK-NEXT:  call void @__asan_handle_no_return
-// CHECK-NEXT:  call void @__ubsan_handle_builtin_unreachable
-// CHECK-NEXT:  unreachable
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 32c4d45..65c8c75 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -1458,10 +1458,6 @@
     This function attribute indicates that the function never returns
     normally. This produces undefined behavior at runtime if the
     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``
     This function attribute indicates that the function does not call itself
     either directly or indirectly down any possible call path. This produces
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index 0015668..ce853cd 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -603,7 +603,6 @@
   ATTR_KIND_OPT_FOR_FUZZING = 57,
   ATTR_KIND_SHADOWCALLSTACK = 58,
   ATTR_KIND_SPECULATIVE_LOAD_HARDENING = 59,
-  ATTR_KIND_EXPECT_NO_RETURN = 60,
 };
 
 enum ComdatSelectionKindCodes {
diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td
index dc972cf..e786d85 100644
--- a/llvm/include/llvm/IR/Attributes.td
+++ b/llvm/include/llvm/IR/Attributes.td
@@ -106,10 +106,6 @@
 /// Mark the function as not returning.
 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.
 def NoCfCheck : EnumAttr<"nocf_check">;
 
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index a60639b..b543115 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -656,7 +656,6 @@
   KEYWORD(nonnull);
   KEYWORD(noredzone);
   KEYWORD(noreturn);
-  KEYWORD(expect_noreturn);
   KEYWORD(nocf_check);
   KEYWORD(nounwind);
   KEYWORD(optforfuzzing);
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 9167694..855c5d2 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -1248,8 +1248,6 @@
     case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break;
     case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); 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_norecurse: B.addAttribute(Attribute::NoRecurse); break;
     case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break;
@@ -1613,7 +1611,6 @@
     case lltok::kw_nonlazybind:
     case lltok::kw_noredzone:
     case lltok::kw_noreturn:
-    case lltok::kw_expect_noreturn:
     case lltok::kw_nocf_check:
     case lltok::kw_nounwind:
     case lltok::kw_optforfuzzing:
@@ -1711,7 +1708,6 @@
     case lltok::kw_nonlazybind:
     case lltok::kw_noredzone:
     case lltok::kw_noreturn:
-    case lltok::kw_expect_noreturn:
     case lltok::kw_nocf_check:
     case lltok::kw_nounwind:
     case lltok::kw_optforfuzzing:
diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h
index b90394f..41899b2 100644
--- a/llvm/lib/AsmParser/LLToken.h
+++ b/llvm/lib/AsmParser/LLToken.h
@@ -200,7 +200,6 @@
   kw_nonnull,
   kw_noredzone,
   kw_noreturn,
-  kw_expect_noreturn,
   kw_nocf_check,
   kw_nounwind,
   kw_optforfuzzing,
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index d377b6a..0b93a61 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1186,8 +1186,8 @@
   case Attribute::NoCfCheck:       return 1ULL << 57;
   case Attribute::OptForFuzzing:   return 1ULL << 58;
   case Attribute::ShadowCallStack: return 1ULL << 59;
-  case Attribute::SpeculativeLoadHardening: return 1ULL << 60;
-  case Attribute::ExpectNoReturn:  return 1ULL << 61;
+  case Attribute::SpeculativeLoadHardening:
+    return 1ULL << 60;
   case Attribute::Dereferenceable:
     llvm_unreachable("dereferenceable attribute not supported in raw format");
     break;
@@ -1366,8 +1366,6 @@
     return Attribute::NoRedZone;
   case bitc::ATTR_KIND_NO_RETURN:
     return Attribute::NoReturn;
-  case bitc::ATTR_KIND_EXPECT_NO_RETURN:
-    return Attribute::ExpectNoReturn;
   case bitc::ATTR_KIND_NOCF_CHECK:
     return Attribute::NoCfCheck;
   case bitc::ATTR_KIND_NO_UNWIND:
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index f16cdac..f4a539e 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -654,8 +654,6 @@
     return bitc::ATTR_KIND_NO_RED_ZONE;
   case Attribute::NoReturn:
     return bitc::ATTR_KIND_NO_RETURN;
-  case Attribute::ExpectNoReturn:
-    return bitc::ATTR_KIND_EXPECT_NO_RETURN;
   case Attribute::NoCfCheck:
     return bitc::ATTR_KIND_NOCF_CHECK;
   case Attribute::NoUnwind:
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index ab49adba..a474d57 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -298,8 +298,6 @@
     return "noredzone";
   if (hasAttribute(Attribute::NoReturn))
     return "noreturn";
-  if (hasAttribute(Attribute::ExpectNoReturn))
-    return "expect_noreturn";
   if (hasAttribute(Attribute::NoCfCheck))
     return "nocf_check";
   if (hasAttribute(Attribute::NoRecurse))
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 3b3e315..1000e21 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -1477,7 +1477,6 @@
 static bool isFuncOnlyAttr(Attribute::AttrKind Kind) {
   switch (Kind) {
   case Attribute::NoReturn:
-  case Attribute::ExpectNoReturn:
   case Attribute::NoCfCheck:
   case Attribute::NoUnwind:
   case Attribute::NoInline:
diff --git a/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp b/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp
index 7300ca0..cd1fc37 100644
--- a/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp
@@ -41,7 +41,6 @@
       .Case("nonlazybind", Attribute::NonLazyBind)
       .Case("noredzone", Attribute::NoRedZone)
       .Case("noreturn", Attribute::NoReturn)
-      .Case("expect_noreturn", Attribute::ExpectNoReturn)
       .Case("nocf_check", Attribute::NoCfCheck)
       .Case("norecurse", Attribute::NoRecurse)
       .Case("nounwind", Attribute::NoUnwind)
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 8d27ee9..1a007b4 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -2568,8 +2568,7 @@
         if (CS) {
           // A call inside BB.
           TempsToInstrument.clear();
-          if (CS.doesNotReturn() || CS.hasFnAttr(Attribute::ExpectNoReturn))
-            NoReturnCalls.push_back(CS.getInstruction());
+          if (CS.doesNotReturn()) NoReturnCalls.push_back(CS.getInstruction());
         }
         if (CallInst *CI = dyn_cast<CallInst>(&Inst))
           maybeMarkSanitizerLibraryCallNoBuiltin(CI, TLI);
diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
index 3cf26b5..03e2b9d 100644
--- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp
+++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
@@ -779,7 +779,6 @@
       case Attribute::NoBuiltin:
       case Attribute::NoCapture:
       case Attribute::NoReturn:
-      case Attribute::ExpectNoReturn:
       case Attribute::None:
       case Attribute::NonNull:
       case Attribute::ReadNone:
diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll
index e96007e..de3cf8d 100644
--- a/llvm/test/Bitcode/attributes.ll
+++ b/llvm/test/Bitcode/attributes.ll
@@ -204,7 +204,7 @@
 ; CHECK: define void @f34()
 {
         call void @nobuiltin() nobuiltin
-; CHECK: call void @nobuiltin() #37
+; CHECK: call void @nobuiltin() #36
         ret void;
 }
 
@@ -351,12 +351,6 @@
   ret void
 }
 
-; CHECK: define void @f60() #36
-define void @f60() expect_noreturn
-{
-  ret void
-}
-
 ; CHECK: attributes #0 = { noreturn }
 ; CHECK: attributes #1 = { nounwind }
 ; CHECK: attributes #2 = { readnone }
@@ -393,5 +387,4 @@
 ; CHECK: attributes #33 = { speculatable }
 ; CHECK: attributes #34 = { sanitize_hwaddress }
 ; CHECK: attributes #35 = { shadowcallstack }
-; CHECK: attributes #36 = { expect_noreturn }
-; CHECK: attributes #37 = { nobuiltin }
+; CHECK: attributes #36 = { nobuiltin }
diff --git a/llvm/test/Instrumentation/AddressSanitizer/instrument-no-return.ll b/llvm/test/Instrumentation/AddressSanitizer/instrument-no-return.ll
index b8e6aef..2e90bfc 100644
--- a/llvm/test/Instrumentation/AddressSanitizer/instrument-no-return.ll
+++ b/llvm/test/Instrumentation/AddressSanitizer/instrument-no-return.ll
@@ -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
 ; 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 triple = "x86_64-unknown-linux-gnu"
 
-declare void @NormalFunc()
-declare void @NoReturnFunc() noreturn
+declare void @MyNoReturnFunc(i32) noreturn
 
-; Instrument calls to noreturn functions (regardless of callsite)
-define i32 @Call1() sanitize_address {
-  call void @NoReturnFunc()
+define i32 @Call1(i8* nocapture %arg) uwtable sanitize_address {
+entry:
+  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
 }
-; 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() sanitize_address {
-  call void @NormalFunc() noreturn
+define i32 @Call2(i8* nocapture %arg) uwtable sanitize_address {
+entry:
+  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
 }
-; 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(...)
 
-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:
-  invoke void @NoReturnFunc()
+  invoke void @MyNoReturnFunc(i32 1)
           to label %invoke.cont unwind label %lpad
 
 invoke.cont:
@@ -50,8 +42,8 @@
           filter [0 x i8*] zeroinitializer
   ret i64 1
 }
-; CHECK-LABEL:  @Invoke1
+; CHECK: @Invoke1
 ; CHECK:        call void @__asan_handle_no_return
-; CHECK-NEXT:   invoke void @NoReturnFunc
+; CHECK-NEXT:   invoke void @MyNoReturnFunc
 ; CHECK: ret i64 0
 ; CHECK: ret i64 1