diff options
author | Jordan Rose <jordan_rose@apple.com> | 2016-11-10 23:28:34 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2016-11-10 23:28:34 +0000 |
commit | 16d52a2a723e0a365c79152c7438a60134346d1d (patch) | |
tree | aef612dd1ba33e3ad24e7643288b2ed4a94ba5f8 | |
parent | 3b917fe019fff717f9b92defb8ec14601090381f (diff) | |
download | bcm5719-llvm-16d52a2a723e0a365c79152c7438a60134346d1d.tar.gz bcm5719-llvm-16d52a2a723e0a365c79152c7438a60134346d1d.zip |
Don't require nullability on 'va_list'.
There are many non-portable typedefs, but va_list is one that nobody
ever thinks of as a pointer or an array. (When's the last time you saw
someone check for a NULL va_list?) Make an exception for this one
special type.
Part of rdar://problem/25846421.
llvm-svn: 286522
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 16 | ||||
-rw-r--r-- | clang/test/SemaObjCXX/Inputs/nullability-consistency-arrays.h | 22 |
2 files changed, 37 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 0ae53a13d03..13843da081c 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -3919,8 +3919,22 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, attr->setUsedAsTypeAttr(); } } + + auto isVaList = [&S](QualType T) -> bool { + auto *typedefTy = T->getAs<TypedefType>(); + if (!typedefTy) + return false; + TypedefDecl *vaListTypedef = S.Context.getBuiltinVaListDecl(); + do { + if (typedefTy->getDecl() == vaListTypedef) + return true; + typedefTy = typedefTy->desugar()->getAs<TypedefType>(); + } while (typedefTy); + return false; + }; + if (complainAboutMissingNullability == CAMN_Yes && - T->isArrayType() && !T->getNullability(S.Context) && + T->isArrayType() && !T->getNullability(S.Context) && !isVaList(T) && D.isPrototypeContext() && !hasOuterPointerLikeChunk(D, D.getNumTypeObjects())) { checkNullabilityConsistency(S, SimplePointerKind::Array, diff --git a/clang/test/SemaObjCXX/Inputs/nullability-consistency-arrays.h b/clang/test/SemaObjCXX/Inputs/nullability-consistency-arrays.h index dda35a62305..900930c7a70 100644 --- a/clang/test/SemaObjCXX/Inputs/nullability-consistency-arrays.h +++ b/clang/test/SemaObjCXX/Inputs/nullability-consistency-arrays.h @@ -1,3 +1,5 @@ +#include <stdarg.h> + void firstThingInTheFileThatNeedsNullabilityIsAnArray(int ints[]); #if ARRAYS_CHECKED // expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}} @@ -33,6 +35,26 @@ void testAllOK( void * _Nullable ptrs[_Nonnull], void * _Nullable * _Nullable nestedPtrs[_Nonnull]); +void testVAList(va_list ok); // no warning + +#if __cplusplus +// Carefully construct a test case such that if a platform's va_list is an array +// or pointer type, it gets tested, but otherwise it does not. +template<class T, class F> +struct pointer_like_or { typedef F type; }; +template<class T, class F> +struct pointer_like_or<T*, F> { typedef T *type; }; +template<class T, class F> +struct pointer_like_or<T* const, F> { typedef T * const type; }; +template<class T, class F> +struct pointer_like_or<T[], F> { typedef T type[]; }; +template<class T, class F, unsigned size> +struct pointer_like_or<T[size], F> { typedef T type[size]; }; + +void testVAListWithNullability( + pointer_like_or<va_list, void*>::type _Nonnull x); // no errors +#endif + void nestedArrays(int x[5][1]) {} #if ARRAYS_CHECKED // expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}} |