1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wno-nullability-declspec %s -verify -Wnullable-to-nonnull-conversion -I%S/Inputs
3 #if __has_feature(nullability)
5 # error nullability feature should be defined
7 #if __has_feature(nullability_on_classes)
9 # error smart-pointer feature should be defined
12 #include "nullability-completeness.h"
14 typedef decltype(nullptr) nullptr_t
;
19 // Nullability applies to all pointer types.
20 typedef int (X::* _Nonnull member_function_type_1
)(int);
21 typedef int X::* _Nonnull member_data_type_1
;
22 typedef nullptr_t _Nonnull nonnull_nullptr_t
; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'nullptr_t' (aka 'std::nullptr_t')}}
24 // Nullability can move into member pointers (this is suppressing a warning).
25 typedef _Nonnull
int (X::* member_function_type_2
)(int);
26 typedef int (X::* _Nonnull member_function_type_3
)(int);
27 typedef _Nonnull
int X::* member_data_type_2
;
29 // Adding non-null via a template.
32 typedef _Nonnull T type
; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'int'}}
33 // expected-error@-1{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'std::nullptr_t'}}
34 // expected-error@-2{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'NotPtr'}}
37 typedef AddNonNull
<int *>::type nonnull_int_ptr_1
;
38 typedef AddNonNull
<int * _Nullable
>::type nonnull_int_ptr_2
; // FIXME: check that it was overridden
39 typedef AddNonNull
<nullptr_t
>::type nonnull_int_ptr_3
; // expected-note{{in instantiation of template class}}
41 typedef AddNonNull
<int>::type nonnull_non_pointer_1
; // expected-note{{in instantiation of template class 'AddNonNull<int>' requested here}}
43 // Nullability on C++ class types (smart pointers).
45 typedef AddNonNull
<NotPtr
>::type nonnull_non_pointer_2
; // expected-note{{in instantiation}}
46 struct _Nullable SmartPtr
{
49 SmartPtr(const SmartPtr
&);
51 SmartPtr
&operator=(const SmartPtr
&);
52 SmartPtr
&operator=(SmartPtr
&&);
54 typedef AddNonNull
<SmartPtr
>::type nonnull_smart_pointer_1
;
55 template<class> struct _Nullable SmartPtrTemplate
{};
56 typedef AddNonNull
<SmartPtrTemplate
<int>>::type nonnull_smart_pointer_2
;
57 namespace std
{ inline namespace __1
{
58 template <class> class unique_ptr
{};
59 template <class> class function
;
60 template <class Ret
, class... Args
> class function
<Ret(Args
...)> {};
62 typedef AddNonNull
<std::unique_ptr
<int>>::type nonnull_smart_pointer_3
;
63 typedef AddNonNull
<std::function
<int()>>::type nonnull_smart_pointer_4
;
65 class Derived
: public SmartPtr
{};
66 Derived _Nullable x
; // expected-error {{'_Nullable' cannot be applied}}
67 class DerivedPrivate
: private SmartPtr
{};
68 DerivedPrivate _Nullable y
; // expected-error {{'_Nullable' cannot be applied}}
70 // Non-null checking within a template.
73 typedef _Nonnull AddNonNull
<T
> invalid1
; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'AddNonNull<T>'}}
74 typedef _Nonnull AddNonNull2 invalid2
; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'AddNonNull2<T>'}}
75 typedef _Nonnull AddNonNull2
<T
> invalid3
; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'AddNonNull2<T>'}}
76 typedef _Nonnull typename AddNonNull
<T
>::type okay1
;
78 // Don't move past a dependent type even if we know that nullability
79 // cannot apply to that specific dependent type.
80 typedef _Nonnull AddNonNull
<T
> (*invalid4
); // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'AddNonNull<T>'}}
83 // Check passing null to a _Nonnull argument.
84 void (*accepts_nonnull_1
)(_Nonnull
int *ptr
);
85 void (*& accepts_nonnull_2
)(_Nonnull
int *ptr
) = accepts_nonnull_1
;
86 void (X::* accepts_nonnull_3
)(_Nonnull
int *ptr
);
87 void accepts_nonnull_4(_Nonnull
int *ptr
);
88 void (&accepts_nonnull_5
)(_Nonnull
int *ptr
) = accepts_nonnull_4
;
89 void accepts_nonnull_6(SmartPtr _Nonnull
);
91 void test_accepts_nonnull_null_pointer_literal(X
*x
) {
92 accepts_nonnull_1(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
93 accepts_nonnull_2(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
94 (x
->*accepts_nonnull_3
)(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
95 accepts_nonnull_4(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
96 accepts_nonnull_5(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
98 accepts_nonnull_6(nullptr); // expected-warning{{null passed to a callee that requires a non-null argument}}
101 template<void FP(_Nonnull
int*)>
102 void test_accepts_nonnull_null_pointer_literal_template() {
103 FP(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
106 template void test_accepts_nonnull_null_pointer_literal_template
<&accepts_nonnull_4
>(); // expected-note{{instantiation of function template specialization}}
108 void TakeNonnull(void *_Nonnull
);
109 void TakeSmartNonnull(SmartPtr _Nonnull
);
110 // Check different forms of assignment to a nonull type from a nullable one.
111 void AssignAndInitNonNull() {
112 void *_Nullable nullable
;
113 void *_Nonnull
p(nullable
); // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
114 void *_Nonnull p2
{nullable
}; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
115 void *_Nonnull p3
= {nullable
}; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
116 void *_Nonnull p4
= nullable
; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
117 void *_Nonnull nonnull
;
118 nonnull
= nullable
; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
119 nonnull
= {nullable
}; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
120 TakeNonnull(nullable
); //expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull}}
121 TakeNonnull(nonnull
); // OK
122 nonnull
= (void *_Nonnull
)nullable
; // explicit cast OK
124 SmartPtr _Nullable s_nullable
;
125 SmartPtr _Nonnull
s(s_nullable
); // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
126 SmartPtr _Nonnull s2
{s_nullable
}; // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
127 SmartPtr _Nonnull s3
= {s_nullable
}; // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
128 SmartPtr _Nonnull s4
= s_nullable
; // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
129 SmartPtr _Nonnull s_nonnull
;
130 s_nonnull
= s_nullable
; // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
131 s_nonnull
= {s_nullable
}; // no warning here - might be nice?
132 TakeSmartNonnull(s_nullable
); //expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull}}
133 TakeSmartNonnull(s_nonnull
); // OK
134 s_nonnull
= (SmartPtr _Nonnull
)s_nullable
; // explicit cast OK
135 s_nonnull
= static_cast<SmartPtr _Nonnull
>(s_nullable
); // explicit cast OK
138 void *_Nullable
ReturnNullable();
139 SmartPtr _Nullable
ReturnSmartNullable();
141 void AssignAndInitNonNullFromFn() {
142 void *_Nonnull
p(ReturnNullable()); // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
143 void *_Nonnull p2
{ReturnNullable()}; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
144 void *_Nonnull p3
= {ReturnNullable()}; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
145 void *_Nonnull p4
= ReturnNullable(); // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
146 void *_Nonnull nonnull
;
147 nonnull
= ReturnNullable(); // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
148 nonnull
= {ReturnNullable()}; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
149 TakeNonnull(ReturnNullable()); //expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull}}
151 SmartPtr _Nonnull
s(ReturnSmartNullable()); // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
152 SmartPtr _Nonnull s2
{ReturnSmartNullable()}; // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
153 SmartPtr _Nonnull s3
= {ReturnSmartNullable()}; // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
154 SmartPtr _Nonnull s4
= ReturnSmartNullable(); // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
155 SmartPtr _Nonnull s_nonnull
;
156 s_nonnull
= ReturnSmartNullable(); // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
157 s_nonnull
= {ReturnSmartNullable()};
158 TakeSmartNonnull(ReturnSmartNullable()); // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
161 void ConditionalExpr(bool c
) {
163 struct Derived
: Base
{};
166 Base
* _Nonnull nonnullB
;
167 Base
* _Nullable nullableB
;
168 Derived
* _Nonnull nonnullD
;
169 Derived
* _Nullable nullableD
;
171 p
= c
? nonnullB
: nonnullD
;
172 p
= c
? nonnullB
: nullableD
; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}}
173 p
= c
? nullableB
: nonnullD
; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}}
174 p
= c
? nullableB
: nullableD
; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}}
175 p
= c
? nonnullD
: nonnullB
;
176 p
= c
? nonnullD
: nullableB
; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}}
177 p
= c
? nullableD
: nonnullB
; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}}
178 p
= c
? nullableD
: nullableB
; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}}
181 void arraysInLambdas() {
183 auto simple
= [](int [_Nonnull
2]) {};
184 simple(nullptr); // expected-warning {{null passed to a callee that requires a non-null argument}}
185 auto nested
= [](void *_Nullable
[_Nonnull
2]) {};
186 nested(nullptr); // expected-warning {{null passed to a callee that requires a non-null argument}}
187 auto nestedBad
= [](int [2][_Nonnull
2]) {}; // expected-error {{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'int[2]'}}
189 auto withTypedef
= [](INTS _Nonnull
) {};
190 withTypedef(nullptr); // expected-warning {{null passed to a callee that requires a non-null argument}}
191 auto withTypedefBad
= [](INTS _Nonnull
[2]) {}; // expected-error {{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'INTS' (aka 'int[4]')}}
194 void testNullabilityCompletenessWithTemplate() {
200 template <typename b
> using c
= b _Nullable
; // expected-error {{'_Nullable' cannot be applied to non-pointer type 'a'}}
201 c
<a
>; // expected-note {{in instantiation of template type alias 'c' requested here}}