summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2017-05-19 20:20:13 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2017-05-19 20:20:13 +0000
commit0a12b90c98a76df07bd815a660d1ed5fdc178697 (patch)
treee3298ab2bf8cbfc65ca0bac4b5b55bfee3539412
parentd05a006a537bc5860eec042c2c541ccdbb182a02 (diff)
downloadbcm5719-llvm-0a12b90c98a76df07bd815a660d1ed5fdc178697.tar.gz
bcm5719-llvm-0a12b90c98a76df07bd815a660d1ed5fdc178697.zip
Do not issue -Wnullability-completeness for dependent types that are not written as pointer types.
llvm-svn: 303451
-rw-r--r--clang/include/clang/AST/Type.h9
-rw-r--r--clang/lib/AST/Type.cpp16
-rw-r--r--clang/lib/Sema/SemaType.cpp15
-rw-r--r--clang/test/SemaCXX/Inputs/nullability-completeness.h4
-rw-r--r--clang/test/SemaCXX/nullability.cpp8
5 files changed, 27 insertions, 25 deletions
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index ce1ce54d156..9eb6d81296d 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -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.
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 22d52bcd3f3..1e10094aeee 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -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:
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 1433607e9c7..f8970744389 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -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)
diff --git a/clang/test/SemaCXX/Inputs/nullability-completeness.h b/clang/test/SemaCXX/Inputs/nullability-completeness.h
new file mode 100644
index 00000000000..1b30e1b4d90
--- /dev/null
+++ b/clang/test/SemaCXX/Inputs/nullability-completeness.h
@@ -0,0 +1,4 @@
+template<typename T> struct Template final {
+ int *_Nonnull x;
+ T y;
+};
diff --git a/clang/test/SemaCXX/nullability.cpp b/clang/test/SemaCXX/nullability.cpp
index 160741b1409..99375a9fdde 100644
--- a/clang/test/SemaCXX/nullability.cpp
+++ b/clang/test/SemaCXX/nullability.cpp
@@ -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;
+}
OpenPOWER on IntegriCloud