[compiler-rt] 97c675d - Revert "Revert "Temporarily do not drop volatile stores before unreachable""

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 9 08:45:03 PDT 2021


Author: Nico Weber
Date: 2021-07-09T11:44:34-04:00
New Revision: 97c675d3d43fe02a0ff0a8350d79344c845758af

URL: https://github.com/llvm/llvm-project/commit/97c675d3d43fe02a0ff0a8350d79344c845758af
DIFF: https://github.com/llvm/llvm-project/commit/97c675d3d43fe02a0ff0a8350d79344c845758af.diff

LOG: Revert "Revert "Temporarily do not drop volatile stores before unreachable""

This reverts commit 52aeacfbf5ce5f949efe0eae029e56db171ea1f7.
There isn't full agreement on a path forward yet, but there is agreement that
this shouldn't land as-is.  See discussion on https://reviews.llvm.org/D105338

Also reverts unreviewed "[clang] Improve `-Wnull-dereference` diag to be more in-line with reality"
This reverts commit f4877c78c0fc98be47b926439bbfe33d5e1d1b6d.

And all the related changes to tests:
This reverts commit 9a0152799f8e4a59e0483728c9f11c8a7805616f.
This reverts commit 3f7c9cc27422f7302cf5a683eeb3978e6cb84270.
This reverts commit 329f8197ef59f9bd23328b52d623ba768b51dbb2.
This reverts commit aa9f58cc2c48ca6cfc853a2467cd775dc7622746.
This reverts commit 2df37d5ddd38091aafbb7d338660e58836f4ac80.
This reverts commit a72a44181264fd83e05be958c2712cbd4560aba7.

Added: 
    compiler-rt/test/fuzzer/NullDerefTest.cpp
    compiler-rt/test/fuzzer/null-deref.test

Modified: 
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaExpr.cpp
    clang/test/Analysis/NewDelete-checker-test.cpp
    clang/test/Analysis/conditional-path-notes.c
    clang/test/Analysis/cxx-for-range.cpp
    clang/test/Analysis/diagnostics/no-prune-paths.c
    clang/test/Analysis/inlining/path-notes.cpp
    clang/test/Analysis/objc-arc.m
    clang/test/Analysis/objc-for.m
    clang/test/Analysis/taint-generic.c
    clang/test/Analysis/valist-uninitialized.c
    clang/test/CodeGenOpenCL/convergent.cl
    clang/test/Parser/expressions.c
    clang/test/Sema/exprs.c
    clang/test/Sema/offsetof.c
    clang/test/SemaCXX/member-pointer.cpp
    compiler-rt/test/asan/TestCases/Windows/dll_control_c.cpp
    compiler-rt/test/fuzzer/ShallowOOMDeepCrash.cpp
    compiler-rt/test/fuzzer/coverage.test
    compiler-rt/test/fuzzer/fork.test
    compiler-rt/test/fuzzer/fuzzer-seed.test
    compiler-rt/test/fuzzer/fuzzer-segv.test
    compiler-rt/test/fuzzer/fuzzer-singleinputs.test
    compiler-rt/test/fuzzer/minimize_crash.test
    compiler-rt/test/sanitizer_common/TestCases/Linux/signal_line.cpp
    llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
    llvm/lib/Transforms/Utils/Local.cpp
    llvm/lib/Transforms/Utils/SimplifyCFG.cpp
    llvm/test/CodeGen/AArch64/branch-relax-alignment.ll
    llvm/test/CodeGen/AArch64/branch-relax-bcc.ll
    llvm/test/CodeGen/AMDGPU/early-inline.ll
    llvm/test/CodeGen/X86/indirect-branch-tracking-eh2.ll
    llvm/test/Transforms/InstCombine/volatile_store.ll
    llvm/test/Transforms/SimplifyCFG/trapping-load-unreachable.ll
    llvm/utils/unittest/googletest/src/gtest.cc

Removed: 
    compiler-rt/test/fuzzer/TrapTest.cpp
    compiler-rt/test/fuzzer/trap.test


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d33d48846b18b..a9d7388950331 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6744,13 +6744,13 @@ def ext_typecheck_indirection_through_void_pointer : ExtWarn<
   "ISO C++ does not allow indirection on operand of type %0">,
   InGroup<DiagGroup<"void-ptr-dereference">>;
 def warn_indirection_through_null : Warning<
-  "indirection of null pointer will be deleted, not trap">,
+  "indirection of non-volatile null pointer will be deleted, not trap">,
   InGroup<NullDereference>;
 def warn_binding_null_to_reference : Warning<
   "binding dereferenced null pointer to reference has undefined behavior">,
   InGroup<NullDereference>;
 def note_indirection_through_null : Note<
