diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -77,6 +77,9 @@ - Added support for parameter pack expansion in `clang::annotate`. +- The ``overloadable`` attribute can now be written in all of the syntactic + locations a declaration attribute may appear. Fixes PR53805. + Windows Support --------------- 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 @@ -5237,7 +5237,9 @@ // function is marked with the "overloadable" attribute. Scan // for this attribute now. if (!FTI.NumParams && FTI.isVariadic && !LangOpts.CPlusPlus) - if (!D.getAttributes().hasAttribute(ParsedAttr::AT_Overloadable)) + if (!D.getAttributes().hasAttribute(ParsedAttr::AT_Overloadable) && + !D.getDeclSpec().getAttributes().hasAttribute( + ParsedAttr::AT_Overloadable)) S.Diag(FTI.getEllipsisLoc(), diag::err_ellipsis_first_param); if (FTI.NumParams && FTI.Params[0].Param == nullptr) { diff --git a/clang/test/Sema/overloadable.c b/clang/test/Sema/overloadable.c --- a/clang/test/Sema/overloadable.c +++ b/clang/test/Sema/overloadable.c @@ -248,3 +248,14 @@ // if take_fn is passed a void (**)(void *), we'll get a warning. take_fn(fn); } + +// PR53805 +// We previously failed to consider the attribute being written before the +// declaration when considering whether to allow a variadic signature with no +// other parameters, and so we handled these cases differently. +__attribute__((overloadable)) void can_overload_1(...); // ok, was previously rejected +void can_overload_2(...) __attribute__((overloadable)); // ok +[[clang::overloadable]] void can_overload_3(...); // ok, was previously rejected +void can_overload_4 [[clang::overloadable]] (...); // ok +void cannot_overload(...) [[clang::overloadable]]; // expected-error {{ISO C requires a named parameter before '...'}} \ + // expected-error {{'overloadable' attribute cannot be applied to types}}