llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-codegen Author: None (dyung) <details> <summary>Changes</summary> 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 --- Patch is 28.27 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/87041.diff 21 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (-15) - (modified) clang/include/clang/Basic/Attr.td (+1-2) - (modified) clang/include/clang/Basic/AttrDocs.td (-25) - (modified) clang/include/clang/Basic/Features.def (-1) - (modified) clang/include/clang/Parse/Parser.h (-1) - (modified) clang/include/clang/Sema/Sema.h (-3) - (modified) clang/lib/AST/Type.cpp (+10-19) - (modified) clang/lib/CodeGen/CGCall.cpp (+1-2) - (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+1-2) - (modified) clang/lib/Parse/ParseDeclCXX.cpp (+9-24) - (modified) clang/lib/Sema/SemaAttr.cpp (-12) - (modified) clang/lib/Sema/SemaChecking.cpp (-9) - (modified) clang/lib/Sema/SemaDecl.cpp (+1-3) - (modified) clang/lib/Sema/SemaDeclAttr.cpp (-18) - (modified) clang/lib/Sema/SemaInit.cpp (-5) - (modified) clang/lib/Sema/SemaOverload.cpp (-7) - (modified) clang/lib/Sema/SemaTemplate.cpp (-1) - (modified) clang/lib/Sema/SemaType.cpp (+4-14) - (modified) clang/test/Sema/nullability.c (-2) - (modified) clang/test/SemaCXX/nullability.cpp (+2-60) - (modified) clang/test/SemaObjCXX/nullability-consistency.mm (-1) ``````````diff 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 differently - // 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 d52b... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/87041 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits