blob: 2af25730b66fd6d72214508b9390dbba095da9ea [file] [log] [blame]
George Burgess IV8d141e02015-12-14 22:00:49 +00001// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wno-nullability-declspec %s -verify -Wnullable-to-nonnull-conversion
Douglas Gregor261a89b2015-06-19 17:51:05 +00002
Douglas Gregor4c27d102015-06-29 18:11:42 +00003#if __has_feature(nullability)
4#else
5# error nullability feature should be defined
6#endif
7
Douglas Gregor261a89b2015-06-19 17:51:05 +00008typedef decltype(nullptr) nullptr_t;
9
10class X {
11};
12
13// Nullability applies to all pointer types.
Douglas Gregoraea7afd2015-06-24 22:02:08 +000014typedef int (X::* _Nonnull member_function_type_1)(int);
15typedef int X::* _Nonnull member_data_type_1;
16typedef nullptr_t _Nonnull nonnull_nullptr_t; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'nullptr_t'}}
Douglas Gregor261a89b2015-06-19 17:51:05 +000017
18// Nullability can move into member pointers (this is suppressing a warning).
Douglas Gregoraea7afd2015-06-24 22:02:08 +000019typedef _Nonnull int (X::* member_function_type_2)(int);
20typedef int (X::* _Nonnull member_function_type_3)(int);
21typedef _Nonnull int X::* member_data_type_2;
Douglas Gregor261a89b2015-06-19 17:51:05 +000022
23// Adding non-null via a template.
24template<typename T>
25struct AddNonNull {
Douglas Gregoraea7afd2015-06-24 22:02:08 +000026 typedef _Nonnull T type; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'int'}}
27 // expected-error@-1{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'nullptr_t'}}
Douglas Gregor261a89b2015-06-19 17:51:05 +000028};
29
30typedef AddNonNull<int *>::type nonnull_int_ptr_1;
Douglas Gregoraea7afd2015-06-24 22:02:08 +000031typedef AddNonNull<int * _Nullable>::type nonnull_int_ptr_2; // FIXME: check that it was overridden
Douglas Gregor261a89b2015-06-19 17:51:05 +000032typedef AddNonNull<nullptr_t>::type nonnull_int_ptr_3; // expected-note{{in instantiation of template class}}
33
34typedef AddNonNull<int>::type nonnull_non_pointer_1; // expected-note{{in instantiation of template class 'AddNonNull<int>' requested here}}
35
36// Non-null checking within a template.
37template<typename T>
38struct AddNonNull2 {
Douglas Gregoraea7afd2015-06-24 22:02:08 +000039 typedef _Nonnull AddNonNull<T> invalid1; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'AddNonNull<T>'}}
40 typedef _Nonnull AddNonNull2 invalid2; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'AddNonNull2<T>'}}
41 typedef _Nonnull AddNonNull2<T> invalid3; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'AddNonNull2<T>'}}
42 typedef _Nonnull typename AddNonNull<T>::type okay1;
Douglas Gregor261a89b2015-06-19 17:51:05 +000043
44 // Don't move past a dependent type even if we know that nullability
45 // cannot apply to that specific dependent type.
Douglas Gregoraea7afd2015-06-24 22:02:08 +000046 typedef _Nonnull AddNonNull<T> (*invalid4); // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'AddNonNull<T>'}}
Douglas Gregor261a89b2015-06-19 17:51:05 +000047};
Douglas Gregorb4866e82015-06-19 18:13:19 +000048
Douglas Gregoraea7afd2015-06-24 22:02:08 +000049// Check passing null to a _Nonnull argument.
50void (*accepts_nonnull_1)(_Nonnull int *ptr);
51void (*& accepts_nonnull_2)(_Nonnull int *ptr) = accepts_nonnull_1;
52void (X::* accepts_nonnull_3)(_Nonnull int *ptr);
53void accepts_nonnull_4(_Nonnull int *ptr);
54void (&accepts_nonnull_5)(_Nonnull int *ptr) = accepts_nonnull_4;
Douglas Gregorb4866e82015-06-19 18:13:19 +000055
56void test_accepts_nonnull_null_pointer_literal(X *x) {
57 accepts_nonnull_1(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
58 accepts_nonnull_2(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
59 (x->*accepts_nonnull_3)(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
60 accepts_nonnull_4(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
61 accepts_nonnull_5(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
62}
63
Douglas Gregoraea7afd2015-06-24 22:02:08 +000064template<void FP(_Nonnull int*)>
Douglas Gregorb4866e82015-06-19 18:13:19 +000065void test_accepts_nonnull_null_pointer_literal_template() {
66 FP(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
67}
68
69template void test_accepts_nonnull_null_pointer_literal_template<&accepts_nonnull_4>(); // expected-note{{instantiation of function template specialization}}
George Burgess IV8d141e02015-12-14 22:00:49 +000070
71void TakeNonnull(void *_Nonnull);
72// Check different forms of assignment to a nonull type from a nullable one.
73void AssignAndInitNonNull() {
74 void *_Nullable nullable;
75 void *_Nonnull p(nullable); // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
76 void *_Nonnull p2{nullable}; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
77 void *_Nonnull p3 = {nullable}; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
78 void *_Nonnull p4 = nullable; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
79 void *_Nonnull nonnull;
80 nonnull = nullable; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
81 nonnull = {nullable}; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
82
83 TakeNonnull(nullable); //expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull}}
84 TakeNonnull(nonnull); // OK
85}
86
87void *_Nullable ReturnNullable();
88
89void AssignAndInitNonNullFromFn() {
90 void *_Nonnull p(ReturnNullable()); // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
91 void *_Nonnull p2{ReturnNullable()}; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
92 void *_Nonnull p3 = {ReturnNullable()}; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
93 void *_Nonnull p4 = ReturnNullable(); // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
94 void *_Nonnull nonnull;
95 nonnull = ReturnNullable(); // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
96 nonnull = {ReturnNullable()}; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
97
98 TakeNonnull(ReturnNullable()); //expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull}}
99}
Akira Hatanaka73118fd2016-07-20 01:48:11 +0000100
101void ConditionalExpr(bool c) {
102 struct Base {};
103 struct Derived : Base {};
104
105 Base * _Nonnull p;
106 Base * _Nonnull nonnullB;
107 Base * _Nullable nullableB;
108 Derived * _Nonnull nonnullD;
109 Derived * _Nullable nullableD;
110
111 p = c ? nonnullB : nonnullD;
112 p = c ? nonnullB : nullableD; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}}
113 p = c ? nullableB : nonnullD; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}}
114 p = c ? nullableB : nullableD; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}}
115 p = c ? nonnullD : nonnullB;
116 p = c ? nonnullD : nullableB; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}}
117 p = c ? nullableD : nonnullB; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}}
118 p = c ? nullableD : nullableB; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}}
119}