chrisbazley created this revision. Herald added a project: All. chrisbazley requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Parameter declarations using [] syntax can be written more naturally using an _Optional qualifier than using Clang's _Nullable annotation, e.g. void myfunc(_Optional const char s[]); // s may be a null pointer With the above exception, it isn't useful to declare a non-pointed-to object as _Optional (although so-qualified types exist during expression evaluation). Such declarations are therefore disallowed, like equivalent abuse of the restrict qualifier, to avoid confusion. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D142738 Files: clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaType.cpp Index: clang/lib/Sema/SemaType.cpp =================================================================== --- clang/lib/Sema/SemaType.cpp +++ clang/lib/Sema/SemaType.cpp @@ -5807,6 +5807,16 @@ } } + // Types other than those of a pointed-to object or pointed-to incomplete type + // shall not be _Optional-qualified in a declaration. + if (T.isOptionalQualified() && !IsTypedefName && + (!T->isArrayType() || !D.isPrototypeContext())) { + S.Diag(D.getDeclSpec().getOptionalSpecLoc(), + diag::err_typecheck_invalid_optional_not_pointee) + << T; + Context.getNonOptionalType(T); + } + // Apply any undistributed attributes from the declaration or declarator. ParsedAttributesView NonSlidingAttrs; for (ParsedAttr &AL : D.getDeclarationAttributes()) { Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -5088,6 +5088,13 @@ Diag(DS.getRestrictSpecLoc(), diag::err_typecheck_invalid_restrict_not_pointer_noarg) << DS.getSourceRange(); + + // Types other than those of a pointed-to object or pointed-to incomplete + // type shall not be _Optional-qualified in a declaration. + if (TypeQuals & DeclSpec::TQ_optional) + Diag(DS.getOptionalSpecLoc(), + diag::err_typecheck_invalid_optional_not_pointee_noarg) + << DS.getSourceRange(); } if (DS.isInlineSpecified()) Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5930,6 +5930,10 @@ "restrict requires a pointer or reference">; def err_typecheck_invalid_restrict_invalid_pointee : Error< "pointer to function type %0 may not be 'restrict' qualified">; +def err_typecheck_invalid_optional_not_pointee : Error< + "_Optional is only valid on a pointed-to object or incomplete type (%0 is invalid)">; +def err_typecheck_invalid_optional_not_pointee_noarg : Error< + "_Optional is only valid on a pointed-to object or incomplete type">; def ext_typecheck_zero_array_size : Extension< "zero size arrays are an extension">, InGroup<ZeroLengthArray>; def err_typecheck_zero_array_size : Error<
Index: clang/lib/Sema/SemaType.cpp =================================================================== --- clang/lib/Sema/SemaType.cpp +++ clang/lib/Sema/SemaType.cpp @@ -5807,6 +5807,16 @@ } } + // Types other than those of a pointed-to object or pointed-to incomplete type + // shall not be _Optional-qualified in a declaration. + if (T.isOptionalQualified() && !IsTypedefName && + (!T->isArrayType() || !D.isPrototypeContext())) { + S.Diag(D.getDeclSpec().getOptionalSpecLoc(), + diag::err_typecheck_invalid_optional_not_pointee) + << T; + Context.getNonOptionalType(T); + } + // Apply any undistributed attributes from the declaration or declarator. ParsedAttributesView NonSlidingAttrs; for (ParsedAttr &AL : D.getDeclarationAttributes()) { Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -5088,6 +5088,13 @@ Diag(DS.getRestrictSpecLoc(), diag::err_typecheck_invalid_restrict_not_pointer_noarg) << DS.getSourceRange(); + + // Types other than those of a pointed-to object or pointed-to incomplete + // type shall not be _Optional-qualified in a declaration. + if (TypeQuals & DeclSpec::TQ_optional) + Diag(DS.getOptionalSpecLoc(), + diag::err_typecheck_invalid_optional_not_pointee_noarg) + << DS.getSourceRange(); } if (DS.isInlineSpecified()) Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5930,6 +5930,10 @@ "restrict requires a pointer or reference">; def err_typecheck_invalid_restrict_invalid_pointee : Error< "pointer to function type %0 may not be 'restrict' qualified">; +def err_typecheck_invalid_optional_not_pointee : Error< + "_Optional is only valid on a pointed-to object or incomplete type (%0 is invalid)">; +def err_typecheck_invalid_optional_not_pointee_noarg : Error< + "_Optional is only valid on a pointed-to object or incomplete type">; def ext_typecheck_zero_array_size : Extension< "zero size arrays are an extension">, InGroup<ZeroLengthArray>; def err_typecheck_zero_array_size : Error<
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits