[clang] 97c675d - Revert "Revert "Temporarily do not drop volatile stores before unreachable""
Nico Weber via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 9 08:45:02 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 cfe-commits
mailing list