blob: f0aa13be8fa38726032b91f24bfa88f45b30ae24 [file] [log] [blame]
Douglas Gregor261a89b2015-06-19 17:51:05 +00001// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wno-nullability-declspec %s -verify
2
3typedef decltype(nullptr) nullptr_t;
4
5class X {
6};
7
8// Nullability applies to all pointer types.
9typedef int (X::* __nonnull member_function_type_1)(int);
10typedef int X::* __nonnull member_data_type_1;
11typedef nullptr_t __nonnull nonnull_nullptr_t; // expected-error{{nullability specifier '__nonnull' cannot be applied to non-pointer type 'nullptr_t'}}
12
13// Nullability can move into member pointers (this is suppressing a warning).
14typedef __nonnull int (X::* member_function_type_2)(int);
15typedef int (X::* __nonnull member_function_type_3)(int);
16typedef __nonnull int X::* member_data_type_2;
17
18// Adding non-null via a template.
19template<typename T>
20struct AddNonNull {
21 typedef __nonnull T type; // expected-error{{nullability specifier '__nonnull' cannot be applied to non-pointer type 'int'}}
22 // expected-error@-1{{nullability specifier '__nonnull' cannot be applied to non-pointer type 'nullptr_t'}}
23};
24
25typedef AddNonNull<int *>::type nonnull_int_ptr_1;
26typedef AddNonNull<int * __nullable>::type nonnull_int_ptr_2; // FIXME: check that it was overridden
27typedef AddNonNull<nullptr_t>::type nonnull_int_ptr_3; // expected-note{{in instantiation of template class}}
28
29typedef AddNonNull<int>::type nonnull_non_pointer_1; // expected-note{{in instantiation of template class 'AddNonNull<int>' requested here}}
30
31// Non-null checking within a template.
32template<typename T>
33struct AddNonNull2 {
34 typedef __nonnull AddNonNull<T> invalid1; // expected-error{{nullability specifier '__nonnull' cannot be applied to non-pointer type 'AddNonNull<T>'}}
35 typedef __nonnull AddNonNull2 invalid2; // expected-error{{nullability specifier '__nonnull' cannot be applied to non-pointer type 'AddNonNull2<T>'}}
36 typedef __nonnull AddNonNull2<T> invalid3; // expected-error{{nullability specifier '__nonnull' cannot be applied to non-pointer type 'AddNonNull2<T>'}}
37 typedef __nonnull typename AddNonNull<T>::type okay1;
38
39 // Don't move past a dependent type even if we know that nullability
40 // cannot apply to that specific dependent type.
41 typedef __nonnull AddNonNull<T> (*invalid4); // expected-error{{nullability specifier '__nonnull' cannot be applied to non-pointer type 'AddNonNull<T>'}}
42};
Douglas Gregorb4866e82015-06-19 18:13:19 +000043
44// Check passing null to a __nonnull argument.
45void (*accepts_nonnull_1)(__nonnull int *ptr);
46void (*& accepts_nonnull_2)(__nonnull int *ptr) = accepts_nonnull_1;
47void (X::* accepts_nonnull_3)(__nonnull int *ptr);
48void accepts_nonnull_4(__nonnull int *ptr);
49void (&accepts_nonnull_5)(__nonnull int *ptr) = accepts_nonnull_4;
50
51void test_accepts_nonnull_null_pointer_literal(X *x) {
52 accepts_nonnull_1(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
53 accepts_nonnull_2(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
54 (x->*accepts_nonnull_3)(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
55 accepts_nonnull_4(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
56 accepts_nonnull_5(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
57}
58
59template<void FP(__nonnull int*)>
60void test_accepts_nonnull_null_pointer_literal_template() {
61 FP(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
62}
63
64template void test_accepts_nonnull_null_pointer_literal_template<&accepts_nonnull_4>(); // expected-note{{instantiation of function template specialization}}