-  "consider using __builtin_trap()">;
+  "consider using __builtin_trap() or qualifying pointer with 'volatile'">;
 def warn_pointer_indirection_from_incompatible_type : Warning<
   "dereference of type %1 that was reinterpret_cast from type %0 has undefined "
   "behavior">,

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index d0efe4c02a1e3..a3a26d21422f0 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -533,16 +533,21 @@ ExprResult Sema::DefaultFunctionArrayConversion(Expr *E, bool Diagnose) {
 }
 
 static void CheckForNullPointerDereference(Sema &S, Expr *E) {
-  // Check to see if we are dereferencing a null pointer.
-  // If so, this is undefined behavior that the optimizer will delete,
-  // so warn about it. People sometimes try to use this to get a deterministic
-  // trap and are surprised by clang's behavior. This only handles the pattern
-  // "*null", which is a very syntactic check.
+  // Check to see if we are dereferencing a null pointer.  If so,
+  // and if not volatile-qualified, this is undefined behavior that the
+  // optimizer will delete, so warn about it.  People sometimes try to use this
+  // to get a deterministic trap and are surprised by clang's behavior.  This
+  // only handles the pattern "*null", which is a very syntactic check.
   const auto *UO = dyn_cast<UnaryOperator>(E->IgnoreParenCasts());
   if (UO && UO->getOpcode() == UO_Deref &&
       UO->getSubExpr()->getType()->isPointerType()) {
-    if (UO->getSubExpr()->IgnoreParenCasts()->isNullPointerConstant(
-            S.Context, Expr::NPC_ValueDependentIsNotNull)) {
+    const LangAS AS =
+        UO->getSubExpr()->getType()->getPointeeType().getAddressSpace();
+    if ((!isTargetAddressSpace(AS) ||
+         (isTargetAddressSpace(AS) && toTargetAddressSpace(AS) == 0)) &&
+        UO->getSubExpr()->IgnoreParenCasts()->isNullPointerConstant(
+            S.Context, Expr::NPC_ValueDependentIsNotNull) &&
+        !UO->getType().isVolatileQualified()) {
       S.DiagRuntimeBehavior(UO->getOperatorLoc(), UO,
                             S.PDiag(diag::warn_indirection_through_null)
                                 << UO->getSubExpr()->getSourceRange());

diff  --git a/clang/test/Analysis/NewDelete-checker-test.cpp b/clang/test/Analysis/NewDelete-checker-test.cpp
index 44a176a6eef8b..86df9d01dfb01 100644
--- a/clang/test/Analysis/NewDelete-checker-test.cpp
+++ b/clang/test/Analysis/NewDelete-checker-test.cpp
@@ -83,7 +83,7 @@ void testGlobalPointerPlacementNew() {
 //----- Other cases
 void testNewMemoryIsInHeap() {
   int *p = new int;
-  if (global != p) // condition is always true as 'p' wraps a heap region that
+  if (global != p) // condition is always true as 'p' wraps a heap region that 
                    // is 
diff erent from a region wrapped by 'global'
     global = p; // pointer escapes
 }
@@ -263,13 +263,13 @@ void testUninitFree() {
 void testUninitDeleteSink() {
   int *x;
   delete x; // expected-warning{{Argument to 'delete' is uninitialized}}
-  (*(volatile int *)0 = 1); // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
+  (*(volatile int *)0 = 1); // no warn
 }
 
 void testUninitDeleteArraySink() {
   int *x;
   delete[] x; // expected-warning{{Argument to 'delete[]' is uninitialized}}
-  (*(volatile int *)0 = 1); // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
+  (*(volatile int *)0 = 1); // no warn
 }
 
 namespace reference_count {

diff  --git a/clang/test/Analysis/conditional-path-notes.c b/clang/test/Analysis/conditional-path-notes.c
index df69488f2b2b6..5ef81d81a0fd4 100644
--- a/clang/test/Analysis/conditional-path-notes.c
+++ b/clang/test/Analysis/conditional-path-notes.c
@@ -59,7 +59,7 @@ void testDiagnosableBranch(int a) {
   if (a) {
     // expected-note at -1 {{Assuming 'a' is not equal to 0}}
     // expected-note at -2 {{Taking true branch}}
-    *(volatile int *)0 = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} expected-warning {{Dereference of null pointer}}
+    *(volatile int *)0 = 1; // expected-warning{{Dereference of null pointer}}
     // expected-note at -1 {{Dereference of null pointer}}
   }
 }
@@ -70,7 +70,7 @@ void testDiagnosableBranchLogical(int a, int b) {
     // expected-note at -2 {{Left side of '&&' is true}}
     // expected-note at -3 {{Assuming 'b' is not equal to 0}}
     // expected-note at -4 {{Taking true branch}}
-    *(volatile int *)0 = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} expected-warning {{Dereference of null pointer}}
+    *(volatile int *)0 = 1; // expected-warning{{Dereference of null pointer}}
     // expected-note at -1 {{Dereference of null pointer}}
   }
 }
@@ -79,7 +79,7 @@ void testNonDiagnosableBranchArithmetic(int a, int b) {
   if (a - b) {
     // expected-note at -1 {{Taking true branch}}
     // expected-note at -2 {{Assuming the condition is true}}
-    *(volatile int *)0 = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} expected-warning {{Dereference of null pointer}}
+    *(volatile int *)0 = 1; // expected-warning{{Dereference of null pointer}}
     // expected-note at -1 {{Dereference of null pointer}}
   }
 }

diff  --git a/clang/test/Analysis/cxx-for-range.cpp b/clang/test/Analysis/cxx-for-range.cpp
index 6fa38b4f4411a..034007813e4e4 100644
--- a/clang/test/Analysis/cxx-for-range.cpp
+++ b/clang/test/Analysis/cxx-for-range.cpp
@@ -9,13 +9,13 @@ void testLoop() {
     work();
     work();
     if (y == 2)
-      *(volatile int *)0 = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} expected-warning {{Dereference of null pointer}}
+      *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}}
     work();
     work();
     (void)y;
   }
 
-  *(volatile int *)0 = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
+  *(volatile int *)0 = 1; // no-warning
 }
 
 class MagicVector {
@@ -30,7 +30,7 @@ class MagicVector {
 
 MagicVector get(bool fail = false) {
   if (fail)
-    *(volatile int *)0 = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} expected-warning {{Dereference of null pointer}}
+    *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}}
   return MagicVector{};
 }
 
@@ -39,13 +39,13 @@ void testLoopOpaqueCollection() {
     work();
     work();
     if (y == 2)
-      *(volatile int *)0 = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} expected-warning {{Dereference of null pointer}}
+      *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}}
     work();
     work();
     (void)y;
   }
 
-  *(volatile int *)0 = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} expected-warning {{Dereference of null pointer}}
+  *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}}
 }
 
 
@@ -74,13 +74,13 @@ void testLoopOpaqueIterator() {
     work();
     work();
     if (y == 2)
-      *(volatile int *)0 = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} expected-warning {{Dereference of null pointer}}
+      *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}}
     work();
     work();
     (void)y;
   }
 
-  *(volatile int *)0 = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} expected-warning {{Dereference of null pointer}}
+  *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}}
 }
 
 
@@ -89,13 +89,13 @@ void testLoopErrorInRange() {
     work();
     work();
     if (y == 2)
-      *(volatile int *)0 = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
+      *(volatile int *)0 = 1; // no-warning
     work();
     work();
     (void)y;
   }
 
-  *(volatile int *)0 = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
+  *(volatile int *)0 = 1; // no-warning
 }
 
 void testForRangeInit() {

diff  --git a/clang/test/Analysis/diagnostics/no-prune-paths.c b/clang/test/Analysis/diagnostics/no-prune-paths.c
index 53042eee4a3ff..6e9e45766bf5a 100644
--- a/clang/test/Analysis/diagnostics/no-prune-paths.c
+++ b/clang/test/Analysis/diagnostics/no-prune-paths.c
@@ -16,5 +16,6 @@ void test() {
   // expected-note at -3 {{Returning from 'helper'}}
 #endif
 
-  *(volatile int *)0 = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} expected-warning {{Dereference of null pointer}} expected-note {{Dereference of null pointer}}
+  *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}}
+  // expected-note at -1 {{Dereference of null pointer}}
 }

diff  --git a/clang/test/Analysis/inlining/path-notes.cpp b/clang/test/Analysis/inlining/path-notes.cpp
index 4daa39e44d0c5..59726df37b9a3 100644
--- a/clang/test/Analysis/inlining/path-notes.cpp
+++ b/clang/test/Analysis/inlining/path-notes.cpp
@@ -278,7 +278,7 @@ namespace PR17746 {
   class Inner {
   public:
     ~Inner() {
-      *(volatile int *)0 = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} expected-warning {{Dereference of null pointer}}
+      *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}}
       // expected-note at -1 {{Dereference of null pointer}}
     }
   };

diff  --git a/clang/test/Analysis/objc-arc.m b/clang/test/Analysis/objc-arc.m
index b599fca13f5da..7127232f0de5c 100644
--- a/clang/test/Analysis/objc-arc.m
+++ b/clang/test/Analysis/objc-arc.m
@@ -119,7 +119,7 @@ void rdar9424882() {
   id x = [NSObject alloc]; // expected-warning {{Value stored to 'x' during its initialization is never read}}
 }
 
-// Test
+// Test 
 typedef const void *CFTypeRef;
 typedef const struct __CFString *CFStringRef;
 
