[clang] 28760b6 - Revert "Reapply "[clang][nullability] allow _Nonnull etc on nullable class types (#82705)"" (#87041)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 29 00:50:15 PDT 2024
Author: dyung
Date: 2024-03-29T00:50:11-07:00
New Revision: 28760b63bbf9e267713957105a8d17091fb0d20e
URL: https://github.com/llvm/llvm-project/commit/28760b63bbf9e267713957105a8d17091fb0d20e
DIFF: https://github.com/llvm/llvm-project/commit/28760b63bbf9e267713957105a8d17091fb0d20e.diff
LOG: Revert "Reapply "[clang][nullability] allow _Nonnull etc on nullable class types (#82705)"" (#87041)
This reverts commit bbbcc1d99d08855069f4501c896c43a6d4d7b598.
This change is causing the following build bots to fail due to a missing
header file:
- https://lab.llvm.org/buildbot/#/builders/188/builds/43765
- https://lab.llvm.org/buildbot/#/builders/176/builds/9428
- https://lab.llvm.org/buildbot/#/builders/187/builds/14696
- https://lab.llvm.org/buildbot/#/builders/186/builds/15551
- https://lab.llvm.org/buildbot/#/builders/182/builds/9413
- https://lab.llvm.org/buildbot/#/builders/245/builds/22507
- https://lab.llvm.org/buildbot/#/builders/258/builds/16026
- https://lab.llvm.org/buildbot/#/builders/249/builds/17221
- https://lab.llvm.org/buildbot/#/builders/38/builds/18566
- https://lab.llvm.org/buildbot/#/builders/214/builds/11735
- https://lab.llvm.org/buildbot/#/builders/231/builds/21947
- https://lab.llvm.org/buildbot/#/builders/230/builds/26675
- https://lab.llvm.org/buildbot/#/builders/57/builds/33922
- https://lab.llvm.org/buildbot/#/builders/124/builds/10311
- https://lab.llvm.org/buildbot/#/builders/109/builds/86173
- https://lab.llvm.org/buildbot/#/builders/280/builds/1043
- https://lab.llvm.org/buildbot/#/builders/283/builds/440
- https://lab.llvm.org/buildbot/#/builders/247/builds/16034
- https://lab.llvm.org/buildbot/#/builders/139/builds/62423
- https://lab.llvm.org/buildbot/#/builders/216/builds/36718
- https://lab.llvm.org/buildbot/#/builders/259/builds/2039
- https://lab.llvm.org/buildbot/#/builders/36/builds/44091
- https://lab.llvm.org/buildbot/#/builders/272/builds/12629
- https://lab.llvm.org/buildbot/#/builders/271/builds/6020
- https://lab.llvm.org/buildbot/#/builders/236/builds/10319
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/include/clang/Basic/Features.def
clang/include/clang/Parse/Parser.h
clang/include/clang/Sema/Sema.h
clang/lib/AST/Type.cpp
clang/lib/CodeGen/CGCall.cpp
clang/lib/CodeGen/CodeGenFunction.cpp
clang/lib/Parse/ParseDeclCXX.cpp
clang/lib/Sema/SemaAttr.cpp
clang/lib/Sema/SemaChecking.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/lib/Sema/SemaInit.cpp
clang/lib/Sema/SemaOverload.cpp
clang/lib/Sema/SemaTemplate.cpp
clang/lib/Sema/SemaType.cpp
clang/test/Sema/nullability.c
clang/test/SemaCXX/nullability.cpp
clang/test/SemaObjCXX/nullability-consistency.mm
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c303eee7be7927..232de0d7d8bb73 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -253,21 +253,6 @@ Attribute Changes in Clang
added a new extension query ``__has_extension(swiftcc)`` corresponding to the
``__attribute__((swiftcc))`` attribute.
-- The ``_Nullable`` and ``_Nonnull`` family of type attributes can now apply
- to certain C++ class types, such as smart pointers:
- ``void useObject(std::unique_ptr<Object> _Nonnull obj);``.
-
- This works for standard library types including ``unique_ptr``, ``shared_ptr``,
- and ``function``. See
- `the attribute reference documentation <https://llvm.org/docs/AttributeReference.html#nullability-attributes>`_
- for the full list.
-
-- The ``_Nullable`` attribute can be applied to C++ class declarations:
- ``template <class T> class _Nullable MySmartPointer {};``.
-
- This allows the ``_Nullable`` and ``_Nonnull`` family of type attributes to
- apply to this class.
-
Improvements to Clang's diagnostics
-----------------------------------
- Clang now applies syntax highlighting to the code snippets it
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 6584460cf5685e..80e607525a0a37 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2178,10 +2178,9 @@ def TypeNonNull : TypeAttr {
let Documentation = [TypeNonNullDocs];
}
-def TypeNullable : DeclOrTypeAttr {
+def TypeNullable : TypeAttr {
let Spellings = [CustomKeyword<"_Nullable">];
let Documentation = [TypeNullableDocs];
-// let Subjects = SubjectList<[CXXRecord], ErrorDiag>;
}
def TypeNullableResult : TypeAttr {
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 0ca4ea377fc36a..3ea4d676b4f89d 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -4151,20 +4151,6 @@ non-underscored keywords. For example:
@property (assign, nullable) NSView *superview;
@property (readonly, nonnull) NSArray *subviews;
@end
-
-As well as built-in pointer types, the nullability attributes can be attached
-to C++ classes marked with the ``_Nullable`` attribute.
-
-The following C++ standard library types are considered nullable:
-``unique_ptr``, ``shared_ptr``, ``auto_ptr``, ``exception_ptr``, ``function``,
-``move_only_function`` and ``coroutine_handle``.
-
-Types should be marked nullable only where the type itself leaves nullability
-ambiguous. For example, ``std::optional`` is not marked ``_Nullable``, because
-``optional<int> _Nullable`` is redundant and ``optional<int> _Nonnull`` is
-not a useful type. ``std::weak_ptr`` is not nullable, because its nullability
-can change with no visible modification, so static annotation is unlikely to be
-unhelpful.
}];
}
@@ -4199,17 +4185,6 @@ The ``_Nullable`` nullability qualifier indicates that a value of the
int fetch_or_zero(int * _Nullable ptr);
a caller of ``fetch_or_zero`` can provide null.
-
-The ``_Nullable`` attribute on classes indicates that the given class can
-represent null values, and so the ``_Nullable``, ``_Nonnull`` etc qualifiers
-make sense for this type. For example:
-
- .. code-block:: c
-
- class _Nullable ArenaPointer { ... };
-
- ArenaPointer _Nonnull x = ...;
- ArenaPointer _Nullable y = nullptr;
}];
}
diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def
index fe4d1c4afcca65..b41aadc73f205d 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -94,7 +94,6 @@ EXTENSION(define_target_os_macros,
FEATURE(enumerator_attributes, true)
FEATURE(nullability, true)
FEATURE(nullability_on_arrays, true)
-FEATURE(nullability_on_classes, true)
FEATURE(nullability_nullable_result, true)
FEATURE(memory_sanitizer,
LangOpts.Sanitize.hasOneOf(SanitizerKind::Memory |
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 580bf2a5d79df5..bba8ef4ff01739 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -3014,7 +3014,6 @@ class Parser : public CodeCompletionHandler {
void DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
SourceLocation SkipExtendedMicrosoftTypeAttributes();
void ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs);
- void ParseNullabilityClassAttributes(ParsedAttributes &attrs);
void ParseBorlandTypeAttributes(ParsedAttributes &attrs);
void ParseOpenCLKernelAttributes(ParsedAttributes &attrs);
void ParseOpenCLQualifiers(ParsedAttributes &Attrs);
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 3fcb963e752f3a..3a1abd4c7892b8 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -1655,9 +1655,6 @@ class Sema final {
/// Add [[gsl::Pointer]] attributes for std:: types.
void inferGslPointerAttribute(TypedefNameDecl *TD);
- /// Add _Nullable attributes for std:: types.
- void inferNullableClassAttribute(CXXRecordDecl *CRD);
-
enum PragmaOptionsAlignKind {
POAK_Native, // #pragma options align=native
POAK_Natural, // #pragma options align=natural
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 47fdbfe21e5884..8f3e26d4601921 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -4642,15 +4642,16 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
case Type::Auto:
return ResultIfUnknown;
- // Dependent template specializations could instantiate to pointer types.
+ // Dependent template specializations can instantiate to pointer
+ // types unless they're known to be specializations of a class
+ // template.
case Type::TemplateSpecialization:
- // If it's a known class template, we can already check if it's nullable.
- if (TemplateDecl *templateDecl =
- cast<TemplateSpecializationType>(type.getTypePtr())
- ->getTemplateName()
- .getAsTemplateDecl())
- if (auto *CTD = dyn_cast<ClassTemplateDecl>(templateDecl))
- return CTD->getTemplatedDecl()->hasAttr<TypeNullableAttr>();
+ if (TemplateDecl *templateDecl
+ = cast<TemplateSpecializationType>(type.getTypePtr())
+ ->getTemplateName().getAsTemplateDecl()) {
+ if (isa<ClassTemplateDecl>(templateDecl))
+ return false;
+ }
return ResultIfUnknown;
case Type::Builtin:
@@ -4707,17 +4708,6 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
}
llvm_unreachable("unknown builtin type");
- case Type::Record: {
- const RecordDecl *RD = cast<RecordType>(type)->getDecl();
- // For template specializations, look only at primary template attributes.
- // This is a consistent regardless of whether the instantiation is known.
- if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
- return CTSD->getSpecializedTemplate()
- ->getTemplatedDecl()
- ->hasAttr<TypeNullableAttr>();
- return RD->hasAttr<TypeNullableAttr>();
- }
-
// Non-pointer types.
case Type::Complex:
case Type::LValueReference:
@@ -4735,6 +4725,7 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
case Type::DependentAddressSpace:
case Type::FunctionProto:
case Type::FunctionNoProto:
+ case Type::Record:
case Type::DeducedTemplateSpecialization:
case Type::Enum:
case Type::InjectedClassName:
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 4a4426d13e7b6b..a5fe39633679b9 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4379,8 +4379,7 @@ void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType,
NNAttr = getNonNullAttr(AC.getDecl(), PVD, ArgType, ArgNo);
bool CanCheckNullability = false;
- if (SanOpts.has(SanitizerKind::NullabilityArg) && !NNAttr && PVD &&
- !PVD->getType()->isRecordType()) {
+ if (SanOpts.has(SanitizerKind::NullabilityArg) && !NNAttr && PVD) {
auto Nullability = PVD->getType()->getNullability();
CanCheckNullability = Nullability &&
*Nullability == NullabilityKind::NonNull &&
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index fa3f2972458971..44103884940fd9 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -989,8 +989,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
// return value. Initialize the flag to 'true' and refine it in EmitParmDecl.
if (SanOpts.has(SanitizerKind::NullabilityReturn)) {
auto Nullability = FnRetTy->getNullability();
- if (Nullability && *Nullability == NullabilityKind::NonNull &&
- !FnRetTy->isRecordType()) {
+ if (Nullability && *Nullability == NullabilityKind::NonNull) {
if (!(SanOpts.has(SanitizerKind::ReturnsNonnullAttribute) &&
CurCodeDecl && CurCodeDecl->getAttr<ReturnsNonNullAttr>()))
RetValNullabilityPrecondition =
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 861a25dc5103c1..63fe678cbb29e2 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -1502,15 +1502,6 @@ void Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) {
}
}
-void Parser::ParseNullabilityClassAttributes(ParsedAttributes &attrs) {
- while (Tok.is(tok::kw__Nullable)) {
- IdentifierInfo *AttrName = Tok.getIdentifierInfo();
- auto Kind = Tok.getKind();
- SourceLocation AttrNameLoc = ConsumeToken();
- attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, Kind);
- }
-}
-
/// Determine whether the following tokens are valid after a type-specifier
/// which could be a standalone declaration. This will conservatively return
/// true if there's any doubt, and is appropriate for insert-';' fixits.
@@ -1692,21 +1683,15 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
ParsedAttributes attrs(AttrFactory);
// If attributes exist after tag, parse them.
- for (;;) {
- MaybeParseAttributes(PAKM_CXX11 | PAKM_Declspec | PAKM_GNU, attrs);
- // Parse inheritance specifiers.
- if (Tok.isOneOf(tok::kw___single_inheritance,
- tok::kw___multiple_inheritance,
- tok::kw___virtual_inheritance)) {
- ParseMicrosoftInheritanceClassAttributes(attrs);
- continue;
- }
- if (Tok.is(tok::kw__Nullable)) {
- ParseNullabilityClassAttributes(attrs);
- continue;
- }
- break;
- }
+ MaybeParseAttributes(PAKM_CXX11 | PAKM_Declspec | PAKM_GNU, attrs);
+
+ // Parse inheritance specifiers.
+ if (Tok.isOneOf(tok::kw___single_inheritance, tok::kw___multiple_inheritance,
+ tok::kw___virtual_inheritance))
+ ParseMicrosoftInheritanceClassAttributes(attrs);
+
+ // Allow attributes to precede or succeed the inheritance specifiers.
+ MaybeParseAttributes(PAKM_CXX11 | PAKM_Declspec | PAKM_GNU, attrs);
// Source location used by FIXIT to insert misplaced
// C++11 attributes
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index a5dd158808f26b..0dcf42e4899713 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -215,18 +215,6 @@ void Sema::inferGslOwnerPointerAttribute(CXXRecordDecl *Record) {
inferGslPointerAttribute(Record, Record);
}
-void Sema::inferNullableClassAttribute(CXXRecordDecl *CRD) {
- static llvm::StringSet<> Nullable{
- "auto_ptr", "shared_ptr", "unique_ptr", "exception_ptr",
- "coroutine_handle", "function", "move_only_function",
- };
-
- if (CRD->isInStdNamespace() && Nullable.count(CRD->getName()) &&
- !CRD->hasAttr<TypeNullableAttr>())
- for (Decl *Redecl : CRD->redecls())
- Redecl->addAttr(TypeNullableAttr::CreateImplicit(Context));
-}
-
void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
SourceLocation PragmaLoc) {
PragmaMsStackAction Action = Sema::PSK_Reset;
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index a1ce867248a49b..2e4e18a3ebf759 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -27,7 +27,6 @@
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprOpenMP.h"
#include "clang/AST/FormatString.h"
-#include "clang/AST/IgnoreExpr.h"
#include "clang/AST/NSAPI.h"
#include "clang/AST/NonTrivialTypeVisitor.h"
#include "clang/AST/OperationKinds.h"
@@ -7610,14 +7609,6 @@ bool Sema::getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember,
///
/// Returns true if the value evaluates to null.
static bool CheckNonNullExpr(Sema &S, const Expr *Expr) {
- // Treat (smart) pointers constructed from nullptr as null, whether we can
- // const-evaluate them or not.
- // This must happen first: the smart pointer expr might have _Nonnull type!
- if (isa<CXXNullPtrLiteralExpr>(
- IgnoreExprNodes(Expr, IgnoreImplicitAsWrittenSingleStep,
- IgnoreElidableImplicitConstructorSingleStep)))
- return true;
-
// If the expression has non-null type, it doesn't evaluate to null.
if (auto nullability = Expr->IgnoreImplicit()->getType()->getNullability()) {
if (*nullability == NullabilityKind::NonNull)
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 19a52a2d703796..0bd88ece2aa544 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -18317,10 +18317,8 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
if (PrevDecl)
mergeDeclAttributes(New, PrevDecl);
- if (auto *CXXRD = dyn_cast<CXXRecordDecl>(New)) {
+ if (auto *CXXRD = dyn_cast<CXXRecordDecl>(New))
inferGslOwnerPointerAttribute(CXXRD);
- inferNullableClassAttribute(CXXRD);
- }
// If there's a #pragma GCC visibility in scope, set the visibility of this
// record.
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 8bce04640e748e..f25f3afd0f4af2 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5982,20 +5982,6 @@ static void handleBuiltinAliasAttr(Sema &S, Decl *D,
D->addAttr(::new (S.Context) BuiltinAliasAttr(S.Context, AL, Ident));
}
-static void handleNullableTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- if (AL.isUsedAsTypeAttr())
- return;
-
- if (auto *CRD = dyn_cast<CXXRecordDecl>(D);
- !CRD || !(CRD->isClass() || CRD->isStruct())) {
- S.Diag(AL.getRange().getBegin(), diag::err_attribute_wrong_decl_type_str)
- << AL << AL.isRegularKeywordAttribute() << "classes";
- return;
- }
-
- handleSimpleAttribute<TypeNullableAttr>(S, D, AL);
-}
-
static void handlePreferredTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
if (!AL.hasParsedType()) {
S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
@@ -9947,10 +9933,6 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
case ParsedAttr::AT_UsingIfExists:
handleSimpleAttribute<UsingIfExistsAttr>(S, D, AL);
break;
-
- case ParsedAttr::AT_TypeNullable:
- handleNullableTypeAttr(S, D, AL);
- break;
}
}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 3382d56303d628..dce225a7204da8 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -7079,11 +7079,6 @@ PerformConstructorInitialization(Sema &S,
hasCopyOrMoveCtorParam(S.Context,
getConstructorInfo(Step.Function.FoundDecl));
- // A smart pointer constructed from a nullable pointer is nullable.
- if (NumArgs == 1 && !Kind.isExplicitCast())
- S.diagnoseNullableToNonnullConversion(
- Entity.getType(), Args.front()->getType(), Kind.getLocation());
-
// Determine the arguments required to actually perform the constructor
// call.
if (S.CompleteConstructorCall(Constructor, Step.Type, Args, Loc,
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index de0c2e7399632b..51450e486eaeb4 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -14811,13 +14811,6 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
}
}
- // Check for nonnull = nullable.
- // This won't be caught in the arg's initialization: the parameter to
- // the assignment operator is not marked nonnull.
- if (Op == OO_Equal)
- diagnoseNullableToNonnullConversion(Args[0]->getType(),
- Args[1]->getType(), OpLoc);
-
// Convert the arguments.
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
// Best->Access is only meaningful for class members.
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index de728305d55aa9..e575bb2df97f05 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2171,7 +2171,6 @@ DeclResult Sema::CheckClassTemplate(
AddPushedVisibilityAttribute(NewClass);
inferGslOwnerPointerAttribute(NewClass);
- inferNullableClassAttribute(NewClass);
if (TUK != TUK_Friend) {
// Per C++ [basic.scope.temp]p2, skip the template parameter scopes.
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 2ddc9c0cf5fb5e..fd94caa4e1d449 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -4717,18 +4717,6 @@ static bool DiagnoseMultipleAddrSpaceAttributes(Sema &S, LangAS ASOld,
return false;
}
-// Whether this is a type broadly expected to have nullability attached.
-// These types are affected by `#pragma assume_nonnull`, and missing nullability
-// will be diagnosed with -Wnullability-completeness.
-static bool shouldHaveNullability(QualType T) {
- return T->canHaveNullability(/*ResultIfUnknown=*/false) &&
- // For now, do not infer/require nullability on C++ smart pointers.
- // It's unclear whether the pragma's behavior is useful for C++.
- // e.g. treating type-aliases and template-type-parameters
diff erently
- // from types of declarations can be surprising.
- !isa<RecordType>(T->getCanonicalTypeInternal());
-}
-
static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
QualType declSpecType,
TypeSourceInfo *TInfo) {
@@ -4847,7 +4835,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// inner pointers.
complainAboutMissingNullability = CAMN_InnerPointers;
- if (shouldHaveNullability(T) && !T->getNullability()) {
+ if (T->canHaveNullability(/*ResultIfUnknown*/ false) &&
+ !T->getNullability()) {
// Note that we allow but don't require nullability on dependent types.
++NumPointersRemaining;
}
@@ -5070,7 +5059,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 (shouldHaveNullability(T) && !T->getNullability()) {
+ if (T->canHaveNullability(/*ResultIfUnknown*/ false) &&
+ !T->getNullability()) {
if (isVaList(T)) {
// Record that we've seen a pointer, but do nothing else.
if (NumPointersRemaining > 0)
diff --git a/clang/test/Sema/nullability.c b/clang/test/Sema/nullability.c
index 0401516233b6db..7d193bea46771f 100644
--- a/clang/test/Sema/nullability.c
+++ b/clang/test/Sema/nullability.c
@@ -248,5 +248,3 @@ void arraysInBlocks(void) {
void (^withTypedefBad)(INTS _Nonnull [2]) = // expected-error {{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'INTS' (aka 'int[4]')}}
^(INTS _Nonnull x[2]) {}; // expected-error {{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'INTS' (aka 'int[4]')}}
}
-
-struct _Nullable NotCplusplusClass {}; // expected-error {{'_Nullable' attribute only applies to classes}}
diff --git a/clang/test/SemaCXX/nullability.cpp b/clang/test/SemaCXX/nullability.cpp
index d52ba4efaccdbd..8d0c4dc195a6bd 100644
--- a/clang/test/SemaCXX/nullability.cpp
+++ b/clang/test/SemaCXX/nullability.cpp
@@ -4,10 +4,6 @@
#else
# error nullability feature should be defined
#endif
-#if __has_feature(nullability_on_classes)
-#else
-# error smart-pointer feature should be defined
-#endif
#include "nullability-completeness.h"
@@ -31,7 +27,6 @@ template<typename T>
struct AddNonNull {
typedef _Nonnull T type; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'int'}}
// expected-error at -1{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'std::nullptr_t'}}
- // expected-error at -2{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'NotPtr'}}
};
typedef AddNonNull<int *>::type nonnull_int_ptr_1;
@@ -40,33 +35,6 @@ typedef AddNonNull<nullptr_t>::type nonnull_int_ptr_3; // expected-note{{in inst
typedef AddNonNull<int>::type nonnull_non_pointer_1; // expected-note{{in instantiation of template class 'AddNonNull<int>' requested here}}
-// Nullability on C++ class types (smart pointers).
-struct NotPtr{};
-typedef AddNonNull<NotPtr>::type nonnull_non_pointer_2; // expected-note{{in instantiation}}
-struct _Nullable SmartPtr{
- SmartPtr();
- SmartPtr(nullptr_t);
- SmartPtr(const SmartPtr&);
- SmartPtr(SmartPtr&&);
- SmartPtr &operator=(const SmartPtr&);
- SmartPtr &operator=(SmartPtr&&);
-};
-typedef AddNonNull<SmartPtr>::type nonnull_smart_pointer_1;
-template<class> struct _Nullable SmartPtrTemplate{};
-typedef AddNonNull<SmartPtrTemplate<int>>::type nonnull_smart_pointer_2;
-namespace std { inline namespace __1 {
- template <class> class unique_ptr {};
- template <class> class function;
- template <class Ret, class... Args> class function<Ret(Args...)> {};
-} }
-typedef AddNonNull<std::unique_ptr<int>>::type nonnull_smart_pointer_3;
-typedef AddNonNull<std::function<int()>>::type nonnull_smart_pointer_4;
-
-class Derived : public SmartPtr {};
-Derived _Nullable x; // expected-error {{'_Nullable' cannot be applied}}
-class DerivedPrivate : private SmartPtr {};
-DerivedPrivate _Nullable y; // expected-error {{'_Nullable' cannot be applied}}
-
// Non-null checking within a template.
template<typename T>
struct AddNonNull2 {
@@ -86,7 +54,6 @@ void (*& accepts_nonnull_2)(_Nonnull int *ptr) = accepts_nonnull_1;
void (X::* accepts_nonnull_3)(_Nonnull int *ptr);
void accepts_nonnull_4(_Nonnull int *ptr);
void (&accepts_nonnull_5)(_Nonnull int *ptr) = accepts_nonnull_4;
-void accepts_nonnull_6(SmartPtr _Nonnull);
void test_accepts_nonnull_null_pointer_literal(X *x) {
accepts_nonnull_1(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
@@ -94,8 +61,6 @@ void test_accepts_nonnull_null_pointer_literal(X *x) {
(x->*accepts_nonnull_3)(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
accepts_nonnull_4(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
accepts_nonnull_5(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
-
- accepts_nonnull_6(nullptr); // expected-warning{{null passed to a callee that requires a non-null argument}}
}
template<void FP(_Nonnull int*)>
@@ -106,7 +71,6 @@ void test_accepts_nonnull_null_pointer_literal_template() {
template void test_accepts_nonnull_null_pointer_literal_template<&accepts_nonnull_4>(); // expected-note{{instantiation of function template specialization}}
void TakeNonnull(void *_Nonnull);
-void TakeSmartNonnull(SmartPtr _Nonnull);
// Check
diff erent forms of assignment to a nonull type from a nullable one.
void AssignAndInitNonNull() {
void *_Nullable nullable;
@@ -117,26 +81,12 @@ void AssignAndInitNonNull() {
void *_Nonnull nonnull;
nonnull = nullable; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
nonnull = {nullable}; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
+
TakeNonnull(nullable); //expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull}}
TakeNonnull(nonnull); // OK
- nonnull = (void *_Nonnull)nullable; // explicit cast OK
-
- SmartPtr _Nullable s_nullable;
- SmartPtr _Nonnull s(s_nullable); // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
- SmartPtr _Nonnull s2{s_nullable}; // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
- SmartPtr _Nonnull s3 = {s_nullable}; // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
- SmartPtr _Nonnull s4 = s_nullable; // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
- SmartPtr _Nonnull s_nonnull;
- s_nonnull = s_nullable; // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
- s_nonnull = {s_nullable}; // no warning here - might be nice?
- TakeSmartNonnull(s_nullable); //expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull}}
- TakeSmartNonnull(s_nonnull); // OK
- s_nonnull = (SmartPtr _Nonnull)s_nullable; // explicit cast OK
- s_nonnull = static_cast<SmartPtr _Nonnull>(s_nullable); // explicit cast OK
}
void *_Nullable ReturnNullable();
-SmartPtr _Nullable ReturnSmartNullable();
void AssignAndInitNonNullFromFn() {
void *_Nonnull p(ReturnNullable()); // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
@@ -146,16 +96,8 @@ void AssignAndInitNonNullFromFn() {
void *_Nonnull nonnull;
nonnull = ReturnNullable(); // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
nonnull = {ReturnNullable()}; // expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull'}}
- TakeNonnull(ReturnNullable()); //expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull}}
- SmartPtr _Nonnull s(ReturnSmartNullable()); // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
- SmartPtr _Nonnull s2{ReturnSmartNullable()}; // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
- SmartPtr _Nonnull s3 = {ReturnSmartNullable()}; // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
- SmartPtr _Nonnull s4 = ReturnSmartNullable(); // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
- SmartPtr _Nonnull s_nonnull;
- s_nonnull = ReturnSmartNullable(); // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
- s_nonnull = {ReturnSmartNullable()};
- TakeSmartNonnull(ReturnSmartNullable()); // expected-warning{{implicit conversion from nullable pointer 'SmartPtr _Nullable' to non-nullable pointer type 'SmartPtr _Nonnull'}}
+ TakeNonnull(ReturnNullable()); //expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull}}
}
void ConditionalExpr(bool c) {
diff --git a/clang/test/SemaObjCXX/nullability-consistency.mm b/clang/test/SemaObjCXX/nullability-consistency.mm
index 09c9a84475a939..6921d8b9d3dd5b 100644
--- a/clang/test/SemaObjCXX/nullability-consistency.mm
+++ b/clang/test/SemaObjCXX/nullability-consistency.mm
@@ -9,7 +9,6 @@
#include "nullability-consistency-6.h"
#include "nullability-consistency-7.h"
#include "nullability-consistency-8.h"
-#include "nullability-consistency-smart.h"
#include "nullability-consistency-system.h"
void h1(int *ptr) { } // don't warn
More information about the cfe-commits
mailing list