Author: Roman Lebedev Date: 2021-07-09T12:51:12+03:00 New Revision: f4877c78c0fc98be47b926439bbfe33d5e1d1b6d
URL: https://github.com/llvm/llvm-project/commit/f4877c78c0fc98be47b926439bbfe33d5e1d1b6d DIFF: https://github.com/llvm/llvm-project/commit/f4877c78c0fc98be47b926439bbfe33d5e1d1b6d.diff LOG: [clang] Improve `-Wnull-dereference` diag to be more in-line with reality * Drop any mention of `volatile`. Please refer to https://reviews.llvm.org/D105338 * Drop address space check - it really doesn't affect the behavior, the store will still be dropped: https://godbolt.org/z/dP8fevxG4 Added: 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/Parser/expressions.c clang/test/Sema/exprs.c clang/test/Sema/offsetof.c clang/test/SemaCXX/member-pointer.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index a9d738895033..d33d48846b18 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 non-volatile null pointer will be deleted, not trap">, + "indirection of 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() or qualifying pointer with 'volatile'">; + "consider using __builtin_trap()">; 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 a3a26d21422f..d0efe4c02a1e 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -533,21 +533,16 @@ 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, - // 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. + // 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. const auto *UO = dyn_cast<UnaryOperator>(E->IgnoreParenCasts()); if (UO && UO->getOpcode() == UO_Deref && UO->getSubExpr()->getType()->isPointerType()) { - 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()) { + if (UO->getSubExpr()->IgnoreParenCasts()->isNullPointerConstant( + S.Context, Expr::NPC_ValueDependentIsNotNull)) { 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 86df9d01dfb0..44a176a6eef8 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); // no warn + (*(volatile int *)0 = 1); // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} } void testUninitDeleteArraySink() { int *x; delete[] x; // expected-warning{{Argument to 'delete[]' is uninitialized}} - (*(volatile int *)0 = 1); // no warn + (*(volatile int *)0 = 1); // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} } namespace reference_count { diff --git a/clang/test/Analysis/conditional-path-notes.c b/clang/test/Analysis/conditional-path-notes.c index 5ef81d81a0fd..df69488f2b2b 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@-1 {{Assuming 'a' is not equal to 0}} // expected-note@-2 {{Taking true branch}} - *(volatile int *)0 = 1; // expected-warning{{Dereference of null pointer}} + *(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@-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@-3 {{Assuming 'b' is not equal to 0}} // expected-note@-4 {{Taking true branch}} - *(volatile int *)0 = 1; // expected-warning{{Dereference of null pointer}} + *(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@-1 {{Dereference of null pointer}} } } @@ -79,7 +79,7 @@ void testNonDiagnosableBranchArithmetic(int a, int b) { if (a - b) { // expected-note@-1 {{Taking true branch}} // expected-note@-2 {{Assuming the condition is true}} - *(volatile int *)0 = 1; // expected-warning{{Dereference of null pointer}} + *(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@-1 {{Dereference of null pointer}} } } diff --git a/clang/test/Analysis/cxx-for-range.cpp b/clang/test/Analysis/cxx-for-range.cpp index 034007813e4e..6fa38b4f4411 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 {{Dereference of null pointer}} + *(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}} work(); work(); (void)y; } - *(volatile int *)0 = 1; // no-warning + *(volatile int *)0 = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} } class MagicVector { @@ -30,7 +30,7 @@ class MagicVector { MagicVector get(bool fail = false) { if (fail) - *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}} + *(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}} return MagicVector{}; } @@ -39,13 +39,13 @@ void testLoopOpaqueCollection() { work(); work(); if (y == 2) - *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}} + *(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}} work(); work(); (void)y; } - *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}} + *(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}} } @@ -74,13 +74,13 @@ void testLoopOpaqueIterator() { work(); work(); if (y == 2) - *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}} + *(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}} work(); work(); (void)y; } - *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}} + *(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}} } @@ -89,13 +89,13 @@ void testLoopErrorInRange() { work(); work(); if (y == 2) - *(volatile int *)0 = 1; // no-warning + *(volatile int *)0 = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} work(); work(); (void)y; } - *(volatile int *)0 = 1; // no-warning + *(volatile int *)0 = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} } void testForRangeInit() { diff --git a/clang/test/Analysis/diagnostics/no-prune-paths.c b/clang/test/Analysis/diagnostics/no-prune-paths.c index 6e9e45766bf5..53042eee4a3f 100644 --- a/clang/test/Analysis/diagnostics/no-prune-paths.c +++ b/clang/test/Analysis/diagnostics/no-prune-paths.c @@ -16,6 +16,5 @@ void test() { // expected-note@-3 {{Returning from 'helper'}} #endif - *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}} - // expected-note@-1 {{Dereference of null pointer}} + *(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}} } diff --git a/clang/test/Analysis/inlining/path-notes.cpp b/clang/test/Analysis/inlining/path-notes.cpp index 59726df37b9a..4daa39e44d0c 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 {{Dereference of null pointer}} + *(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@-1 {{Dereference of null pointer}} } }; diff --git a/clang/test/Analysis/objc-arc.m b/clang/test/Analysis/objc-arc.m index 7127232f0de5..b599fca13f5d 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{{Dereference of null pointer}} + *(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}} return result; } diff --git a/clang/test/Analysis/objc-for.m b/clang/test/Analysis/objc-for.m index d4a04c1c3e80..cdbb069ac953 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; // no-warning + *(volatile int *)0 = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} 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 2cbd580168ba..dc1f2d4330f3 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; // no-warning + *(volatile int *)0; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} } diff --git a/clang/test/Analysis/valist-uninitialized.c b/clang/test/Analysis/valist-uninitialized.c index 003592997eab..8ed05d23ab1c 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@-1{{va_end() is called on an uninitialized va_list}} - *((volatile int *)0) = 1; + *((volatile int *)0) = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} } // NOTE: this is invalid, as the man page of va_end requires that "Each invocation of va_start() diff --git a/clang/test/Parser/expressions.c b/clang/test/Parser/expressions.c index 64b44470f7e7..bd0ef8785426 100644 --- a/clang/test/Parser/expressions.c +++ b/clang/test/Parser/expressions.c @@ -39,14 +39,13 @@ void test_sizeof(){ // PR3418 int test_leading_extension() { - __extension__ (*(char*)0) = 1; // expected-warning {{indirection of non-volatile null pointer}} \ - // expected-note {{consider using __builtin_trap}} + __extension__(*(char *)0) = 1; // expected-warning{{indirection of null pointer will be deleted, not trap}} 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 4e144041acae..a5ed610d74bf 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 non-volatile null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap() or qualifying pointer with 'volatile'}} + PR8876_pos(0); // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} 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 non-volatile null pointer will be deleted, not trap}} expected-note {{consider using __builtin_trap() or qualifying pointer with 'volatile'}} + (*((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()}} } // 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,21 +187,17 @@ void test18(int b) { typedef int __attribute__((address_space(256))) int_AS256; // PR7569 void test19() { - *(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. + *(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()}} // rdar://9269271 - 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 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 *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. @@ -213,7 +209,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 b5e392dda82d..5cd8e67938f6 100644 --- a/clang/test/Sema/offsetof.c +++ b/clang/test/Sema/offsetof.c @@ -5,10 +5,9 @@ typedef struct P { int i; float f; } PT; struct external_sun3_core { - unsigned c_regs; + unsigned c_regs; PT X[100]; - }; void swap() @@ -16,24 +15,30 @@ 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 @@ -67,6 +72,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 non-volatile null pointer}} expected-note{{__builtin_trap}} + return __builtin_offsetof(Array, array[*(int *)0]); // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} } diff --git a/clang/test/SemaCXX/member-pointer.cpp b/clang/test/SemaCXX/member-pointer.cpp index f3adb95977a1..e612fda5c09b 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,14 +312,13 @@ 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 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}} + 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()}} } 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 non-volatile null pointer will be deleted}} expected-note {{consider}} + return (*((A *)0)).**(int A::**)0; // expected-warning{{indirection of null pointer will be deleted, not trap}} expected-note{{consider using __builtin_trap()}} } } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits