blob: 8a621d3b5f8354e92c6ee5d3371cbecbc9c52b3e [file] [log] [blame]
Douglas Gregorb4866e82015-06-19 18:13:19 +00001// RUN: %clang_cc1 -fsyntax-only -fblocks -Wnullable-to-nonnull-conversion -Wno-nullability-declspec %s -verify
Douglas Gregor261a89b2015-06-19 17:51:05 +00002
3#if __has_feature(nullability)
4#else
5# error nullability feature should be defined
6#endif
7
8typedef int * int_ptr;
9
10// Parse nullability type specifiers.
Douglas Gregoraea7afd2015-06-24 22:02:08 +000011typedef int * _Nonnull nonnull_int_ptr; // expected-note{{'_Nonnull' specified here}}
12typedef int * _Nullable nullable_int_ptr;
13typedef int * _Null_unspecified null_unspecified_int_ptr;
Douglas Gregor261a89b2015-06-19 17:51:05 +000014
15// Redundant nullability type specifiers.
Douglas Gregoraea7afd2015-06-24 22:02:08 +000016typedef int * _Nonnull _Nonnull redundant_1; // expected-warning{{duplicate nullability specifier '_Nonnull'}}
Douglas Gregor261a89b2015-06-19 17:51:05 +000017
18// Conflicting nullability type specifiers.
Douglas Gregoraea7afd2015-06-24 22:02:08 +000019typedef int * _Nonnull _Nullable conflicting_1; // expected-error{{nullability specifier '_Nonnull' conflicts with existing specifier '_Nullable'}}
20typedef int * _Null_unspecified _Nonnull conflicting_2; // expected-error{{nullability specifier '_Null_unspecified' conflicts with existing specifier '_Nonnull'}}
Douglas Gregor261a89b2015-06-19 17:51:05 +000021
22// Redundant nullability specifiers via a typedef are okay.
Douglas Gregoraea7afd2015-06-24 22:02:08 +000023typedef nonnull_int_ptr _Nonnull redundant_okay_1;
Douglas Gregor261a89b2015-06-19 17:51:05 +000024
25// Conflicting nullability specifiers via a typedef are not.
Douglas Gregoraea7afd2015-06-24 22:02:08 +000026typedef nonnull_int_ptr _Nullable conflicting_2; // expected-error{{nullability specifier '_Nullable' conflicts with existing specifier '_Nonnull'}}
Douglas Gregor261a89b2015-06-19 17:51:05 +000027typedef nonnull_int_ptr nonnull_int_ptr_typedef;
Douglas Gregoraea7afd2015-06-24 22:02:08 +000028typedef nonnull_int_ptr_typedef _Nullable conflicting_2; // expected-error{{nullability specifier '_Nullable' conflicts with existing specifier '_Nonnull'}}
Douglas Gregor261a89b2015-06-19 17:51:05 +000029typedef nonnull_int_ptr_typedef nonnull_int_ptr_typedef_typedef;
Douglas Gregoraea7afd2015-06-24 22:02:08 +000030typedef nonnull_int_ptr_typedef_typedef _Null_unspecified conflicting_3; // expected-error{{nullability specifier '_Null_unspecified' conflicts with existing specifier '_Nonnull'}}
Douglas Gregor261a89b2015-06-19 17:51:05 +000031
32// Nullability applies to all pointer types.
Douglas Gregoraea7afd2015-06-24 22:02:08 +000033typedef int (* _Nonnull function_pointer_type_1)(int, int);
34typedef int (^ _Nonnull block_type_1)(int, int);
Douglas Gregor261a89b2015-06-19 17:51:05 +000035
36// Nullability must be on a pointer type.
Douglas Gregoraea7afd2015-06-24 22:02:08 +000037typedef int _Nonnull int_type_1; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'int'}}
Douglas Gregor261a89b2015-06-19 17:51:05 +000038
39// Nullability can move out to a pointer/block pointer declarator
40// (with a suppressed warning).
Douglas Gregoraea7afd2015-06-24 22:02:08 +000041typedef _Nonnull int * nonnull_int_ptr_2;
42typedef int _Nullable * nullable_int_ptr_2;
43typedef _Nonnull int (* function_pointer_type_2)(int, int);
44typedef _Nonnull int (^ block_type_2)(int, int);
45typedef _Nonnull int * * _Nullable nonnull_int_ptr_ptr_1;
46typedef _Nonnull int *(^ block_type_3)(int, int);
47typedef _Nonnull int *(* function_pointer_type_3)(int, int);
48typedef _Nonnull int_ptr (^ block_type_4)(int, int);
49typedef _Nonnull int_ptr (* function_pointer_type_4)(int, int);
Nikola Smiljanicfa007282015-07-16 01:06:17 +000050typedef void (* function_pointer_type_5)(int_ptr _Nonnull);
Douglas Gregor261a89b2015-06-19 17:51:05 +000051
Douglas Gregoraea7afd2015-06-24 22:02:08 +000052void acceptFunctionPtr(_Nonnull int *(*)(void));
53void acceptBlockPtr(_Nonnull int *(^)(void));
Douglas Gregor261a89b2015-06-19 17:51:05 +000054
55void testBlockFunctionPtrNullability() {
56 float *fp;
Douglas Gregoraea7afd2015-06-24 22:02:08 +000057 fp = (function_pointer_type_3)0; // expected-warning{{from 'function_pointer_type_3' (aka 'int * _Nonnull (*)(int, int)')}}
58 fp = (block_type_3)0; // expected-error{{from incompatible type 'block_type_3' (aka 'int * _Nonnull (^)(int, int)')}}
Nikola Smiljanicfa007282015-07-16 01:06:17 +000059 fp = (function_pointer_type_4)0; // expected-warning{{from 'function_pointer_type_4' (aka 'int * _Nonnull (*)(int, int)')}}
60 fp = (function_pointer_type_5)0; // expected-warning{{from 'function_pointer_type_5' (aka 'void (*)(int * _Nonnull)')}}
Douglas Gregoraea7afd2015-06-24 22:02:08 +000061 fp = (block_type_4)0; // expected-error{{from incompatible type 'block_type_4' (aka 'int_ptr _Nonnull (^)(int, int)')}}
Douglas Gregor261a89b2015-06-19 17:51:05 +000062
63 acceptFunctionPtr(0); // no-warning
64 acceptBlockPtr(0); // no-warning
65}
66
67// Moving nullability where it creates a conflict.
Douglas Gregoraea7afd2015-06-24 22:02:08 +000068typedef _Nonnull int * _Nullable * conflict_int_ptr_ptr_2; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'int'}}
Douglas Gregor261a89b2015-06-19 17:51:05 +000069
70// Nullability is not part of the canonical type.
Douglas Gregoraea7afd2015-06-24 22:02:08 +000071typedef int * _Nonnull ambiguous_int_ptr;
Douglas Gregor261a89b2015-06-19 17:51:05 +000072typedef int * ambiguous_int_ptr;
Douglas Gregoraea7afd2015-06-24 22:02:08 +000073typedef int * _Nullable ambiguous_int_ptr;
Douglas Gregor261a89b2015-06-19 17:51:05 +000074
75// Printing of nullability.
76float f;
Douglas Gregoraea7afd2015-06-24 22:02:08 +000077int * _Nonnull ip_1 = &f; // expected-warning{{incompatible pointer types initializing 'int * _Nonnull' with an expression of type 'float *'}}
Douglas Gregor261a89b2015-06-19 17:51:05 +000078
79// Check printing of nullability specifiers.
80void printing_nullability(void) {
Douglas Gregoraea7afd2015-06-24 22:02:08 +000081 int * _Nonnull iptr;
82 float *fptr = iptr; // expected-warning{{incompatible pointer types initializing 'float *' with an expression of type 'int * _Nonnull'}}
Douglas Gregor261a89b2015-06-19 17:51:05 +000083
Douglas Gregoraea7afd2015-06-24 22:02:08 +000084 int * * _Nonnull iptrptr;
85 float **fptrptr = iptrptr; // expected-warning{{incompatible pointer types initializing 'float **' with an expression of type 'int ** _Nonnull'}}
Douglas Gregor261a89b2015-06-19 17:51:05 +000086
Douglas Gregoraea7afd2015-06-24 22:02:08 +000087 int * _Nullable * _Nonnull iptrptr2;
88 float * *fptrptr2 = iptrptr2; // expected-warning{{incompatible pointer types initializing 'float **' with an expression of type 'int * _Nullable * _Nonnull'}}
Douglas Gregor261a89b2015-06-19 17:51:05 +000089}
Douglas Gregorb4866e82015-06-19 18:13:19 +000090
Douglas Gregoraea7afd2015-06-24 22:02:08 +000091// Check passing null to a _Nonnull argument.
92void accepts_nonnull_1(_Nonnull int *ptr);
93void (*accepts_nonnull_2)(_Nonnull int *ptr);
94void (^accepts_nonnull_3)(_Nonnull int *ptr);
Douglas Gregorb4866e82015-06-19 18:13:19 +000095
96void test_accepts_nonnull_null_pointer_literal() {
97 accepts_nonnull_1(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
98 accepts_nonnull_2(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
99 accepts_nonnull_3(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
100}
101
Douglas Gregoraea7afd2015-06-24 22:02:08 +0000102// Check returning nil from a _Nonnull-returning function.
103_Nonnull int *returns_int_ptr(int x) {
Douglas Gregorb4866e82015-06-19 18:13:19 +0000104 if (x) {
105 return 0; // expected-warning{{null returned from function that requires a non-null return value}}
106 }
107
Douglas Gregoraea7afd2015-06-24 22:02:08 +0000108 return (_Nonnull int *)0;
Douglas Gregorb4866e82015-06-19 18:13:19 +0000109}
110
111// Check nullable-to-nonnull conversions.
Douglas Gregoraea7afd2015-06-24 22:02:08 +0000112void nullable_to_nonnull(_Nullable int *ptr) {
Douglas Gregorb4866e82015-06-19 18:13:19 +0000113 int *a = ptr; // okay
Douglas Gregoraea7afd2015-06-24 22:02:08 +0000114 _Nonnull int *b = ptr; // expected-warning{{implicit conversion from nullable pointer 'int * _Nullable' to non-nullable pointer type 'int * _Nonnull'}}
Douglas Gregorb4866e82015-06-19 18:13:19 +0000115}