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)58 void 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()67 void 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()75 void 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()91 void 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)103 void 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()123 void 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()136 void testNullabilityCompletenessWithTemplate() {
137   Template<int*> tip;
138 }
139