From 9969f6c3052c0683f17a78ab6f223b1db84b6fe8 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Thu, 10 Nov 2016 23:28:34 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@286522 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaType.cpp | 16 +++++++++++++- .../Inputs/nullability-consistency-arrays.h | 22 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 0ae53a13d0..13843da081 100644 --- a/lib/Sema/SemaType.cpp +++ b/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(); + if (!typedefTy) + return false; + TypedefDecl *vaListTypedef = S.Context.getBuiltinVaListDecl(); + do { + if (typedefTy->getDecl() == vaListTypedef) + return true; + typedefTy = typedefTy->desugar()->getAs(); + } 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/test/SemaObjCXX/Inputs/nullability-consistency-arrays.h b/test/SemaObjCXX/Inputs/nullability-consistency-arrays.h index dda35a6230..900930c7a7 100644 --- a/test/SemaObjCXX/Inputs/nullability-consistency-arrays.h +++ b/test/SemaObjCXX/Inputs/nullability-consistency-arrays.h @@ -1,3 +1,5 @@ +#include + 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 +struct pointer_like_or { typedef F type; }; +template +struct pointer_like_or { typedef T *type; }; +template +struct pointer_like_or { typedef T * const type; }; +template +struct pointer_like_or { typedef T type[]; }; +template +struct pointer_like_or { typedef T type[size]; }; + +void testVAListWithNullability( + pointer_like_or::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)}} -- 2.40.0