]> granicus.if.org Git - clang/commitdiff
Don't require nullability on 'va_list'.
authorJordan Rose <jordan_rose@apple.com>
Thu, 10 Nov 2016 23:28:34 +0000 (23:28 +0000)
committerJordan Rose <jordan_rose@apple.com>
Thu, 10 Nov 2016 23:28:34 +0000 (23:28 +0000)
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
test/SemaObjCXX/Inputs/nullability-consistency-arrays.h

index 0ae53a13d03281c656e7c0d4df82b71eb49a2764..13843da081c285263bf71664bf8b873200fb09a5 100644 (file)
@@ -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,
index dda35a62305af775184d43b093f9990a565c3ee7..900930c7a705c3dada34fa634a75057fce44e875 100644 (file)
@@ -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)}}