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
8 #include "nullability-completeness.h"
10 typedef decltype(nullptr) nullptr_t
;
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' (aka 'std::nullptr_t')}}
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
;
25 // Adding non-null via a template.
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 'std::nullptr_t'}}
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}}
36 typedef AddNonNull
<int>::type nonnull_non_pointer_1
; // expected-note{{in instantiation of template class 'AddNonNull<int>' requested here}}
38 // Non-null checking within a template.
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
;
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>'}}
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
;
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}}
66 template<void FP(_Nonnull
int*)>
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}}
71 template void test_accepts_nonnull_null_pointer_literal_template
<&accepts_nonnull_4
>(); // expected-note{{instantiation of function template specialization}}
73 void TakeNonnull(void *_Nonnull
);
74 // Check different forms of assignment to a nonull type from a nullable one.
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'}}
85 TakeNonnull(nullable
); //expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull}}
86 TakeNonnull(nonnull
); // OK
89 void *_Nullable
ReturnNullable();
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'}}
100 TakeNonnull(ReturnNullable()); //expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull}}
103 void ConditionalExpr(bool c
) {
105 struct Derived
: Base
{};
108 Base
* _Nonnull nonnullB
;
109 Base
* _Nullable nullableB
;
110 Derived
* _Nonnull nonnullD
;
111 Derived
* _Nullable nullableD
;
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}}
123 void arraysInLambdas() {
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]'}}
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]')}}
136 void testNullabilityCompletenessWithTemplate() {
142 template <typename b
> using c
= b _Nullable
; // expected-error {{'_Nullable' cannot be applied to non-pointer type 'GH60344::a'}}
143 c
<a
>; // expected-note {{in instantiation of template type alias 'c' requested here}}