Author: Aaron Ballman
Date: 2025-04-01T07:56:36-04:00
New Revision: 41b83b48e37aa0c7f9e0458638567f37d6dbc924

URL: 
https://github.com/llvm/llvm-project/commit/41b83b48e37aa0c7f9e0458638567f37d6dbc924
DIFF: 
https://github.com/llvm/llvm-project/commit/41b83b48e37aa0c7f9e0458638567f37d6dbc924.diff

LOG: No longer assert on incorrect attribute argument index (#133766)

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

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Sema/Sema.h
    clang/lib/Sema/SemaDeclAttr.cpp
    clang/test/Sema/attr-args.c

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c034b925cddc6..75a173a48e67e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -298,6 +298,15 @@ 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.,
+  .. code-block:: c
+
+    __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}}


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to