1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wno-nullability-declspec %s -verify -Wnullable-to-nonnull-conversion -I%S/Inputs 2 3 #if __has_feature(nullability) 4 #else 5 # error nullability feature should be defined 6 #endif 7 8 #include "nullability-completeness.h" 9 10 typedef decltype(nullptr) nullptr_t; 11 12 class X { 13 }; 14 15 // Nullability applies to all pointer types. 16 typedef int (X::* _Nonnull member_function_type_1)(int); 17 typedef int X::* _Nonnull member_data_type_1; 18 typedef nullptr_t _Nonnull nonnull_nullptr_t; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'nullptr_t'}} 19 20 // Nullability can move into member pointers (this is suppressing a warning). 21 typedef _Nonnull int (X::* member_function_type_2)(int); 22 typedef int (X::* _Nonnull member_function_type_3)(int); 23 typedef _Nonnull int X::* member_data_type_2; 24 25 // Adding non-null via a template. 26 template<typename T> 27 struct AddNonNull { 28 typedef _Nonnull T type; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'int'}} 29 // expected-error@-1{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'nullptr_t'}} 30 }; 31 32 typedef AddNonNull<int *>::type nonnull_int_ptr_1; 33 typedef AddNonNull<int * _Nullable>::type nonnull_int_ptr_2; // FIXME: check that it was overridden 34 typedef AddNonNull<nullptr_t>::type nonnull_int_ptr_3; // expected-note{{in instantiation of template class}} 35 36 typedef AddNonNull<int>::type nonnull_non_pointer_1; // expected-note{{in instantiation of template class 'AddNonNull<int>' requested here}} 37 38 // Non-null checking within a template. 39 template<typename T> 40 struct AddNonNull2 { 41 typedef _Nonnull AddNonNull<T> invalid1; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'AddNonNull<T>'}} 42 typedef _Nonnull AddNonNull2 invalid2; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'AddNonNull2<T>'}} 43 typedef _Nonnull AddNonNull2<T> invalid3; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'AddNonNull2<T>'}} 44 typedef _Nonnull typename AddNonNull<T>::type okay1; 45 46 // Don't move past a dependent type even if we know that nullability 47 // cannot apply to that specific dependent type. 48 typedef _Nonnull AddNonNull<T> (*invalid4); // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'AddNonNull<T>'}} 49 }; 50 51 // Check passing null to a _Nonnull argument. 52 void (*accepts_nonnull_1)(_Nonnull int *ptr); 53 void (*& accepts_nonnull_2)(_Nonnull int *ptr) = accepts_nonnull_1; 54 void (X::* accepts_nonnull_3)(_Nonnull int *ptr); 55 void accepts_nonnull_4(_Nonnull int *ptr); 56 void (&accepts_nonnull_5)(_Nonnull int *ptr) = accepts_nonnull_4; 57 test_accepts_nonnull_null_pointer_literal(X * x)58void test_accepts_nonnull_null_pointer_literal(X *x) { 59 accepts_nonnull_1(0); // expected-warning{{null passed to a callee that requires a non-null argument}} 60 accepts_nonnull_2(0); // expected-warning{{null passed to a callee that requires a non-null argument}} 61 (x->*accepts_nonnull_3)(0); // expected-warning{{null passed to a callee that requires a non-null argument}} 62 accepts_nonnull_4(0); // expected-warning{{null passed to a callee that requires a non-null argument}} 63 accepts_nonnull_5(0); // expected-warning{{null passed to a callee that requires a non-null argument}} 64 } 65 66 template<void FP(_Nonnull int*)> test_accepts_nonnull_null_pointer_literal_template()67void test_accepts_nonnull_null_pointer_literal_template() { 68 FP(0); // expected-warning{{null passed to a callee that requires a non-null argument}} 69 } 70 71 template void test_accepts_nonnull_null_pointer_literal_template<&accepts_nonnull_4>(); // expected-note{{instantiation of function template specialization}} 72 73 void TakeNonnull(void *_Nonnull); 74 // Check different forms of assignment to a nonull type from a nullable one. AssignAndInitNonNull()75void AssignAndInitNonNull() { 76 void *_Nullable nullable; 77 void *_Nonnull p(nullable); // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}} 78 void *_Nonnull p2{nullable}; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}} 79 void *_Nonnull p3 = {nullable}; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}} 80 void *_Nonnull p4 = nullable; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}} 81 void *_Nonnull nonnull; 82 nonnull = nullable; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}} 83 nonnull = {nullable}; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}} 84 85 TakeNonnull(nullable); //expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull}} 86 TakeNonnull(nonnull); // OK 87 } 88 89 void *_Nullable ReturnNullable(); 90 AssignAndInitNonNullFromFn()91void AssignAndInitNonNullFromFn() { 92 void *_Nonnull p(ReturnNullable()); // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}} 93 void *_Nonnull p2{ReturnNullable()}; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}} 94 void *_Nonnull p3 = {ReturnNullable()}; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}} 95 void *_Nonnull p4 = ReturnNullable(); // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}} 96 void *_Nonnull nonnull; 97 nonnull = ReturnNullable(); // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}} 98 nonnull = {ReturnNullable()}; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}} 99 100 TakeNonnull(ReturnNullable()); //expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull}} 101 } 102 ConditionalExpr(bool c)103void ConditionalExpr(bool c) { 104 struct Base {}; 105 struct Derived : Base {}; 106 107 Base * _Nonnull p; 108 Base * _Nonnull nonnullB; 109 Base * _Nullable nullableB; 110 Derived * _Nonnull nonnullD; 111 Derived * _Nullable nullableD; 112 113 p = c ? nonnullB : nonnullD; 114 p = c ? nonnullB : nullableD; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}} 115 p = c ? nullableB : nonnullD; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}} 116 p = c ? nullableB : nullableD; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}} 117 p = c ? nonnullD : nonnullB; 118 p = c ? nonnullD : nullableB; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}} 119 p = c ? nullableD : nonnullB; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}} 120 p = c ? nullableD : nullableB; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}} 121 } 122 arraysInLambdas()123void arraysInLambdas() { 124 typedef int INTS[4]; 125 auto simple = [](int [_Nonnull 2]) {}; 126 simple(nullptr); // expected-warning {{null passed to a callee that requires a non-null argument}} 127 auto nested = [](void *_Nullable [_Nonnull 2]) {}; 128 nested(nullptr); // expected-warning {{null passed to a callee that requires a non-null argument}} 129 auto nestedBad = [](int [2][_Nonnull 2]) {}; // expected-error {{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'int [2]'}} 130 131 auto withTypedef = [](INTS _Nonnull) {}; 132 withTypedef(nullptr); // expected-warning {{null passed to a callee that requires a non-null argument}} 133 auto withTypedefBad = [](INTS _Nonnull[2]) {}; // expected-error {{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'INTS' (aka 'int [4]')}} 134 } 135 testNullabilityCompletenessWithTemplate()136void testNullabilityCompletenessWithTemplate() { 137 Template<int*> tip; 138 } 139