@@ -208,7 +208,7 @@ void test_objc_arrays() {
 
 void rdar11059275(dispatch_object_t object) {
   NSObject *o = [[NSObject alloc] init];
-  dispatch_set_context(object, CFBridgingRetain(o)); // no-warning
+  dispatch_set_context(object, CFBridgingRetain(o)); // no-warning  
 }
 void rdar11059275_positive() {
   NSObject *o = [[NSObject alloc] init]; // expected-warning {{leak}}
@@ -227,7 +227,7 @@ id rdar14061675() {
   // ARC produces an implicit cast here. We need to make sure the combination
   // of that and the inlined call don't produce a spurious edge cycle.
   id result = rdar14061675_helper();
-  *(volatile int *)0 = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} expected-warning {{Dereference of null pointer}}
+  *(volatile int *)0 = 1; // expected-warning{{Dereference of null pointer}}
   return result;
 }
 

diff  --git a/clang/test/Analysis/objc-for.m b/clang/test/Analysis/objc-for.m
index cdbb069ac9539..d4a04c1c3e80b 100644
--- a/clang/test/Analysis/objc-for.m
+++ b/clang/test/Analysis/objc-for.m
@@ -86,7 +86,7 @@ void testNonNil(id a, id b) {
   if (b != nil)
     return;
   for (id x in b)
-    *(volatile int *)0 = 1;      // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
+    *(volatile int *)0 = 1; // no-warning
   clang_analyzer_eval(b != nil); // expected-warning{{FALSE}}
 }
 

diff  --git a/clang/test/Analysis/taint-generic.c b/clang/test/Analysis/taint-generic.c
index dc1f2d4330f35..2cbd580168ba9 100644
--- a/clang/test/Analysis/taint-generic.c
+++ b/clang/test/Analysis/taint-generic.c
@@ -338,7 +338,7 @@ void constraintManagerShouldTreatAsOpaque(int rhs) {
   if (i < rhs)
     return;
   if (i < rhs)
-    *(volatile int *)0; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
+    *(volatile int *) 0; // no-warning
 }
 
 

diff  --git a/clang/test/Analysis/valist-uninitialized.c b/clang/test/Analysis/valist-uninitialized.c
index 8ed05d23ab1ce..003592997eab8 100644
--- a/clang/test/Analysis/valist-uninitialized.c
+++ b/clang/test/Analysis/valist-uninitialized.c
@@ -145,7 +145,7 @@ void is_sink(int fst, ...) {
   va_list va;
   va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}}
   // expected-note at -1{{va_end() is called on an uninitialized va_list}}
-  *((volatile int *)0) = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
+  *((volatile int *)0) = 1;
 }
 
 // NOTE: this is invalid, as the man page of va_end requires that "Each invocation of va_start()

diff  --git a/clang/test/CodeGenOpenCL/convergent.cl b/clang/test/CodeGenOpenCL/convergent.cl
index a69b3d784e8c9..1905d7dd81aab 100644
--- a/clang/test/CodeGenOpenCL/convergent.cl
+++ b/clang/test/CodeGenOpenCL/convergent.cl
@@ -3,10 +3,11 @@
 
 // This is initially assumed convergent, but can be deduced to not require it.
 
-// CHECK-LABEL: define{{.*}} spir_func void @non_convfun(i32* %p) local_unnamed_addr #0
+// CHECK-LABEL: define{{.*}} spir_func void @non_convfun() local_unnamed_addr #0
 // CHECK: ret void
 __attribute__((noinline))
