diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/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; def err_typecheck_zero_array_size : Error< diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/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()) diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp --- a/clang/lib/Sema/SemaType.cpp +++ b/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()) {