forked from OSchip/llvm-project
Do not issue -Wnullability-completeness for dependent types that are not written as pointer types.
llvm-svn: 303451
This commit is contained in:
parent
d05a006a53
commit
0a12b90c98
|
@ -2011,10 +2011,11 @@ public:
|
|||
Optional<NullabilityKind> getNullability(const ASTContext &context) const;
|
||||
|
||||
/// Determine whether the given type can have a nullability
|
||||
/// specifier applied to it, i.e., if it is any kind of pointer type
|
||||
/// or a dependent type that could instantiate to any kind of
|
||||
/// pointer type.
|
||||
bool canHaveNullability() const;
|
||||
/// specifier applied to it, i.e., if it is any kind of pointer type.
|
||||
///
|
||||
/// \param ResultIfUnknown The value to return if we don't yet know whether
|
||||
/// this type can have nullability because it is dependent.
|
||||
bool canHaveNullability(bool ResultIfUnknown = true) const;
|
||||
|
||||
/// Retrieve the set of substitutions required when accessing a member
|
||||
/// of the Objective-C receiver type that is declared in the given context.
|
||||
|
|
|
@ -3531,7 +3531,7 @@ Optional<NullabilityKind> Type::getNullability(const ASTContext &context) const
|
|||
} while (true);
|
||||
}
|
||||
|
||||
bool Type::canHaveNullability() const {
|
||||
bool Type::canHaveNullability(bool ResultIfUnknown) const {
|
||||
QualType type = getCanonicalTypeInternal();
|
||||
|
||||
switch (type->getTypeClass()) {
|
||||
|
@ -3559,7 +3559,8 @@ bool Type::canHaveNullability() const {
|
|||
case Type::SubstTemplateTypeParmPack:
|
||||
case Type::DependentName:
|
||||
case Type::DependentTemplateSpecialization:
|
||||
return true;
|
||||
case Type::Auto:
|
||||
return ResultIfUnknown;
|
||||
|
||||
// Dependent template specializations can instantiate to pointer
|
||||
// types unless they're known to be specializations of a class
|
||||
|
@ -3571,12 +3572,7 @@ bool Type::canHaveNullability() const {
|
|||
if (isa<ClassTemplateDecl>(templateDecl))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
// auto is considered dependent when it isn't deduced.
|
||||
case Type::Auto:
|
||||
case Type::DeducedTemplateSpecialization:
|
||||
return !cast<DeducedType>(type.getTypePtr())->isDeduced();
|
||||
return ResultIfUnknown;
|
||||
|
||||
case Type::Builtin:
|
||||
switch (cast<BuiltinType>(type.getTypePtr())->getKind()) {
|
||||
|
@ -3595,7 +3591,7 @@ bool Type::canHaveNullability() const {
|
|||
case BuiltinType::PseudoObject:
|
||||
case BuiltinType::UnknownAny:
|
||||
case BuiltinType::ARCUnbridgedCast:
|
||||
return true;
|
||||
return ResultIfUnknown;
|
||||
|
||||
case BuiltinType::Void:
|
||||
case BuiltinType::ObjCId:
|
||||
|
@ -3614,6 +3610,7 @@ bool Type::canHaveNullability() const {
|
|||
case BuiltinType::OMPArraySection:
|
||||
return false;
|
||||
}
|
||||
llvm_unreachable("unknown builtin type");
|
||||
|
||||
// Non-pointer types.
|
||||
case Type::Complex:
|
||||
|
@ -3629,6 +3626,7 @@ bool Type::canHaveNullability() const {
|
|||
case Type::FunctionProto:
|
||||
case Type::FunctionNoProto:
|
||||
case Type::Record:
|
||||
case Type::DeducedTemplateSpecialization:
|
||||
case Type::Enum:
|
||||
case Type::InjectedClassName:
|
||||
case Type::PackExpansion:
|
||||
|
|
|
@ -3735,16 +3735,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
|||
// inner pointers.
|
||||
complainAboutMissingNullability = CAMN_InnerPointers;
|
||||
|
||||
auto isDependentNonPointerType = [](QualType T) -> bool {
|
||||
// Note: This is intended to be the same check as Type::canHaveNullability
|
||||
// except with all of the ambiguous cases being treated as 'false' rather
|
||||
// than 'true'.
|
||||
return T->isDependentType() && !T->isAnyPointerType() &&
|
||||
!T->isBlockPointerType() && !T->isMemberPointerType();
|
||||
};
|
||||
|
||||
if (T->canHaveNullability() && !T->getNullability(S.Context) &&
|
||||
!isDependentNonPointerType(T)) {
|
||||
if (T->canHaveNullability(/*ResultIfUnknown*/false) &&
|
||||
!T->getNullability(S.Context)) {
|
||||
// Note that we allow but don't require nullability on dependent types.
|
||||
++NumPointersRemaining;
|
||||
}
|
||||
|
@ -3962,7 +3954,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
|||
// If the type itself could have nullability but does not, infer pointer
|
||||
// nullability and perform consistency checking.
|
||||
if (S.CodeSynthesisContexts.empty()) {
|
||||
if (T->canHaveNullability() && !T->getNullability(S.Context)) {
|
||||
if (T->canHaveNullability(/*ResultIfUnknown*/false) &&
|
||||
!T->getNullability(S.Context)) {
|
||||
if (isVaList(T)) {
|
||||
// Record that we've seen a pointer, but do nothing else.
|
||||
if (NumPointersRemaining > 0)
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
template<typename T> struct Template final {
|
||||
int *_Nonnull x;
|
||||
T y;
|
||||
};
|
|
@ -1,10 +1,12 @@
|
|||
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wno-nullability-declspec %s -verify -Wnullable-to-nonnull-conversion
|
||||
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wno-nullability-declspec %s -verify -Wnullable-to-nonnull-conversion -I%S/Inputs
|
||||
|
||||
#if __has_feature(nullability)
|
||||
#else
|
||||
# error nullability feature should be defined
|
||||
#endif
|
||||
|
||||
#include "nullability-completeness.h"
|
||||
|
||||
typedef decltype(nullptr) nullptr_t;
|
||||
|
||||
class X {
|
||||
|
@ -130,3 +132,7 @@ void arraysInLambdas() {
|
|||
withTypedef(nullptr); // expected-warning {{null passed to a callee that requires a non-null argument}}
|
||||
auto withTypedefBad = [](INTS _Nonnull[2]) {}; // expected-error {{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'INTS' (aka 'int [4]')}}
|
||||
}
|
||||
|
||||
void testNullabilityCompletenessWithTemplate() {
|
||||
Template<int*> tip;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue