Revert "Revert "Temporarily do not drop volatile stores before unreachable""
This reverts commit52aeacfbf5
. 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 commitf4877c78c0
. And all the related changes to tests: This reverts commit9a0152799f
. This reverts commit3f7c9cc274
. This reverts commit329f8197ef
. This reverts commitaa9f58cc2c
. This reverts commit2df37d5ddd
. This reverts commita72a441812
.
This commit is contained in:
parent
5035e7be1a
commit
97c675d3d4
|
@ -6744,13 +6744,13 @@ def ext_typecheck_indirection_through_void_pointer : ExtWarn<
|
||||||
"ISO C++ does not allow indirection on operand of type %0">,
|
"ISO C++ does not allow indirection on operand of type %0">,
|
||||||
InGroup<DiagGroup<"void-ptr-dereference">>;
|
InGroup<DiagGroup<"void-ptr-dereference">>;
|
||||||
def warn_indirection_through_null : Warning<
|
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>;
|
InGroup<NullDereference>;
|
||||||
def warn_binding_null_to_reference : Warning<
|
def warn_binding_null_to_reference : Warning<
|
||||||
"binding dereferenced null pointer to reference has undefined behavior">,
|
"binding dereferenced null pointer to reference has undefined behavior">,
|
||||||
InGroup<NullDereference>;
|
InGroup<NullDereference>;
|
||||||
def note_indirection_through_null : Note<
|
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<
|
def warn_pointer_indirection_from_incompatible_type : Warning<
|
||||||
"dereference of type %1 that was reinterpret_cast from type %0 has undefined "
|
"dereference of type %1 that was reinterpret_cast from type %0 has undefined "
|
||||||
"behavior">,
|
"behavior">,
|
||||||
|
|
|
@ -533,16 +533,21 @@ ExprResult Sema::DefaultFunctionArrayConversion(Expr *E, bool Diagnose) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CheckForNullPointerDereference(Sema &S, Expr *E) {
|
static void CheckForNullPointerDereference(Sema &S, Expr *E) {
|
||||||
// Check to see if we are dereferencing a null pointer.
|
// Check to see if we are dereferencing a null pointer. If so,
|
||||||
// If so, this is undefined behavior that the optimizer will delete,
|
// and if not volatile-qualified, this is undefined behavior that the
|
||||||
// so warn about it. People sometimes try to use this to get a deterministic
|
// optimizer will delete, so warn about it. People sometimes try to use this
|
||||||
// trap and are surprised by clang's behavior. This only handles the pattern
|
// to get a deterministic trap and are surprised by clang's behavior. This
|
||||||
// "*null", which is a very syntactic check.
|
// only handles the pattern "*null", which is a very syntactic check.
|
||||||
const auto *UO = dyn_cast<UnaryOperator>(E->IgnoreParenCasts());
|
const auto *UO = dyn_cast<UnaryOperator>(E->IgnoreParenCasts());
|
||||||
if (UO && UO->getOpcode() == UO_Deref &&
|
if (UO && UO->getOpcode() == UO_Deref &&
|
||||||
UO->getSubExpr()->getType()->isPointerType()) {
|
UO->getSubExpr()->getType()->isPointerType()) {
|
||||||
if (UO->getSubExpr()->IgnoreParenCasts()->isNullPointerConstant(
|
const LangAS AS =
|
||||||
S.Context, Expr::NPC_ValueDependentIsNotNull)) {
|
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.DiagRuntimeBehavior(UO->getOperatorLoc(), UO,
|
||||||
S.PDiag(diag::warn_indirection_through_null)
|
S.PDiag(diag::warn_indirection_through_null)
|
||||||
<< UO->getSubExpr()->getSourceRange());
|
<< UO->getSubExpr()->getSourceRange());
|
||||||
|
|
|
@ -83,7 +83,7 @@ void testGlobalPointerPlacementNew() {
|
||||||
//----- Other cases
|
//----- Other cases
|
||||||
void testNewMemoryIsInHeap() {
|
void testNewMemoryIsInHeap() {
|
||||||
int *p = new int;
|
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 different from a region wrapped by 'global'
|
// is different from a region wrapped by 'global'
|
||||||
global = p; // pointer escapes
|
global = p; // pointer escapes
|
||||||
}
|
}
|
||||||
|
@ -263,13 +263,13 @@ void testUninitFree() {
|
||||||
void testUninitDeleteSink() {
|
void testUninitDeleteSink() {
|
||||||
int *x;
|
int *x;
|
||||||
delete x; // expected-warning{{Argument to 'delete' is uninitialized}}
|
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() {
|
void testUninitDeleteArraySink() {
|
||||||
int *x;
|
int *x;
|
||||||
delete[] x; // expected-warning{{Argument to 'delete[]' is uninitialized}}
|
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 {
|
namespace reference_count {
|
||||||
|
|
|
@ -59,7 +59,7 @@ void testDiagnosableBranch(int a) {
|
||||||
if (a) {
|
if (a) {
|
||||||
// expected-note@-1 {{Assuming 'a' is not equal to 0}}
|
// expected-note@-1 {{Assuming 'a' is not equal to 0}}
|
||||||
// expected-note@-2 {{Taking true branch}}
|
// expected-note@-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@-1 {{Dereference of null pointer}}
|
// expected-note@-1 {{Dereference of null pointer}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ void testDiagnosableBranchLogical(int a, int b) {
|
||||||
// expected-note@-2 {{Left side of '&&' is true}}
|
// expected-note@-2 {{Left side of '&&' is true}}
|
||||||
// expected-note@-3 {{Assuming 'b' is not equal to 0}}
|
// expected-note@-3 {{Assuming 'b' is not equal to 0}}
|
||||||
// expected-note@-4 {{Taking true branch}}
|
// expected-note@-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@-1 {{Dereference of null pointer}}
|
// expected-note@-1 {{Dereference of null pointer}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ void testNonDiagnosableBranchArithmetic(int a, int b) {
|
||||||
if (a - b) {
|
if (a - b) {
|
||||||
// expected-note@-1 {{Taking true branch}}
|
// expected-note@-1 {{Taking true branch}}
|
||||||
// expected-note@-2 {{Assuming the condition is true}}
|
// expected-note@-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@-1 {{Dereference of null pointer}}
|
// expected-note@-1 {{Dereference of null pointer}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,13 +9,13 @@ void testLoop() {
|
||||||
work();
|
work();
|
||||||
work();
|
work();
|
||||||
if (y == 2)
|
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();
|
||||||
work();
|
work();
|
||||||
(void)y;
|
(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 {
|
class MagicVector {
|
||||||
|
@ -30,7 +30,7 @@ public:
|
||||||
|
|
||||||
MagicVector get(bool fail = false) {
|
MagicVector get(bool fail = false) {
|
||||||
if (fail)
|
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{};
|
return MagicVector{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,13 +39,13 @@ void testLoopOpaqueCollection() {
|
||||||
work();
|
work();
|
||||||
work();
|
work();
|
||||||
if (y == 2)
|
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();
|
||||||
work();
|
work();
|
||||||
(void)y;
|
(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();
|
||||||
work();
|
work();
|
||||||
if (y == 2)
|
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();
|
||||||
work();
|
work();
|
||||||
(void)y;
|
(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();
|
||||||
work();
|
work();
|
||||||
if (y == 2)
|
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();
|
||||||
work();
|
work();
|
||||||
(void)y;
|
(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() {
|
void testForRangeInit() {
|
||||||
|
|
|
@ -16,5 +16,6 @@ void test() {
|
||||||
// expected-note@-3 {{Returning from 'helper'}}
|
// expected-note@-3 {{Returning from 'helper'}}
|
||||||
#endif
|
#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@-1 {{Dereference of null pointer}}
|
||||||
}
|
}
|
||||||
|
|
|
@ -278,7 +278,7 @@ namespace PR17746 {
|
||||||
class Inner {
|
class Inner {
|
||||||
public:
|
public:
|
||||||
~Inner() {
|
~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@-1 {{Dereference of null pointer}}
|
// expected-note@-1 {{Dereference of null pointer}}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -119,7 +119,7 @@ void rdar9424882() {
|
||||||
id x = [NSObject alloc]; // expected-warning {{Value stored to 'x' during its initialization is never read}}
|
id x = [NSObject alloc]; // expected-warning {{Value stored to 'x' during its initialization is never read}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test
|
// Test
|
||||||
typedef const void *CFTypeRef;
|
typedef const void *CFTypeRef;
|
||||||
typedef const struct __CFString *CFStringRef;
|
typedef const struct __CFString *CFStringRef;
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ void dispatch_set_context(dispatch_object_t object, const void *context);
|
||||||
|
|
||||||
void rdar11059275(dispatch_object_t object) {
|
void rdar11059275(dispatch_object_t object) {
|
||||||
NSObject *o = [[NSObject alloc] init];
|
NSObject *o = [[NSObject alloc] init];
|
||||||
dispatch_set_context(object, CFBridgingRetain(o)); // no-warning
|
dispatch_set_context(object, CFBridgingRetain(o)); // no-warning
|
||||||
}
|
}
|
||||||
void rdar11059275_positive() {
|
void rdar11059275_positive() {
|
||||||
NSObject *o = [[NSObject alloc] init]; // expected-warning {{leak}}
|
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
|
// 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.
|
// of that and the inlined call don't produce a spurious edge cycle.
|
||||||
id result = rdar14061675_helper();
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ void testNonNil(id a, id b) {
|
||||||
if (b != nil)
|
if (b != nil)
|
||||||
return;
|
return;
|
||||||
for (id x in b)
|
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}}
|
clang_analyzer_eval(b != nil); // expected-warning{{FALSE}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -338,7 +338,7 @@ void constraintManagerShouldTreatAsOpaque(int rhs) {
|
||||||
if (i < rhs)
|
if (i < rhs)
|
||||||
return;
|
return;
|
||||||
if (i < rhs)
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,7 @@ void is_sink(int fst, ...) {
|
||||||
va_list va;
|
va_list va;
|
||||||
va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}}
|
va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}}
|
||||||
// expected-note@-1{{va_end() is called on an uninitialized va_list}}
|
// expected-note@-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()
|
// NOTE: this is invalid, as the man page of va_end requires that "Each invocation of va_start()
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
|
|
||||||
// This is initially assumed convergent, but can be deduced to not require it.
|
// 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
|
// CHECK: ret void
|
||||||
__attribute__((noinline))
|
__attribute__((noinline))
|
||||||
void non_convfun(volatile int* p) {
|
void non_convfun(void) {
|
||||||
|
volatile int* p;
|
||||||
*p = 0;
|
*p = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,29 +28,29 @@ void g(void);
|
||||||
// non_convfun();
|
// 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: %[[tobool:.+]] = icmp eq i32 %a, 0
|
||||||
// CHECK: br i1 %[[tobool]], label %[[if_end3_critedge:.+]], label %[[if_then:.+]]
|
// CHECK: br i1 %[[tobool]], label %[[if_end3_critedge:.+]], label %[[if_then:.+]]
|
||||||
|
|
||||||
// CHECK: [[if_then]]:
|
// CHECK: [[if_then]]:
|
||||||
// CHECK: tail call spir_func void @f()
|
// 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: tail call spir_func void @g()
|
||||||
|
|
||||||
// CHECK: br label %[[if_end3:.+]]
|
// CHECK: br label %[[if_end3:.+]]
|
||||||
|
|
||||||
// CHECK: [[if_end3_critedge]]:
|
// 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: br label %[[if_end3]]
|
||||||
|
|
||||||
// CHECK: [[if_end3]]:
|
// CHECK: [[if_end3]]:
|
||||||
// CHECK: ret void
|
// CHECK: ret void
|
||||||
|
|
||||||
void test_merge_if(int a, volatile int* p) {
|
void test_merge_if(int a) {
|
||||||
if (a) {
|
if (a) {
|
||||||
f();
|
f();
|
||||||
}
|
}
|
||||||
non_convfun(p);
|
non_convfun();
|
||||||
if (a) {
|
if (a) {
|
||||||
g();
|
g();
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,13 +39,14 @@ void test_sizeof(){
|
||||||
|
|
||||||
// PR3418
|
// PR3418
|
||||||
int test_leading_extension() {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PR3972
|
// PR3972
|
||||||
int test5(int);
|
int test5(int);
|
||||||
int test6(void) {
|
int test6(void) {
|
||||||
return test5( // expected-note {{to match}}
|
return test5( // expected-note {{to match}}
|
||||||
test5(1)
|
test5(1)
|
||||||
; // expected-error {{expected ')'}}
|
; // expected-error {{expected ')'}}
|
||||||
|
|
|
@ -22,7 +22,7 @@ void radar9171946() {
|
||||||
|
|
||||||
int test_pr8876() {
|
int test_pr8876() {
|
||||||
PR8876(0); // no-warning
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ int test_pr8876() {
|
||||||
void pr8183(unsigned long long test)
|
void pr8183(unsigned long long test)
|
||||||
{
|
{
|
||||||
(void)((((void*)0)) && (*((unsigned long long*)(((void*)0))) = ((unsigned long long)((test)) % (unsigned long long)((1000000000))))); // no-warning
|
(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
|
// 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; // no warning when the subexpr of the unary op has no space before it.
|
||||||
var =-5;
|
var =-5;
|
||||||
|
|
||||||
#define FIVE 5
|
#define FIVE 5
|
||||||
var=-FIVE; // no warning with macros.
|
var=-FIVE; // no warning with macros.
|
||||||
var=-FIVE;
|
var=-FIVE;
|
||||||
|
@ -159,7 +159,7 @@ void test17(int x) {
|
||||||
x = x % 0; // expected-warning {{remainder by zero is undefined}}
|
x = x % 0; // expected-warning {{remainder by zero is undefined}}
|
||||||
x /= 0; // expected-warning {{division by zero is undefined}}
|
x /= 0; // expected-warning {{division by zero is undefined}}
|
||||||
x %= 0; // expected-warning {{remainder by zero is undefined}}
|
x %= 0; // expected-warning {{remainder by zero is undefined}}
|
||||||
|
|
||||||
x = sizeof(x/0); // no warning.
|
x = sizeof(x/0); // no warning.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,17 +187,21 @@ void test18(int b) {
|
||||||
typedef int __attribute__((address_space(256))) int_AS256;
|
typedef int __attribute__((address_space(256))) int_AS256;
|
||||||
// PR7569
|
// PR7569
|
||||||
void test19() {
|
void test19() {
|
||||||
*(int *)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}} \
|
||||||
*(volatile int *)0 = 0; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_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()}}
|
*(volatile int *)0 = 0; // Ok.
|
||||||
*(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 __attribute__((address_space(256))) *)0 = 0; // Ok.
|
||||||
*(int_AS256 *)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 non-volatile null pointer}} \
|
||||||
|
// expected-note {{consider using __builtin_trap}}
|
||||||
|
*(int_AS256 *)0 = 0; // Ok.
|
||||||
|
|
||||||
// rdar://9269271
|
// rdar://9269271
|
||||||
int x = *(int *)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}} \
|
||||||
int x2 = *(volatile int *)0; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_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 x2 = *(volatile int *)0; // Ok.
|
||||||
int x4 = *(int_AS256 *)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 non-volatile null pointer}} \
|
||||||
|
// expected-note {{consider using __builtin_trap}}
|
||||||
|
int x4 = *(int_AS256 *)0; // Ok.
|
||||||
int *p = &(*(int *)0); // Ok.
|
int *p = &(*(int *)0); // Ok.
|
||||||
int_AS256 *p1 = &(*(int __attribute__((address_space(256))) *)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.
|
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}}
|
// expected-note {{remove constant to silence this warning}}
|
||||||
|
|
||||||
return x && sizeof(int) == 4; // no warning, RHS is logical op.
|
return x && sizeof(int) == 4; // no warning, RHS is logical op.
|
||||||
|
|
||||||
// no warning, this is an idiom for "true" in old C style.
|
// no warning, this is an idiom for "true" in old C style.
|
||||||
return x && (signed char)1;
|
return x && (signed char)1;
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,10 @@
|
||||||
typedef struct P { int i; float f; } PT;
|
typedef struct P { int i; float f; } PT;
|
||||||
struct external_sun3_core
|
struct external_sun3_core
|
||||||
{
|
{
|
||||||
unsigned c_regs;
|
unsigned c_regs;
|
||||||
|
|
||||||
PT X[100];
|
PT X[100];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void swap()
|
void swap()
|
||||||
|
@ -15,30 +16,24 @@ void swap()
|
||||||
int x;
|
int x;
|
||||||
x = offsetof(struct external_sun3_core, c_regs);
|
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].f);
|
||||||
|
|
||||||
x = __builtin_offsetof(struct external_sun3_core, X[42].f2); // expected-error {{no member named 'f2'}}
|
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}}
|
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 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 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'}}
|
int c[__builtin_offsetof(struct external_sun3_core, X[42].f2) == 344 ? 1 : -1]; // expected-error {{no member named 'f2'}}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int f();
|
extern int f();
|
||||||
|
|
||||||
struct s1 {
|
struct s1 { int a; };
|
||||||
int a;
|
|
||||||
};
|
|
||||||
int v1 = offsetof (struct s1, a) == 0 ? 0 : f();
|
int v1 = offsetof (struct s1, a) == 0 ? 0 : f();
|
||||||
|
|
||||||
struct s2 {
|
struct s2 { int a; };
|
||||||
int a;
|
|
||||||
};
|
|
||||||
int v2 = (int)(&((struct s2 *) 0)->a) == 0 ? 0 : f();
|
int v2 = (int)(&((struct s2 *) 0)->a) == 0 ? 0 : f();
|
||||||
|
|
||||||
struct s3 {
|
struct s3 { int a; };
|
||||||
int a;
|
|
||||||
};
|
|
||||||
int v3 = __builtin_offsetof(struct s3, a) == 0 ? 0 : f();
|
int v3 = __builtin_offsetof(struct s3, a) == 0 ? 0 : f();
|
||||||
|
|
||||||
// PR3396
|
// PR3396
|
||||||
|
@ -72,6 +67,6 @@ typedef struct Array { int array[1]; } Array;
|
||||||
int test4 = __builtin_offsetof(Array, array);
|
int test4 = __builtin_offsetof(Array, array);
|
||||||
|
|
||||||
int test5() {
|
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}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ void f() {
|
||||||
|
|
||||||
// Conversion to member of base.
|
// Conversion to member of base.
|
||||||
pdi1 = pdid; // expected-error {{assigning to 'int A::*' from incompatible type 'int D::*'}}
|
pdi1 = pdid; // expected-error {{assigning to 'int A::*' from incompatible type 'int D::*'}}
|
||||||
|
|
||||||
// Comparisons
|
// Comparisons
|
||||||
int (A::*pf2)(int, int);
|
int (A::*pf2)(int, int);
|
||||||
int (D::*pf3)(int, int) = 0;
|
int (D::*pf3)(int, int) = 0;
|
||||||
|
@ -106,7 +106,7 @@ void h() {
|
||||||
int i = phm->*pi;
|
int i = phm->*pi;
|
||||||
(void)&(hm.*pi);
|
(void)&(hm.*pi);
|
||||||
(void)&(phm->*pi);
|
(void)&(phm->*pi);
|
||||||
(void)&((&hm)->*pi);
|
(void)&((&hm)->*pi);
|
||||||
|
|
||||||
void (HasMembers::*pf)() = &HasMembers::f;
|
void (HasMembers::*pf)() = &HasMembers::f;
|
||||||
(hm.*pf)();
|
(hm.*pf)();
|
||||||
|
@ -204,7 +204,7 @@ namespace rdar8358512 {
|
||||||
|
|
||||||
static void stat();
|
static void stat();
|
||||||
static void stat(int);
|
static void stat(int);
|
||||||
|
|
||||||
template <typename T> struct Test0 {
|
template <typename T> struct Test0 {
|
||||||
void test() {
|
void test() {
|
||||||
bind(&nonstat); // expected-error {{no matching function for call}}
|
bind(&nonstat); // expected-error {{no matching function for call}}
|
||||||
|
@ -295,8 +295,8 @@ namespace PR9973 {
|
||||||
{ call(u); } // expected-note{{in instantiation of}}
|
{ call(u); } // expected-note{{in instantiation of}}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class R, class T>
|
template<class R, class T>
|
||||||
dm<R, T> mem_fn(R T::*);
|
dm<R, T> mem_fn(R T::*) ;
|
||||||
|
|
||||||
struct test
|
struct test
|
||||||
{ int nullary_v(); };
|
{ int nullary_v(); };
|
||||||
|
@ -312,13 +312,14 @@ namespace test8 {
|
||||||
struct A { int foo; };
|
struct A { int foo; };
|
||||||
int test1() {
|
int test1() {
|
||||||
// Verify that we perform (and check) an lvalue conversion on the operands here.
|
// 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()}}
|
return (*((A**) 0)) // expected-warning {{indirection of non-volatile null pointer will be deleted}} expected-note {{consider}}
|
||||||
->**(int 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 non-volatile null pointer will be deleted}} expected-note {{consider}}
|
||||||
}
|
}
|
||||||
|
|
||||||
int test2() {
|
int test2() {
|
||||||
// Verify that we perform (and check) an lvalue conversion on the operands here.
|
// Verify that we perform (and check) an lvalue conversion on the operands here.
|
||||||
// TODO: the .* should itself warn about being a dereference of null.
|
// 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}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
static void __declspec(noinline) CrashOnProcessDetach() {
|
static void __declspec(noinline) CrashOnProcessDetach() {
|
||||||
printf("CrashOnProcessDetach\n");
|
printf("CrashOnProcessDetach\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
__builtin_trap();
|
*static_cast<volatile int *>(0) = 0x356;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool g_is_child = false;
|
bool g_is_child = false;
|
||||||
|
|
|
@ -5,10 +5,11 @@
|
||||||
// Simple test for a fuzzer. The fuzzer must find the string "Hi!".
|
// Simple test for a fuzzer. The fuzzer must find the string "Hi!".
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdio>
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
static volatile int Sink;
|
static volatile int Sink;
|
||||||
|
static volatile int *Null = 0;
|
||||||
|
|
||||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||||
if (Size > 0 && Data[0] == 'H') {
|
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') {
|
if (Size > 1 && Data[1] == 'i') {
|
||||||
Sink = 2;
|
Sink = 2;
|
||||||
if (Size > 2 && Data[2] == '!') {
|
if (Size > 2 && Data[2] == '!') {
|
||||||
printf("Found the target, trapping\n");
|
printf("Found the target, dereferencing NULL\n");
|
||||||
__builtin_trap();
|
*Null = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
Sink = new int[1 << 28]; // instant OOM with -rss_limit_mb=128.
|
||||||
if (Size >= 4 && Data[0] == 'F' && Data[1] == 'U' && Data[2] == 'Z' &&
|
if (Size >= 4 && Data[0] == 'F' && Data[1] == 'U' && Data[2] == 'Z' &&
|
||||||
Data[3] == 'Z') // a bit deeper crash.
|
Data[3] == 'Z') // a bit deeper crash.
|
||||||
__builtin_trap();
|
*Zero = 42;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
UNSUPPORTED: windows
|
UNSUPPORTED: windows
|
||||||
# FIXME: CreatePCArray() emits PLT stub addresses for entry blocks, which are ignored by TracePC::PrintCoverage().
|
# FIXME: CreatePCArray() emits PLT stub addresses for entry blocks, which are ignored by TracePC::PrintCoverage().
|
||||||
XFAIL: s390x
|
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/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/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
|
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: COVERAGE:
|
||||||
CHECK: COVERED_FUNC: {{.*}}LLVMFuzzerTestOneInput {{.*}}TrapTest.cpp:13
|
CHECK: COVERED_FUNC: {{.*}}LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:14
|
||||||
RUN: not %run %t-TrapTest -print_coverage=1 2>&1 | FileCheck %s
|
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
|
RUN: %run %t-DSOTest -print_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO
|
||||||
DSO: COVERAGE:
|
DSO: COVERAGE:
|
||||||
|
|
|
@ -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
|
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.
|
# 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: %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
|
RUN: not %run %t-ShallowOOMDeepCrash -fork=1 -rss_limit_mb=128 2>&1 | FileCheck %s --check-prefix=CRASH
|
||||||
|
|
||||||
|
|
|
@ -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
|
RUN: %run %t-SimpleCmpTest -seed=-1 -runs=0 2>&1 | FileCheck %s --check-prefix=CHECK_SEED_MINUS_ONE
|
||||||
CHECK_SEED_MINUS_ONE: Seed: 4294967295
|
CHECK_SEED_MINUS_ONE: Seed: 4294967295
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
RUN: %cpp_compiler %S/TrapTest.cpp -o %t-TrapTest
|
RUN: %cpp_compiler %S/NullDerefTest.cpp -o %t-NullDerefTest
|
||||||
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=0 not %run %t-NullDerefTest 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
|
|
||||||
LIBFUZZER_OWN_SEGV_HANDLER: == ERROR: libFuzzer: deadly signal
|
LIBFUZZER_OWN_SEGV_HANDLER: == ERROR: libFuzzer: deadly signal
|
||||||
LIBFUZZER_OWN_SEGV_HANDLER: SUMMARY: libFuzzer: deadly signal
|
LIBFUZZER_OWN_SEGV_HANDLER: SUMMARY: libFuzzer: deadly signal
|
||||||
LIBFUZZER_OWN_SEGV_HANDLER: Test unit written to ./crash-
|
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
|
||||||
|
|
|
@ -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: %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-
|
SingleInput-NOT: Test unit written to ./crash-
|
||||||
|
|
||||||
RUN: rm -rf %tmp/SINGLE_INPUTS
|
RUN: rm -rf %tmp/SINGLE_INPUTS
|
||||||
|
|
|
@ -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: %cpp_compiler %S/SingleByteInputTest.cpp -o %t-SingleByteInputTest
|
||||||
RUN: mkdir -p %t.dir
|
RUN: mkdir -p %t.dir
|
||||||
|
|
||||||
RUN: echo 'Hi!rv349f34t3gg' > %t.dir/not_minimal_crash
|
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
|
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
|
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
|
RUN: rm %t.dir/not_minimal_crash %t.exact_minimized_path
|
||||||
|
|
||||||
|
|
10
compiler-rt/test/fuzzer/null-deref.test
Normal file
10
compiler-rt/test/fuzzer/null-deref.test
Normal file
|
@ -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
|
|
@ -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
|
|
|
@ -14,11 +14,13 @@
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
int n = atoi(argv[1]);
|
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]+]]
|
if (n == 2)
|
||||||
// CHECK1: SUMMARY: [[SAN]]: SEGV {{.*}}signal_line.cpp:[[@LINE-3]]:[[TAB]] in main
|
*((volatile int *)0x1) = __LINE__;
|
||||||
|
// CHECK2: #{{[0-9]+ .*}}main {{.*}}signal_line.cpp:[[@LINE-1]]:[[TAB:[0-9]+]]
|
||||||
// CHECK2: #{{[0-9]+ .*}}main {{.*}}signal_line.cpp:[[@LINE-5]]:[[TAB:[0-9]+]]
|
// CHECK2: SUMMARY: [[SAN]]: SEGV {{.*}}signal_line.cpp:[[@LINE-2]]:[[TAB]] in main
|
||||||
// CHECK2: SUMMARY: [[SAN]]: SEGV {{.*}}signal_line.cpp:[[@LINE-6]]:[[TAB]] in main
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2888,6 +2888,14 @@ Instruction *InstCombinerImpl::visitUnreachableInst(UnreachableInst &I) {
|
||||||
// Otherwise, this instruction can be freely erased,
|
// Otherwise, this instruction can be freely erased,
|
||||||
// even if it is not side-effect free.
|
// 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
|
// A value may still have uses before we process it here (for example, in
|
||||||
// another unreachable block), so convert those to poison.
|
// another unreachable block), so convert those to poison.
|
||||||
replaceInstUsesWith(*Prev, PoisonValue::get(Prev->getType()));
|
replaceInstUsesWith(*Prev, PoisonValue::get(Prev->getType()));
|
||||||
|
|
|
@ -2302,6 +2302,9 @@ static bool markAliveBlocks(Function &F,
|
||||||
// that they should be changed to unreachable by passes that can't
|
// that they should be changed to unreachable by passes that can't
|
||||||
// modify the CFG.
|
// modify the CFG.
|
||||||
|
|
||||||
|
// Don't touch volatile stores.
|
||||||
|
if (SI->isVolatile()) continue;
|
||||||
|
|
||||||
Value *Ptr = SI->getOperand(1);
|
Value *Ptr = SI->getOperand(1);
|
||||||
|
|
||||||
if (isa<UndefValue>(Ptr) ||
|
if (isa<UndefValue>(Ptr) ||
|
||||||
|
|
|
@ -4672,6 +4672,14 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) {
|
||||||
// Otherwise, this instruction can be freely erased,
|
// Otherwise, this instruction can be freely erased,
|
||||||
// even if it is not side-effect free.
|
// 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
|
// 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
|
// of subtle reasoning. If this inst is an EH, all the predecessors of this
|
||||||
// block will be the unwind edges of Invoke/CatchSwitch/CleanupReturn,
|
// block will be the unwind edges of Invoke/CatchSwitch/CleanupReturn,
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
; Long branch is assumed because the block has a higher alignment
|
; Long branch is assumed because the block has a higher alignment
|
||||||
; requirement than the function.
|
; 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-LABEL: invert_bcc_block_align_higher_func:
|
||||||
; CHECK: ; %bb.0: ; %common.ret
|
; CHECK: ; %bb.0: ; %common.ret
|
||||||
; CHECK-NEXT: cmp w0, w1
|
; 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: mov w9, #42
|
||||||
; CHECK-NEXT: cset w0, ne
|
; CHECK-NEXT: cset w0, ne
|
||||||
; CHECK-NEXT: csel w8, w9, w8, eq
|
; CHECK-NEXT: csel w8, w9, w8, eq
|
||||||
; CHECK-NEXT: str w8, [x2]
|
; CHECK-NEXT: str w8, [x8]
|
||||||
; CHECK-NEXT: ret
|
; CHECK-NEXT: ret
|
||||||
%1 = icmp eq i32 %x, %y
|
%1 = icmp eq i32 %x, %y
|
||||||
br i1 %1, label %bb1, label %bb2
|
br i1 %1, label %bb1, label %bb2
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
store volatile i32 9, i32* %dst
|
store volatile i32 9, i32* undef
|
||||||
ret i32 1
|
ret i32 1
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
store volatile i32 42, i32* %dst
|
store volatile i32 42, i32* undef
|
||||||
ret i32 0
|
ret i32 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,28 +1,27 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
; 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
|
; 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-LABEL: invert_bcc:
|
||||||
; CHECK: ; %bb.0:
|
; CHECK: ; %bb.0:
|
||||||
|
; CHECK-NEXT: mov w0, wzr
|
||||||
; CHECK-NEXT: fcmp s0, s1
|
; 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: b LBB0_2
|
||||||
; CHECK-NEXT: LBB0_3:
|
; CHECK-NEXT: LBB0_3:
|
||||||
; CHECK-NEXT: b.vc LBB0_1
|
; CHECK-NEXT: b.gt LBB0_2
|
||||||
; CHECK-NEXT: b LBB0_2
|
; CHECK-NEXT: ; %bb.1: ; %common.ret
|
||||||
; CHECK-NEXT: LBB0_1: ; %bb2
|
; 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: mov w8, #9
|
||||||
; CHECK-NEXT: ; InlineAsm Start
|
; CHECK-NEXT: ; InlineAsm Start
|
||||||
; CHECK-NEXT: nop
|
; CHECK-NEXT: nop
|
||||||
; CHECK-NEXT: nop
|
; CHECK-NEXT: nop
|
||||||
; CHECK-NEXT: ; InlineAsm End
|
; CHECK-NEXT: ; InlineAsm End
|
||||||
; CHECK-NEXT: str w8, [x0]
|
; CHECK-NEXT: str w8, [x8]
|
||||||
; 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: ret
|
; CHECK-NEXT: ret
|
||||||
%1 = fcmp ueq float %x, %y
|
%1 = fcmp ueq float %x, %y
|
||||||
br i1 %1, label %bb1, label %bb2
|
br i1 %1, label %bb1, label %bb2
|
||||||
|
@ -32,11 +31,11 @@ bb2:
|
||||||
"nop
|
"nop
|
||||||
nop",
|
nop",
|
||||||
""() #0
|
""() #0
|
||||||
store volatile i32 9, i32* %dst0
|
store volatile i32 9, i32* undef
|
||||||
ret i32 1
|
ret i32 1
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
store volatile i32 42, i32* %dst1
|
store volatile i32 42, i32* undef
|
||||||
ret i32 0
|
ret i32 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,18 +16,18 @@ entry:
|
||||||
; CHECK: mul i32
|
; CHECK: mul i32
|
||||||
; CHECK-NOT: call i32
|
; CHECK-NOT: call i32
|
||||||
|
|
||||||
define amdgpu_kernel void @caller(i32 %x, i32 addrspace(1)* %dst) {
|
define amdgpu_kernel void @caller(i32 %x) {
|
||||||
entry:
|
entry:
|
||||||
%res = call i32 @callee(i32 %x)
|
%res = call i32 @callee(i32 %x)
|
||||||
store volatile i32 %res, i32 addrspace(1)* %dst
|
store volatile i32 %res, i32 addrspace(1)* undef
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; CHECK-LABEL: @alias_caller(
|
; CHECK-LABEL: @alias_caller(
|
||||||
; CHECK-NOT: call
|
; CHECK-NOT: call
|
||||||
define amdgpu_kernel void @alias_caller(i32 %x, i32 addrspace(1)* %dst) {
|
define amdgpu_kernel void @alias_caller(i32 %x) {
|
||||||
entry:
|
entry:
|
||||||
%res = call i32 @c_alias(i32 %x)
|
%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
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,38 +3,51 @@
|
||||||
|
|
||||||
; NUM-COUNT-3: endbr64
|
; NUM-COUNT-3: endbr64
|
||||||
|
|
||||||
; SJLJ-LABEL: main:
|
;SJLJ: main: # @main
|
||||||
; SJLJ: # %bb.0: # %entry
|
;SJLJ-NEXT: .Lfunc_begin0:
|
||||||
; SJLJ-NEXT: endbr64
|
;SJLJ-NEXT: # %bb.0: # %entry
|
||||||
; SJLJ: callq _Unwind_SjLj_Register@PLT
|
;SJLJ-NEXT: endbr64
|
||||||
; SJLJ-NEXT: .Ltmp0:
|
;SJLJ-NEXT: pushq %rbp
|
||||||
; SJLJ-NEXT: callq _Z3foov
|
;SJLJ: callq _Unwind_SjLj_Register
|
||||||
; SJLJ-NEXT: .Ltmp1:
|
;SJLJ-NEXT: .Ltmp0:
|
||||||
; SJLJ-NEXT: # %bb.1: # %invoke.cont
|
;SJLJ-NEXT: callq _Z3foov
|
||||||
; SJLJ: .LBB0_6: # %return
|
;SJLJ-NEXT: .Ltmp1:
|
||||||
; SJLJ: callq _Unwind_SjLj_Unregister@PLT
|
;SJLJ-NEXT: # %bb.1: # %invoke.cont
|
||||||
; SJLJ: retq
|
;SJLJ-NEXT: movl
|
||||||
; SJLJ-NEXT: .LBB0_7:
|
;SJLJ-NEXT: .LBB0_7: # %return
|
||||||
; SJLJ-NEXT: endbr64
|
;SJLJ: callq _Unwind_SjLj_Unregister
|
||||||
; SJLJ: jb .LBB0_8
|
;SJLJ: retq
|
||||||
; SJLJ-NEXT: # %bb.9:
|
;SJLJ-NEXT: .LBB0_9:
|
||||||
; SJLJ-NEXT: ud2
|
;SJLJ-NEXT: endbr64
|
||||||
; SJLJ-NEXT: .LBB0_8:
|
;SJLJ-NEXT: movl
|
||||||
; SJLJ: jmpq *(%rcx,%rax,8)
|
;SJLJ-NEXT: cmpl
|
||||||
; SJLJ-NEXT: .LBB0_2: # %lpad
|
;SJLJ-NEXT: jb .LBB0_10
|
||||||
; SJLJ-NEXT: .Ltmp2:
|
;SJLJ-NEXT: # %bb.11:
|
||||||
; SJLJ-NEXT: endbr64
|
;SJLJ-NEXT: ud2
|
||||||
; SJLJ: jne .LBB0_4
|
;SJLJ-NEXT: .LBB0_10:
|
||||||
; SJLJ-NEXT: # %bb.3: # %catch3
|
;SJLJ-NEXT: leaq .LJTI0_0(%rip), %rcx
|
||||||
; SJLJ: callq __cxa_begin_catch
|
;SJLJ-NEXT: jmpq *(%rcx,%rax,8)
|
||||||
; SJLJ: jmp .LBB0_5
|
;SJLJ-NEXT: .LBB0_2: # %lpad
|
||||||
; SJLJ-NEXT: .LBB0_4: # %catch
|
;SJLJ-NEXT: .Ltmp2:
|
||||||
; SJLJ: callq __cxa_begin_catch
|
;SJLJ-NEXT: endbr64
|
||||||
; SJLJ: cmpb $3, %al
|
;SJLJ: jne .LBB0_4
|
||||||
; SJLJ-NEXT: .LBB0_5: # %return
|
;SJLJ-NEXT: # %bb.3: # %catch3
|
||||||
; SJLJ-NEXT: setne %cl
|
;SJLJ: callq __cxa_begin_catch
|
||||||
; SJLJ: callq __cxa_end_catch
|
;SJLJ: jmp .LBB0_6
|
||||||
; SJLJ-NEXT: 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*
|
@_ZTIi = external dso_local constant i8*
|
||||||
@_ZTIc = external dso_local constant i8*
|
@_ZTIc = external dso_local constant i8*
|
||||||
|
|
|
@ -25,6 +25,7 @@ define void @volatile_store_before_unreachable(i1 %c, i8* %p) {
|
||||||
; CHECK-LABEL: @volatile_store_before_unreachable(
|
; CHECK-LABEL: @volatile_store_before_unreachable(
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
||||||
; CHECK: true:
|
; CHECK: true:
|
||||||
|
; CHECK-NEXT: store volatile i8 0, i8* [[P:%.*]], align 1
|
||||||
; CHECK-NEXT: unreachable
|
; CHECK-NEXT: unreachable
|
||||||
; CHECK: false:
|
; CHECK: false:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
|
|
|
@ -76,8 +76,8 @@ entry:
|
||||||
define void @test3() nounwind {
|
define void @test3() nounwind {
|
||||||
; CHECK-LABEL: @test3(
|
; CHECK-LABEL: @test3(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: call void @llvm.trap()
|
; CHECK-NEXT: store volatile i32 4, i32* null, align 4
|
||||||
; CHECK-NEXT: unreachable
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store volatile i32 4, i32* null
|
store volatile i32 4, i32* null
|
||||||
|
@ -101,8 +101,11 @@ entry:
|
||||||
define void @test4(i1 %C, i32* %P) {
|
define void @test4(i1 %C, i32* %P) {
|
||||||
; CHECK-LABEL: @test4(
|
; CHECK-LABEL: @test4(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[C:%.*]], true
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[T:%.*]], label [[F:%.*]]
|
||||||
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
|
; CHECK: T:
|
||||||
|
; CHECK-NEXT: store volatile i32 0, i32* [[P:%.*]], align 4
|
||||||
|
; CHECK-NEXT: unreachable
|
||||||
|
; CHECK: F:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
|
|
@ -4813,9 +4813,10 @@ void UnitTest::AddTestPartResult(
|
||||||
// with clang/gcc we can achieve the same effect on x86 by invoking int3
|
// with clang/gcc we can achieve the same effect on x86 by invoking int3
|
||||||
asm("int3");
|
asm("int3");
|
||||||
#else
|
#else
|
||||||
// While some debuggers don't correctly trap abort(), we can't perform
|
// Dereference nullptr through a volatile pointer to prevent the compiler
|
||||||
// volatile store to null since it will be removed by clang and not trap.
|
// from removing. We use this rather than abort() or __builtin_trap() for
|
||||||
__builtin_trap();
|
// portability: some debuggers don't correctly trap abort().
|
||||||
|
*static_cast<volatile int*>(nullptr) = 1;
|
||||||
#endif // GTEST_OS_WINDOWS
|
#endif // GTEST_OS_WINDOWS
|
||||||
} else if (GTEST_FLAG(throw_on_failure)) {
|
} else if (GTEST_FLAG(throw_on_failure)) {
|
||||||
#if GTEST_HAS_EXCEPTIONS
|
#if GTEST_HAS_EXCEPTIONS
|
||||||
|
|
Loading…
Reference in a new issue