brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.5 KiB · ca45a0d Raw
203 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wno-nullability-declspec %s -verify -Wnullable-to-nonnull-conversion -I%S/Inputs2 3#if __has_feature(nullability)4#else5#  error nullability feature should be defined6#endif7#if __has_feature(nullability_on_classes)8#else9#  error smart-pointer feature should be defined10#endif11 12#include "nullability-completeness.h"13 14typedef decltype(nullptr) nullptr_t;15 16class X {17};18 19// Nullability applies to all pointer types.20typedef int (X::* _Nonnull member_function_type_1)(int);21typedef int X::* _Nonnull member_data_type_1;22typedef nullptr_t _Nonnull nonnull_nullptr_t; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'nullptr_t' (aka 'std::nullptr_t')}}23 24// Nullability can move into member pointers (this is suppressing a warning).25typedef _Nonnull int (X::* member_function_type_2)(int);26typedef int (X::* _Nonnull member_function_type_3)(int);27typedef _Nonnull int X::* member_data_type_2;28 29// Adding non-null via a template.30template<typename T>31struct AddNonNull {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'}}35};36 37typedef AddNonNull<int *>::type nonnull_int_ptr_1;38typedef AddNonNull<int * _Nullable>::type nonnull_int_ptr_2; // FIXME: check that it was overridden39typedef AddNonNull<nullptr_t>::type nonnull_int_ptr_3; // expected-note{{in instantiation of template class}}40 41typedef AddNonNull<int>::type nonnull_non_pointer_1; // expected-note{{in instantiation of template class 'AddNonNull<int>' requested here}}42 43// Nullability on C++ class types (smart pointers).44struct NotPtr{};45typedef AddNonNull<NotPtr>::type nonnull_non_pointer_2; // expected-note{{in instantiation}}46struct _Nullable SmartPtr{47  SmartPtr();48  SmartPtr(nullptr_t);49  SmartPtr(const SmartPtr&);50  SmartPtr(SmartPtr&&);51  SmartPtr &operator=(const SmartPtr&);52  SmartPtr &operator=(SmartPtr&&);53};54typedef AddNonNull<SmartPtr>::type nonnull_smart_pointer_1;55template<class> struct _Nullable SmartPtrTemplate{};56typedef AddNonNull<SmartPtrTemplate<int>>::type nonnull_smart_pointer_2;57namespace 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...)> {};61} }62typedef AddNonNull<std::unique_ptr<int>>::type nonnull_smart_pointer_3;63typedef AddNonNull<std::function<int()>>::type nonnull_smart_pointer_4;64 65class Derived : public SmartPtr {};66Derived _Nullable x; // expected-error {{'_Nullable' cannot be applied}}67class DerivedPrivate : private SmartPtr {};68DerivedPrivate _Nullable y; // expected-error {{'_Nullable' cannot be applied}}69 70// Non-null checking within a template.71template<typename T>72struct AddNonNull2 {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;77 78  // Don't move past a dependent type even if we know that nullability79  // 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>'}}81};82 83// Check passing null to a _Nonnull argument.84void (*accepts_nonnull_1)(_Nonnull int *ptr);85void (*& accepts_nonnull_2)(_Nonnull int *ptr) = accepts_nonnull_1;86void (X::* accepts_nonnull_3)(_Nonnull int *ptr);87void accepts_nonnull_4(_Nonnull int *ptr);88void (&accepts_nonnull_5)(_Nonnull int *ptr) = accepts_nonnull_4;89void accepts_nonnull_6(SmartPtr _Nonnull);90 91void 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}}97 98  accepts_nonnull_6(nullptr); // expected-warning{{null passed to a callee that requires a non-null argument}}99}100 101template<void FP(_Nonnull int*)>102void test_accepts_nonnull_null_pointer_literal_template() {103  FP(0); // expected-warning{{null passed to a callee that requires a non-null argument}}104}105 106template void test_accepts_nonnull_null_pointer_literal_template<&accepts_nonnull_4>(); // expected-note{{instantiation of function template specialization}}107 108void TakeNonnull(void *_Nonnull);109void TakeSmartNonnull(SmartPtr _Nonnull);110// Check different forms of assignment to a nonull type from a nullable one.111void 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); // OK122  nonnull = (void *_Nonnull)nullable; // explicit cast OK123 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); // OK134  s_nonnull = (SmartPtr _Nonnull)s_nullable; // explicit cast OK135  s_nonnull = static_cast<SmartPtr _Nonnull>(s_nullable); // explicit cast OK136}137 138void *_Nullable ReturnNullable();139SmartPtr _Nullable ReturnSmartNullable();140 141void 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}}150 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'}}159}160 161void ConditionalExpr(bool c) {162  struct Base {};163  struct Derived : Base {};164 165  Base * _Nonnull p;166  Base * _Nonnull nonnullB;167  Base * _Nullable nullableB;168  Derived * _Nonnull nonnullD;169  Derived * _Nullable nullableD;170 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}}179}180 181void arraysInLambdas() {182  typedef int INTS[4];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]'}}188 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]')}}192}193 194void testNullabilityCompletenessWithTemplate() {195  Template<int*> tip;196}197 198namespace GH60344 {199class a;200template <typename b> using c = b _Nullable; // expected-error {{'_Nullable' cannot be applied to non-pointer type 'a'}}201c<a>;  // expected-note {{in instantiation of template type alias 'c' requested here}}202}203