-void non_convfun(volatile int* p) {
+void non_convfun(void) {
+  volatile int* p;
   *p = 0;
 }
 
@@ -27,29 +28,29 @@ void g(void);
 //      non_convfun();
 //    }
 //
-// CHECK-LABEL: define{{.*}} spir_func void @test_merge_if(i32 %a, i32* %p) local_unnamed_addr #1 {
+// CHECK-LABEL: define{{.*}} spir_func void @test_merge_if(i32 %a) local_unnamed_addr #1 {
 // CHECK: %[[tobool:.+]] = icmp eq i32 %a, 0
 // CHECK: br i1 %[[tobool]], label %[[if_end3_critedge:.+]], label %[[if_then:.+]]
 
 // CHECK: [[if_then]]:
 // CHECK: tail call spir_func void @f()
-// CHECK: tail call spir_func void @non_convfun(i32* %p)
+// CHECK: tail call spir_func void @non_convfun()
 // CHECK: tail call spir_func void @g()
 
 // CHECK: br label %[[if_end3:.+]]
 
 // CHECK: [[if_end3_critedge]]:
-// CHECK: tail call spir_func void @non_convfun(i32* %p)
+// CHECK: tail call spir_func void @non_convfun()
 // CHECK: br label %[[if_end3]]
 
 // CHECK: [[if_end3]]:
 // CHECK: ret void
 
-void test_merge_if(int a, volatile int* p) {
+void test_merge_if(int a) {
   if (a) {
     f();
   }
-  non_convfun(p);
+  non_convfun();
   if (a) {
     g();
   }

diff  --git a/clang/test/Parser/expressions.c b/clang/test/Parser/expressions.c
index bd0ef87854266..64b44470f7e74 100644
--- a/clang/test/Parser/expressions.c
+++ b/clang/test/Parser/expressions.c
@@ -39,13 +39,14 @@ void test_sizeof(){
 
 // PR3418
 int test_leading_extension() {
-  __extension__(*(char *)0) = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
+  __extension__ (*(char*)0) = 1; // expected-warning {{indirection of non-volatile null pointer}} \
+                                 // expected-note {{consider using __builtin_trap}}
   return 0;
 }
 
 // PR3972
 int test5(int);
-int test6(void) {
+int test6(void) { 
   return test5(      // expected-note {{to match}}
                test5(1)
                  ; // expected-error {{expected ')'}}

diff  --git a/clang/test/Sema/exprs.c b/clang/test/Sema/exprs.c
index a5ed610d74bff..4e144041acae6 100644
--- a/clang/test/Sema/exprs.c
+++ b/clang/test/Sema/exprs.c
@@ -22,7 +22,7 @@ void radar9171946() {
 
 int test_pr8876() {
   PR8876(0); // no-warning
-  PR8876_pos(0); // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
+  PR8876_pos(0); // expected-warning{{indirection of non-volatile null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap() or qualifying pointer with 'volatile'}}
   return 0;
 }
 
@@ -31,7 +31,7 @@ int test_pr8876() {
 void pr8183(unsigned long long test)
 {
   (void)((((void*)0)) && (*((unsigned long long*)(((void*)0))) = ((unsigned long long)((test)) % (unsigned long long)((1000000000)))));  // no-warning
-  (*((unsigned long long *)(((void *)0))) = ((unsigned long long)((test)) % (unsigned long long)((1000000000))));                        // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
+  (*((unsigned long long*)(((void*)0))) = ((unsigned long long)((test)) % (unsigned long long)((1000000000)))); // expected-warning {{indirection of non-volatile null pointer will be deleted, not trap}} expected-note {{consider using __builtin_trap() or qualifying pointer with 'volatile'}}
 }
 
 // PR1966
@@ -59,7 +59,7 @@ void test4() {
 
       var =+5;  // no warning when the subexpr of the unary op has no space before it.
       var =-5;
-
+  
 #define FIVE 5
       var=-FIVE;  // no warning with macros.
       var=-FIVE;
@@ -159,7 +159,7 @@ void test17(int x) {
   x = x % 0;  // expected-warning {{remainder by zero is undefined}}
   x /= 0;  // expected-warning {{division by zero is undefined}}
   x %= 0;  // expected-warning {{remainder by zero is undefined}}
-
+  
   x = sizeof(x/0);  // no warning.
 }
 
@@ -187,17 +187,21 @@ void test18(int b) {
 typedef int __attribute__((address_space(256))) int_AS256;
 // PR7569
 void test19() {
-  *(int *)0 = 0;                                     // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
-  *(volatile int *)0 = 0;                            // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
-  *(int __attribute__((address_space(256))) *)0 = 0; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
-  *(int __attribute__((address_space(0))) *)0 = 0;   // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
-  *(int_AS256 *)0 = 0;                               // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
+  *(int *)0 = 0;                                     // expected-warning {{indirection of non-volatile null pointer}} \
+                  // expected-note {{consider using __builtin_trap}}
+  *(volatile int *)0 = 0;                            // Ok.
+  *(int __attribute__((address_space(256))) *)0 = 0; // Ok.
+  *(int __attribute__((address_space(0))) *)0 = 0;   // expected-warning {{indirection of non-volatile null pointer}} \
+                     // expected-note {{consider using __builtin_trap}}
+  *(int_AS256 *)0 = 0;                               // Ok.
 
   // rdar://9269271
-  int x = *(int *)0;                                                                          // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
-  int x2 = *(volatile int *)0;                                                                // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
-  int x3 = *(int __attribute__((address_space(0))) *)0;                                       // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
-  int x4 = *(int_AS256 *)0;                                                                   // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
+  int x = *(int *)0;                                                                          // expected-warning {{indirection of non-volatile null pointer}} \
+                     // expected-note {{consider using __builtin_trap}}
+  int x2 = *(volatile int *)0;                                                                // Ok.
+  int x3 = *(int __attribute__((address_space(0))) *)0;                                       // expected-warning {{indirection of non-volatile null pointer}} \
+                     // expected-note {{consider using __builtin_trap}}
+  int x4 = *(int_AS256 *)0;                                                                   // Ok.
   int *p = &(*(int *)0);                                                                      // Ok.
   int_AS256 *p1 = &(*(int __attribute__((address_space(256))) *)0);                           // Ok.
   int __attribute__((address_space(0))) *p2 = &(*(int __attribute__((address_space(0))) *)0); // Ok.
@@ -209,7 +213,7 @@ int test20(int x) {
                  // expected-note {{remove constant to silence this warning}}
 
   return x && sizeof(int) == 4;  // no warning, RHS is logical op.
-
+  
   // no warning, this is an idiom for "true" in old C style.
   return x && (signed char)1;
 

diff  --git a/clang/test/Sema/offsetof.c b/clang/test/Sema/offsetof.c
index 5cd8e67938f6d..b5e392dda82d3 100644
--- a/clang/test/Sema/offsetof.c
+++ b/clang/test/Sema/offsetof.c
@@ -5,9 +5,10 @@
 typedef struct P { int i; float f; } PT;
 struct external_sun3_core
 {
-  unsigned c_regs;
+ unsigned c_regs; 
 
   PT  X[100];
+  
 };
 
 void swap()
@@ -15,30 +16,24 @@ void swap()
   int x;
   x = offsetof(struct external_sun3_core, c_regs);
   x = __builtin_offsetof(struct external_sun3_core, X[42].f);
-
+  
   x = __builtin_offsetof(struct external_sun3_core, X[42].f2);  // expected-error {{no member named 'f2'}}
   x = __builtin_offsetof(int, X[42].f2);  // expected-error {{offsetof requires struct}}
-
+  
   int a[__builtin_offsetof(struct external_sun3_core, X) == 4 ? 1 : -1];
   int b[__builtin_offsetof(struct external_sun3_core, X[42]) == 340 ? 1 : -1];
   int c[__builtin_offsetof(struct external_sun3_core, X[42].f2) == 344 ? 1 : -1];  // expected-error {{no member named 'f2'}}
-}
+}    
 
 extern int f();
 
-struct s1 {
-  int a;
-};
+struct s1 { int a; }; 
 int v1 = offsetof (struct s1, a) == 0 ? 0 : f();
 
-struct s2 {
-  int a;
-};
+struct s2 { int a; }; 
 int v2 = (int)(&((struct s2 *) 0)->a) == 0 ? 0 : f();
 
-struct s3 {
-  int a;
-};
+struct s3 { int a; }; 
 int v3 = __builtin_offsetof(struct s3, a) == 0 ? 0 : f();
 
 // PR3396
@@ -72,6 +67,6 @@ typedef struct Array { int array[1]; } Array;
 int test4 = __builtin_offsetof(Array, array);
 
 int test5() {
-  return __builtin_offsetof(Array, array[*(int *)0]); // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
+  return __builtin_offsetof(Array, array[*(int*)0]); // expected-warning{{indirection of non-volatile null pointer}} expected-note{{__builtin_trap}}
 }
 

diff  --git a/clang/test/SemaCXX/member-pointer.cpp b/clang/test/SemaCXX/member-pointer.cpp
index e612fda5c09bc..f3adb95977a14 100644
--- a/clang/test/SemaCXX/member-pointer.cpp
+++ b/clang/test/SemaCXX/member-pointer.cpp
@@ -47,7 +47,7 @@ void f() {
 
   // Conversion to member of base.
   pdi1 = pdid; // expected-error {{assigning to 'int A::*' from incompatible type 'int D::*'}}
-
+  
   // Comparisons
   int (A::*pf2)(int, int);
   int (D::*pf3)(int, int) = 0;
@@ -106,7 +106,7 @@ void h() {
   int i = phm->*pi;
   (void)&(hm.*pi);
   (void)&(phm->*pi);
-  (void)&((&hm)->*pi);
+  (void)&((&hm)->*pi); 
 
   void (HasMembers::*pf)() = &HasMembers::f;
   (hm.*pf)();
@@ -204,7 +204,7 @@ namespace rdar8358512 {
 
     static void stat();
     static void stat(int);
-
+    
     template <typename T> struct Test0 {
       void test() {
         bind(&nonstat); // expected-error {{no matching function for call}}
@@ -295,8 +295,8 @@ namespace PR9973 {
     { call(u); } // expected-note{{in instantiation of}}
   };
 
-  template <class R, class T>
-  dm<R, T> mem_fn(R T::*);
+  template<class R, class T> 
+  dm<R, T> mem_fn(R T::*) ;
 
   struct test
   { int nullary_v(); };
@@ -312,13 +312,14 @@ namespace test8 {
   struct A { int foo; };
   int test1() {
     // Verify that we perform (and check) an lvalue conversion on the operands here.
-    return (*((A **)0))          // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
-               ->**(int A::**)0; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
+    return (*((A**) 0)) // expected-warning {{indirection of non-volatile null pointer will be deleted}} expected-note {{consider}}
+             ->**(int A::**) 0; // expected-warning {{indirection of non-volatile null pointer will be deleted}} expected-note {{consider}}
   }
 
   int test2() {
     // Verify that we perform (and check) an lvalue conversion on the operands here.
     // TODO: the .* should itself warn about being a dereference of null.
-    return (*((A *)0)).**(int A::**)0; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}}
+    return (*((A*) 0))
+             .**(int A::**) 0; // expected-warning {{indirection of non-volatile null pointer will be deleted}} expected-note {{consider}}
   }
 }

diff  --git a/compiler-rt/test/asan/TestCases/Windows/dll_control_c.cpp b/compiler-rt/test/asan/TestCases/Windows/dll_control_c.cpp
index f7c81e0065e6a..e30276325dbdb 100644
--- a/compiler-rt/test/asan/TestCases/Windows/dll_control_c.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/dll_control_c.cpp
@@ -12,7 +12,7 @@
 static void __declspec(noinline) CrashOnProcessDetach() {
   printf("CrashOnProcessDetach\n");
   fflush(stdout);
-  __builtin_trap();
+  *static_cast<volatile int *>(0) = 0x356;
 }
 
 bool g_is_child = false;

diff  --git a/compiler-rt/test/fuzzer/TrapTest.cpp b/compiler-rt/test/fuzzer/NullDerefTest.cpp
similarity index 85%
rename from compiler-rt/test/fuzzer/TrapTest.cpp
rename to compiler-rt/test/fuzzer/NullDerefTest.cpp
index d3e7c2b0d89af..32a3661417234 100644
--- a/compiler-rt/test/fuzzer/TrapTest.cpp
+++ b/compiler-rt/test/fuzzer/NullDerefTest.cpp
@@ -5,10 +5,11 @@
 // Simple test for a fuzzer. The fuzzer must find the string "Hi!".
 #include <cstddef>
 #include <cstdint>
-#include <cstdio>
 #include <cstdlib>
+#include <cstdio>
 
 static volatile int Sink;
+static volatile int *Null = 0;
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
   if (Size > 0 && Data[0] == 'H') {
@@ -16,10 +17,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
     if (Size > 1 && Data[1] == 'i') {
       Sink = 2;
       if (Size > 2 && Data[2] == '!') {
-        printf("Found the target, trapping\n");
-        __builtin_trap();
+        printf("Found the target, dereferencing NULL\n");
+        *Null = 1;
       }
     }
   }
   return 0;
 }
+

diff  --git a/compiler-rt/test/fuzzer/ShallowOOMDeepCrash.cpp b/compiler-rt/test/fuzzer/ShallowOOMDeepCrash.cpp
index 680d940550d6c..197fffa5e007c 100644
--- a/compiler-rt/test/fuzzer/ShallowOOMDeepCrash.cpp
+++ b/compiler-rt/test/fuzzer/ShallowOOMDeepCrash.cpp
@@ -16,7 +16,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
     Sink = new int[1 << 28]; // instant OOM with -rss_limit_mb=128.
   if (Size >= 4 && Data[0] == 'F' && Data[1] == 'U' && Data[2] == 'Z' &&
       Data[3] == 'Z')  // a bit deeper crash.
-    __builtin_trap();
+    *Zero = 42;
   return 0;
 }
 

diff  --git a/compiler-rt/test/fuzzer/coverage.test b/compiler-rt/test/fuzzer/coverage.test
index cf6b4d8e8b4f3..07a10ba169f01 100644
--- a/compiler-rt/test/fuzzer/coverage.test
+++ b/compiler-rt/test/fuzzer/coverage.test
@@ -2,14 +2,14 @@
 UNSUPPORTED: windows
 # FIXME: CreatePCArray() emits PLT stub addresses for entry blocks, which are ignored by TracePC::PrintCoverage().
 XFAIL: s390x
-RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable  %S/TrapTest.cpp -o %t-TrapTest
+RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable  %S/NullDerefTest.cpp -o %t-NullDerefTest
 RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/DSO1.cpp -fPIC %ld_flags_rpath_so1 -O0 -shared -o %dynamiclib1
 RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/DSO2.cpp -fPIC %ld_flags_rpath_so2 -O0 -shared -o %dynamiclib2
 RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/DSOTestMain.cpp %S/DSOTestExtra.cpp %ld_flags_rpath_exe1 %ld_flags_rpath_exe2 -o %t-DSOTest
 
 CHECK: COVERAGE:
-CHECK: COVERED_FUNC: {{.*}}LLVMFuzzerTestOneInput {{.*}}TrapTest.cpp:13
-RUN: not %run %t-TrapTest -print_coverage=1 2>&1 | FileCheck %s
+CHECK: COVERED_FUNC: {{.*}}LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:14
+RUN: not %run %t-NullDerefTest -print_coverage=1 2>&1 | FileCheck %s
 
 RUN: %run %t-DSOTest -print_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO
 DSO: COVERAGE:

diff  --git a/compiler-rt/test/fuzzer/fork.test b/compiler-rt/test/fuzzer/fork.test
index e78541b0e8ca0..6e76fe7f2b06a 100644
--- a/compiler-rt/test/fuzzer/fork.test
+++ b/compiler-rt/test/fuzzer/fork.test
@@ -12,7 +12,7 @@ RUN: %cpp_compiler %S/OutOfMemoryTest.cpp -o %t-OutOfMemoryTest
 RUN: not %run %t-OutOfMemoryTest -fork=1 -ignore_ooms=0  -rss_limit_mb=128 2>&1 | FileCheck %s --check-prefix=OOM
 
 # access-violation is the error thrown on Windows. Address will be smaller on i386.
-CRASH: == ERROR: libFuzzer: deadly signal
+CRASH: {{SEGV|access-violation}} on unknown address 0x00000000
 RUN: %cpp_compiler %S/ShallowOOMDeepCrash.cpp -o %t-ShallowOOMDeepCrash
 RUN: not %run %t-ShallowOOMDeepCrash -fork=1 -rss_limit_mb=128 2>&1 | FileCheck %s --check-prefix=CRASH
 

diff  --git a/compiler-rt/test/fuzzer/fuzzer-seed.test b/compiler-rt/test/fuzzer/fuzzer-seed.test
index 6ca24c91f075a..b6343ffa3dd73 100644
--- a/compiler-rt/test/fuzzer/fuzzer-seed.test
+++ b/compiler-rt/test/fuzzer/fuzzer-seed.test
@@ -1,4 +1,4 @@
-RUN: %cpp_compiler %S/TrapTest.cpp -o %t-SimpleCmpTest
+RUN: %cpp_compiler %S/NullDerefTest.cpp -o %t-SimpleCmpTest
 RUN: %run %t-SimpleCmpTest -seed=-1 -runs=0 2>&1 | FileCheck %s --check-prefix=CHECK_SEED_MINUS_ONE
 CHECK_SEED_MINUS_ONE: Seed: 4294967295
 

diff  --git a/compiler-rt/test/fuzzer/fuzzer-segv.test b/compiler-rt/test/fuzzer/fuzzer-segv.test
index a658b28f68ca7..7ae9049e15a6a 100644
--- a/compiler-rt/test/fuzzer/fuzzer-segv.test
+++ b/compiler-rt/test/fuzzer/fuzzer-segv.test
@@ -1,6 +1,8 @@
-RUN: %cpp_compiler %S/TrapTest.cpp -o %t-TrapTest
-RUN: %env_asan_opts=handle_segv=0 not %run %t-TrapTest 2>&1 | FileCheck %s --check-prefix=LIBFUZZER_OWN_SEGV_HANDLER
-RUN: %env_asan_opts=handle_segv=1 not %run %t-TrapTest 2>&1 | FileCheck %s --check-prefix=LIBFUZZER_OWN_SEGV_HANDLER
+RUN: %cpp_compiler %S/NullDerefTest.cpp -o %t-NullDerefTest
+RUN: %env_asan_opts=handle_segv=0 not %run %t-NullDerefTest 2>&1 | FileCheck %s --check-prefix=LIBFUZZER_OWN_SEGV_HANDLER
 LIBFUZZER_OWN_SEGV_HANDLER: == ERROR: libFuzzer: deadly signal
 LIBFUZZER_OWN_SEGV_HANDLER: SUMMARY: libFuzzer: deadly signal
 LIBFUZZER_OWN_SEGV_HANDLER: Test unit written to ./crash-
+
+RUN: %env_asan_opts=handle_segv=1 not %run %t-NullDerefTest 2>&1 | FileCheck %s --check-prefix=LIBFUZZER_ASAN_SEGV_HANDLER
+LIBFUZZER_ASAN_SEGV_HANDLER: ERROR: AddressSanitizer: {{SEGV|access-violation}} on unknown address

diff  --git a/compiler-rt/test/fuzzer/fuzzer-singleinputs.test b/compiler-rt/test/fuzzer/fuzzer-singleinputs.test
index 67b3ba9dd922a..704f9caa57f94 100644
--- a/compiler-rt/test/fuzzer/fuzzer-singleinputs.test
+++ b/compiler-rt/test/fuzzer/fuzzer-singleinputs.test
@@ -1,7 +1,7 @@
-RUN: %cpp_compiler %S/TrapTest.cpp -o %t-TrapTest
+RUN: %cpp_compiler %S/NullDerefTest.cpp -o %t-NullDerefTest
 RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-SimpleTest
 
-RUN: not %run %t-TrapTest %S/hi.txt 2>&1 | FileCheck %s --check-prefix=SingleInput
+RUN: not %run %t-NullDerefTest %S/hi.txt 2>&1 | FileCheck %s --check-prefix=SingleInput
 SingleInput-NOT: Test unit written to ./crash-
 
 RUN: rm -rf  %tmp/SINGLE_INPUTS

diff  --git a/compiler-rt/test/fuzzer/minimize_crash.test b/compiler-rt/test/fuzzer/minimize_crash.test
index 33c9174920e93..de44b8747e04c 100644
--- a/compiler-rt/test/fuzzer/minimize_crash.test
+++ b/compiler-rt/test/fuzzer/minimize_crash.test
@@ -1,11 +1,11 @@
-RUN: %cpp_compiler %S/TrapTest.cpp -o %t-TrapTest
+RUN: %cpp_compiler %S/NullDerefTest.cpp -o %t-NullDerefTest
 RUN: %cpp_compiler %S/SingleByteInputTest.cpp -o %t-SingleByteInputTest
 RUN: mkdir -p %t.dir
 
 RUN: echo 'Hi!rv349f34t3gg' > %t.dir/not_minimal_crash
-RUN: %run %t-TrapTest -minimize_crash=1 %t.dir/not_minimal_crash -max_total_time=2 2>&1 | FileCheck %s
+RUN: %run %t-NullDerefTest -minimize_crash=1 %t.dir/not_minimal_crash -max_total_time=2 2>&1 | FileCheck %s
 CHECK: CRASH_MIN: failed to minimize beyond {{.*}}minimized-from{{.*}} (3 bytes), exiting
-RUN: %run %t-TrapTest -minimize_crash=1 %t.dir/not_minimal_crash -max_total_time=2 -exact_artifact_path=%t.exact_minimized_path 2>&1 | FileCheck %s --check-prefix=CHECK_EXACT
+RUN: %run %t-NullDerefTest -minimize_crash=1 %t.dir/not_minimal_crash -max_total_time=2 -exact_artifact_path=%t.exact_minimized_path 2>&1 | FileCheck %s --check-prefix=CHECK_EXACT
 CHECK_EXACT: CRASH_MIN: failed to minimize beyond {{.*}}exact_minimized_path{{.*}} (3 bytes), exiting
 RUN: rm %t.dir/not_minimal_crash %t.exact_minimized_path
 

diff  --git a/compiler-rt/test/fuzzer/null-deref.test b/compiler-rt/test/fuzzer/null-deref.test
new file mode 100644
index 0000000000000..31eb5990da33d
--- /dev/null
+++ b/compiler-rt/test/fuzzer/null-deref.test
@@ -0,0 +1,10 @@
+RUN: %cpp_compiler %S/NullDerefTest.cpp -o %t-NullDerefTest
+
+RUN: not %run %t-NullDerefTest                  2>&1 | FileCheck %s --check-prefix=NullDerefTest
+RUN: not %run %t-NullDerefTest -close_fd_mask=3 2>&1 | FileCheck %s --check-prefix=NullDerefTest
+NullDerefTest: ERROR: AddressSanitizer: {{SEGV|access-violation}} on unknown address
+NullDerefTest: Test unit written to ./crash-
+RUN: not %run %t-NullDerefTest  -artifact_prefix=ZZZ 2>&1 | FileCheck %s --check-prefix=NullDerefTestPrefix
+NullDerefTestPrefix: Test unit written to ZZZcrash-
+RUN: not %run %t-NullDerefTest  -artifact_prefix=ZZZ -exact_artifact_path=FOOBAR 2>&1 | FileCheck %s --check-prefix=NullDerefTestExactPath
+NullDerefTestExactPath: Test unit written to FOOBAR

diff  --git a/compiler-rt/test/fuzzer/trap.test b/compiler-rt/test/fuzzer/trap.test
deleted file mode 100644
index c5944aeddbe5e..0000000000000
--- a/compiler-rt/test/fuzzer/trap.test
+++ /dev/null
@@ -1,10 +0,0 @@
-RUN: %cpp_compiler %S/TrapTest.cpp -o %t-TrapTest
-
-RUN: not %run %t-TrapTest                  2>&1 | FileCheck %s --check-prefix=TrapTest
-RUN: not %run %t-TrapTest -close_fd_mask=3 2>&1 | FileCheck %s --check-prefix=TrapTest
-TrapTest: SUMMARY: libFuzzer: deadly signal
-TrapTest: Test unit written to ./crash-
-RUN: not %run %t-TrapTest  -artifact_prefix=ZZZ 2>&1 | FileCheck %s --check-prefix=TrapTestPrefix
-TrapTestPrefix: Test unit written to ZZZcrash-
-RUN: not %run %t-TrapTest  -artifact_prefix=ZZZ -exact_artifact_path=FOOBAR 2>&1 | FileCheck %s --check-prefix=TrapTestExactPath
-TrapTestExactPath: Test unit written to FOOBAR

diff  --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/signal_line.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/signal_line.cpp
index 0da531e557cae..208ece3e05af4 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Linux/signal_line.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/signal_line.cpp
@@ -14,11 +14,13 @@
 int main(int argc, char **argv) {
   int n = atoi(argv[1]);
 
-  *((volatile int *)(n - 1)) = __LINE__;
+  if (n == 1)
+    *((volatile int *)0x0) = __LINE__;
+  // CHECK1: #{{[0-9]+ .*}}main {{.*}}signal_line.cpp:[[@LINE-1]]:[[TAB:[0-9]+]]
+  // CHECK1: SUMMARY: [[SAN]]: SEGV {{.*}}signal_line.cpp:[[@LINE-2]]:[[TAB]] in main
 
-  // CHECK1: #{{[0-9]+ .*}}main {{.*}}signal_line.cpp:[[@LINE-2]]:[[TAB:[0-9]+]]
-  // CHECK1: SUMMARY: [[SAN]]: SEGV {{.*}}signal_line.cpp:[[@LINE-3]]:[[TAB]] in main
-
-  // CHECK2: #{{[0-9]+ .*}}main {{.*}}signal_line.cpp:[[@LINE-5]]:[[TAB:[0-9]+]]
-  // CHECK2: SUMMARY: [[SAN]]: SEGV {{.*}}signal_line.cpp:[[@LINE-6]]:[[TAB]] in main
+  if (n == 2)
+    *((volatile int *)0x1) = __LINE__;
+  // CHECK2: #{{[0-9]+ .*}}main {{.*}}signal_line.cpp:[[@LINE-1]]:[[TAB:[0-9]+]]
+  // CHECK2: SUMMARY: [[SAN]]: SEGV {{.*}}signal_line.cpp:[[@LINE-2]]:[[TAB]] in main
 }

diff  --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 7e4b7d0b636c7..e00bcf8826d0d 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2888,6 +2888,14 @@ Instruction *InstCombinerImpl::visitUnreachableInst(UnreachableInst &I) {
     // Otherwise, this instruction can be freely erased,
     // even if it is not side-effect free.
 
+    // Temporarily disable removal of volatile stores preceding unreachable,
+    // pending a potential LangRef change permitting volatile stores to trap.
+    // TODO: Either remove this code, or properly integrate the check into
+    // isGuaranteedToTransferExecutionToSuccessor().
+    if (auto *SI = dyn_cast<StoreInst>(Prev))
+      if (SI->isVolatile())
+        return nullptr; // Can not drop this instruction. We're done here.
+
     // A value may still have uses before we process it here (for example, in
     // another unreachable block), so convert those to poison.
     replaceInstUsesWith(*Prev, PoisonValue::get(Prev->getType()));

diff  --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 31b4c0ceaa9c6..4bc3747b973b1 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -2302,6 +2302,9 @@ static bool markAliveBlocks(Function &F,
         // that they should be changed to unreachable by passes that can't
         // modify the CFG.
 
+        // Don't touch volatile stores.
+        if (SI->isVolatile()) continue;
+
         Value *Ptr = SI->getOperand(1);
 
         if (isa<UndefValue>(Ptr) ||

diff  --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index fa4b8c9a28ce5..f08ab18b15b20 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -4672,6 +4672,14 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) {
     // Otherwise, this instruction can be freely erased,
     // even if it is not side-effect free.
 
+    // Temporarily disable removal of volatile stores preceding unreachable,
+    // pending a potential LangRef change permitting volatile stores to trap.
+    // TODO: Either remove this code, or properly integrate the check into
+    // isGuaranteedToTransferExecutionToSuccessor().
+    if (auto *SI = dyn_cast<StoreInst>(&*BBI))
+      if (SI->isVolatile())
+        break; // Can not drop this instruction. We're done here.
+
     // Note that deleting EH's here is in fact okay, although it involves a bit
     // of subtle reasoning. If this inst is an EH, all the predecessors of this
     // block will be the unwind edges of Invoke/CatchSwitch/CleanupReturn,

diff  --git a/llvm/test/CodeGen/AArch64/branch-relax-alignment.ll b/llvm/test/CodeGen/AArch64/branch-relax-alignment.ll
index 9c1e569d66404..c1d824b9b79e5 100644
--- a/llvm/test/CodeGen/AArch64/branch-relax-alignment.ll
+++ b/llvm/test/CodeGen/AArch64/branch-relax-alignment.ll
@@ -4,7 +4,7 @@
 ; Long branch is assumed because the block has a higher alignment
 ; requirement than the function.
 
-define i32 @invert_bcc_block_align_higher_func(i32 %x, i32 %y, i32* %dst) align 4 #0 {
+define i32 @invert_bcc_block_align_higher_func(i32 %x, i32 %y) align 4 #0 {
 ; CHECK-LABEL: invert_bcc_block_align_higher_func:
 ; CHECK:       ; %bb.0: ; %common.ret
 ; CHECK-NEXT:    cmp w0, w1
@@ -12,17 +12,17 @@ define i32 @invert_bcc_block_align_higher_func(i32 %x, i32 %y, i32* %dst) align
 ; CHECK-NEXT:    mov w9, #42
 ; CHECK-NEXT:    cset w0, ne
 ; CHECK-NEXT:    csel w8, w9, w8, eq
-; CHECK-NEXT:    str w8, [x2]
+; CHECK-NEXT:    str w8, [x8]
 ; CHECK-NEXT:    ret
   %1 = icmp eq i32 %x, %y
   br i1 %1, label %bb1, label %bb2
 
 bb2:
-  store volatile i32 9, i32* %dst
+  store volatile i32 9, i32* undef
   ret i32 1
 
 bb1:
-  store volatile i32 42, i32* %dst
+  store volatile i32 42, i32* undef
   ret i32 0
 }
 

diff  --git a/llvm/test/CodeGen/AArch64/branch-relax-bcc.ll b/llvm/test/CodeGen/AArch64/branch-relax-bcc.ll
index 377cb2c556968..3f9be3a283018 100644
--- a/llvm/test/CodeGen/AArch64/branch-relax-bcc.ll
+++ b/llvm/test/CodeGen/AArch64/branch-relax-bcc.ll
@@ -1,28 +1,27 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc -mtriple=aarch64-apple-darwin -aarch64-bcc-offset-bits=3 < %s | FileCheck %s
 
-define i32 @invert_bcc(float %x, float %y, i32* %dst0, i32* %dst1) #0 {
+define i32 @invert_bcc(float %x, float %y) #0 {
 ; CHECK-LABEL: invert_bcc:
 ; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w0, wzr
 ; CHECK-NEXT:    fcmp s0, s1
-; CHECK-NEXT:    b.ne LBB0_3
+; CHECK-NEXT:    mov w8, #42
+; CHECK-NEXT:    b.pl LBB0_3
 ; CHECK-NEXT:    b LBB0_2
 ; CHECK-NEXT:  LBB0_3:
-; CHECK-NEXT:    b.vc LBB0_1
-; CHECK-NEXT:    b LBB0_2
-; CHECK-NEXT:  LBB0_1: ; %bb2
+; CHECK-NEXT:    b.gt LBB0_2
+; CHECK-NEXT:  ; %bb.1: ; %common.ret
+; CHECK-NEXT:    str w8, [x8]
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  LBB0_2: ; %bb2
+; CHECK-NEXT:    mov w0, #1
 ; CHECK-NEXT:    mov w8, #9
 ; CHECK-NEXT:    ; InlineAsm Start
 ; CHECK-NEXT:    nop
 ; CHECK-NEXT:    nop
 ; CHECK-NEXT:    ; InlineAsm End
-; CHECK-NEXT:    str w8, [x0]
-; CHECK-NEXT:    mov w0, #1
-; CHECK-NEXT:    ret
-; CHECK-NEXT:  LBB0_2: ; %bb1
-; CHECK-NEXT:    mov w0, wzr
-; CHECK-NEXT:    mov w8, #42
-; CHECK-NEXT:    str w8, [x1]
+; CHECK-NEXT:    str w8, [x8]
 ; CHECK-NEXT:    ret
   %1 = fcmp ueq float %x, %y
   br i1 %1, label %bb1, label %bb2
@@ -32,11 +31,11 @@ bb2:
     "nop
      nop",
     ""() #0
-  store volatile i32 9, i32* %dst0
+  store volatile i32 9, i32* undef
   ret i32 1
 
 bb1:
-  store volatile i32 42, i32* %dst1
+  store volatile i32 42, i32* undef
   ret i32 0
 }
 

diff  --git a/llvm/test/CodeGen/AMDGPU/early-inline.ll b/llvm/test/CodeGen/AMDGPU/early-inline.ll
index 4a3731bf4689f..eb533048e8d2d 100644
--- a/llvm/test/CodeGen/AMDGPU/early-inline.ll
+++ b/llvm/test/CodeGen/AMDGPU/early-inline.ll
@@ -16,18 +16,18 @@ entry:
 ; CHECK: mul i32
 ; CHECK-NOT: call i32
 
-define amdgpu_kernel void @caller(i32 %x, i32 addrspace(1)* %dst) {
+define amdgpu_kernel void @caller(i32 %x) {
 entry:
   %res = call i32 @callee(i32 %x)
-  store volatile i32 %res, i32 addrspace(1)* %dst
+  store volatile i32 %res, i32 addrspace(1)* undef
   ret void
 }
 
 ; CHECK-LABEL: @alias_caller(
 ; CHECK-NOT: call
-define amdgpu_kernel void @alias_caller(i32 %x, i32 addrspace(1)* %dst) {
+define amdgpu_kernel void @alias_caller(i32 %x) {
 entry:
   %res = call i32 @c_alias(i32 %x)
-  store volatile i32 %res, i32 addrspace(1)* %dst
+  store volatile i32 %res, i32 addrspace(1)* undef
   ret void
 }

diff  --git a/llvm/test/CodeGen/X86/indirect-branch-tracking-eh2.ll b/llvm/test/CodeGen/X86/indirect-branch-tracking-eh2.ll
index 32e984df8eb34..b6a6ff35ea9c9 100644
--- a/llvm/test/CodeGen/X86/indirect-branch-tracking-eh2.ll
+++ b/llvm/test/CodeGen/X86/indirect-branch-tracking-eh2.ll
@@ -3,38 +3,51 @@
 
 ; NUM-COUNT-3: endbr64
 
-; SJLJ-LABEL: main:
-; SJLJ:       # %bb.0: # %entry
-; SJLJ-NEXT:    endbr64
-; SJLJ:         callq _Unwind_SjLj_Register at PLT
-; SJLJ-NEXT:  .Ltmp0:
-; SJLJ-NEXT:    callq _Z3foov
-; SJLJ-NEXT:  .Ltmp1:
-; SJLJ-NEXT:  # %bb.1: # %invoke.cont
-; SJLJ:       .LBB0_6: # %return
-; SJLJ:         callq _Unwind_SjLj_Unregister at PLT
-; SJLJ:         retq
-; SJLJ-NEXT:  .LBB0_7:
-; SJLJ-NEXT:    endbr64
-; SJLJ:         jb .LBB0_8
-; SJLJ-NEXT:  # %bb.9:
-; SJLJ-NEXT:    ud2
-; SJLJ-NEXT:  .LBB0_8:
-; SJLJ:         jmpq *(%rcx,%rax,8)
-; SJLJ-NEXT:  .LBB0_2: # %lpad
-; SJLJ-NEXT:  .Ltmp2:
-; SJLJ-NEXT:    endbr64
-; SJLJ:         jne .LBB0_4
-; SJLJ-NEXT:  # %bb.3: # %catch3
-; SJLJ:         callq __cxa_begin_catch
-; SJLJ:         jmp .LBB0_5
-; SJLJ-NEXT:  .LBB0_4: # %catch
-; SJLJ:         callq __cxa_begin_catch
-; SJLJ:         cmpb $3, %al
-; SJLJ-NEXT:  .LBB0_5: # %return
-; SJLJ-NEXT:    setne %cl
-; SJLJ:         callq __cxa_end_catch
-; SJLJ-NEXT:    jmp .LBB0_6
+;SJLJ:       main:                                  # @main
+;SJLJ-NEXT: .Lfunc_begin0:
+;SJLJ-NEXT: # %bb.0:                                # %entry
+;SJLJ-NEXT:         endbr64
+;SJLJ-NEXT:         pushq   %rbp
+;SJLJ:               callq   _Unwind_SjLj_Register
+;SJLJ-NEXT: .Ltmp0:
+;SJLJ-NEXT:         callq   _Z3foov
+;SJLJ-NEXT: .Ltmp1:
+;SJLJ-NEXT: # %bb.1:                                # %invoke.cont
+;SJLJ-NEXT:         movl
+;SJLJ-NEXT: .LBB0_7:                                # %return
+;SJLJ:               callq   _Unwind_SjLj_Unregister
+;SJLJ:               retq
+;SJLJ-NEXT: .LBB0_9:
+;SJLJ-NEXT:         endbr64
+;SJLJ-NEXT:         movl
+;SJLJ-NEXT:         cmpl
+;SJLJ-NEXT:         jb      .LBB0_10
+;SJLJ-NEXT: # %bb.11:
+;SJLJ-NEXT:         ud2
+;SJLJ-NEXT: .LBB0_10:
+;SJLJ-NEXT:         leaq    .LJTI0_0(%rip), %rcx
+;SJLJ-NEXT:         jmpq    *(%rcx,%rax,8)
+;SJLJ-NEXT: .LBB0_2:                                # %lpad
+;SJLJ-NEXT: .Ltmp2:
+;SJLJ-NEXT:         endbr64
+;SJLJ:               jne     .LBB0_4
+;SJLJ-NEXT: # %bb.3:                                # %catch3
+;SJLJ:               callq   __cxa_begin_catch
+;SJLJ:               jmp     .LBB0_6
+;SJLJ-NEXT: .LBB0_4:                                # %catch.fallthrough
+;SJLJ-NEXT:         cmpl
+;SJLJ-NEXT:         jne     .LBB0_8
+;SJLJ-NEXT: # %bb.5:                                # %catch
+;SJLJ:               callq   __cxa_begin_catch
+;SJLJ:               cmpb
+;SJLJ-NEXT: .LBB0_6:                                # %return
+;SJLJ:               callq   __cxa_end_catch
+;SJLJ-NEXT:         jmp     .LBB0_7
+;SJLJ-NEXT: .LBB0_8:                                # %eh.resume
+;SJLJ-NEXT:         movl
+;SJLJ-NEXT: .Lfunc_end0:
+;SJLJ:      .LJTI0_0:
+;SJLJ-NEXT:         .quad   .LBB0_2
 
 @_ZTIi = external dso_local constant i8*
 @_ZTIc = external dso_local constant i8*

diff  --git a/llvm/test/Transforms/InstCombine/volatile_store.ll b/llvm/test/Transforms/InstCombine/volatile_store.ll
index ae9e512afd6c2..105ec83056d61 100644
--- a/llvm/test/Transforms/InstCombine/volatile_store.ll
+++ b/llvm/test/Transforms/InstCombine/volatile_store.ll
@@ -25,6 +25,7 @@ define void @volatile_store_before_unreachable(i1 %c, i8* %p) {
 ; CHECK-LABEL: @volatile_store_before_unreachable(
 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
 ; CHECK:       true:
+; CHECK-NEXT:    store volatile i8 0, i8* [[P:%.*]], align 1
 ; CHECK-NEXT:    unreachable
 ; CHECK:       false:
 ; CHECK-NEXT:    ret void

diff  --git a/llvm/test/Transforms/SimplifyCFG/trapping-load-unreachable.ll b/llvm/test/Transforms/SimplifyCFG/trapping-load-unreachable.ll
index 06b0242f7850e..e437f40cbe753 100644
--- a/llvm/test/Transforms/SimplifyCFG/trapping-load-unreachable.ll
+++ b/llvm/test/Transforms/SimplifyCFG/trapping-load-unreachable.ll
@@ -76,8 +76,8 @@ entry:
 define void @test3() nounwind {
 ; CHECK-LABEL: @test3(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @llvm.trap()
-; CHECK-NEXT:    unreachable
+; CHECK-NEXT:    store volatile i32 4, i32* null, align 4
+; CHECK-NEXT:    ret void
 ;
 entry:
   store volatile i32 4, i32* null
@@ -101,8 +101,11 @@ entry:
 define void @test4(i1 %C, i32* %P) {
 ; CHECK-LABEL: @test4(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[C:%.*]], true
-; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[T:%.*]], label [[F:%.*]]
+; CHECK:       T:
+; CHECK-NEXT:    store volatile i32 0, i32* [[P:%.*]], align 4
+; CHECK-NEXT:    unreachable
+; CHECK:       F:
 ; CHECK-NEXT:    ret void
 ;
 entry:

diff  --git a/llvm/utils/unittest/googletest/src/gtest.cc b/llvm/utils/unittest/googletest/src/gtest.cc
index 5c584048c7897..a5b4e5ac78ca1 100644
--- a/llvm/utils/unittest/googletest/src/gtest.cc
+++ b/llvm/utils/unittest/googletest/src/gtest.cc
@@ -4813,9 +4813,10 @@ void UnitTest::AddTestPartResult(
       // with clang/gcc we can achieve the same effect on x86 by invoking int3
       asm("int3");
 #else
-      // While some debuggers don't correctly trap abort(), we can't perform
-      // volatile store to null since it will be removed by clang and not trap.
-      __builtin_trap();
+      // Dereference nullptr through a volatile pointer to prevent the compiler
+      // from removing. We use this rather than abort() or __builtin_trap() for
+      // portability: some debuggers don't correctly trap abort().
+      *static_cast<volatile int*>(nullptr) = 1;
 #endif  // GTEST_OS_WINDOWS
     } else if (GTEST_FLAG(throw_on_failure)) {
 #if GTEST_HAS_EXCEPTIONS


        


More information about the llvm-commits mailing list