https://github.com/AaronBallman updated https://github.com/llvm/llvm-project/pull/133766
>From 9d0fc75e39908c30567b6ebc0e4c4fa5d4863ca0 Mon Sep 17 00:00:00 2001 From: Aaron Ballman <aa...@aaronballman.com> Date: Mon, 31 Mar 2025 13:55:57 -0400 Subject: [PATCH 1/2] No longer assert on incorrect attribute argument index Fixes an assertion when referencing an out-of-bounds parameter via a function attribute whose argument list refers to parameters by index and the function is variadic. e.g., __attribute__ ((__format_arg__(2))) void test (int i, ...) { } Fixes #61635 --- clang/docs/ReleaseNotes.rst | 6 ++++++ clang/include/clang/Sema/Sema.h | 11 ++++++----- clang/lib/Sema/SemaDeclAttr.cpp | 17 ++++++++++++----- clang/test/Sema/attr-args.c | 5 +++++ 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index daad01919ecd4..58a0e78cd2c55 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -298,6 +298,12 @@ Improvements to Clang's diagnostics - Improve the ``-Wundefined-func-template`` warning when a function template is not instantiated due to being unreachable in modules. +- Fixed an assertion when referencing an out-of-bounds parameter via a function + attribute whose argument list refers to parameters by index and the function + is variadic. e.g., + ``__attribute__ ((__format_arg__(2))) void test (int i, ...) { }`` + Fixes #GH61635 + Improvements to Clang's time-trace ---------------------------------- diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index c74e709ce06d2..09168218a9e36 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -4796,10 +4796,10 @@ class Sema final : public SemaBase { /// /// \returns true if IdxExpr is a valid index. template <typename AttrInfo> - bool checkFunctionOrMethodParameterIndex(const Decl *D, const AttrInfo &AI, - unsigned AttrArgNum, - const Expr *IdxExpr, ParamIdx &Idx, - bool CanIndexImplicitThis = false) { + bool checkFunctionOrMethodParameterIndex( + const Decl *D, const AttrInfo &AI, unsigned AttrArgNum, + const Expr *IdxExpr, ParamIdx &Idx, bool CanIndexImplicitThis = false, + bool CanIndexVariadicArguments = false) { assert(isFunctionOrMethodOrBlockForAttrSubject(D)); // In C++ the implicit 'this' function parameter also counts. @@ -4820,7 +4820,8 @@ class Sema final : public SemaBase { } unsigned IdxSource = IdxInt->getLimitedValue(UINT_MAX); - if (IdxSource < 1 || (!IV && IdxSource > NumParams)) { + if (IdxSource < 1 || + ((!IV || !CanIndexVariadicArguments) && IdxSource > NumParams)) { Diag(getAttrLoc(AI), diag::err_attribute_argument_out_of_bounds) << &AI << AttrArgNum << IdxExpr->getSourceRange(); return false; diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 0a8a3e1c49414..6cb6f6d105a32 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1315,7 +1315,10 @@ static void handleNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) { for (unsigned I = 0; I < AL.getNumArgs(); ++I) { Expr *Ex = AL.getArgAsExpr(I); ParamIdx Idx; - if (!S.checkFunctionOrMethodParameterIndex(D, AL, I + 1, Ex, Idx)) + if (!S.checkFunctionOrMethodParameterIndex( + D, AL, I + 1, Ex, Idx, + /*CanIndexImplicitThis=*/false, + /*CanIndexVariadicArguments=*/true)) return; // Is the function argument a pointer type? @@ -5756,13 +5759,17 @@ static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D, } ParamIdx ArgumentIdx; - if (!S.checkFunctionOrMethodParameterIndex(D, AL, 2, AL.getArgAsExpr(1), - ArgumentIdx)) + if (!S.checkFunctionOrMethodParameterIndex( + D, AL, 2, AL.getArgAsExpr(1), ArgumentIdx, + /*CanIndexImplicitThis=*/false, + /*CanIndexVariadicArguments=*/true)) return; ParamIdx TypeTagIdx; - if (!S.checkFunctionOrMethodParameterIndex(D, AL, 3, AL.getArgAsExpr(2), - TypeTagIdx)) + if (!S.checkFunctionOrMethodParameterIndex( + D, AL, 3, AL.getArgAsExpr(2), TypeTagIdx, + /*CanIndexImplicitThis=*/false, + /*CanIndexVariadicArguments=*/true)) return; bool IsPointer = AL.getAttrName()->getName() == "pointer_with_type_tag"; diff --git a/clang/test/Sema/attr-args.c b/clang/test/Sema/attr-args.c index db69a99bdee3b..23815f3a4e675 100644 --- a/clang/test/Sema/attr-args.c +++ b/clang/test/Sema/attr-args.c @@ -24,3 +24,8 @@ inline __attribute__((stdcall(a))) void *f8(void); // expected-error {{'stdcall inline __attribute__((used(a))) void *f9(void); // expected-error {{'used' attribute takes no arguments}} inline __attribute__((unused(a))) void *f10(void); // expected-error {{'unused' attribute takes no arguments}} inline __attribute__((weak(a))) void *f11(void); // expected-error {{'weak' attribute takes no arguments}} + +__attribute__ ((__format_arg__(2))) // expected-error {{'__format_arg__' attribute parameter 1 is out of bounds}} +void test (int, ...); + +void __attribute__ ((alloc_size (2, 3))) *test2(int, ...); // expected-error {{'alloc_size' attribute parameter 1 is out of bounds}} >From 2222aef1748804fac7c999ce325c3d7137a825e9 Mon Sep 17 00:00:00 2001 From: Aaron Ballman <aa...@aaronballman.com> Date: Mon, 31 Mar 2025 14:10:19 -0400 Subject: [PATCH 2/2] Fix documentation build --- clang/docs/ReleaseNotes.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 58a0e78cd2c55..8953f000a1b8c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -301,7 +301,10 @@ Improvements to Clang's diagnostics - Fixed an assertion when referencing an out-of-bounds parameter via a function attribute whose argument list refers to parameters by index and the function is variadic. e.g., - ``__attribute__ ((__format_arg__(2))) void test (int i, ...) { }`` + .. code-block:: c + + __attribute__ ((__format_arg__(2))) void test (int i, ...) { } + Fixes #GH61635 Improvements to Clang's time-trace _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits