https://github.com/ChenMiaoi created https://github.com/llvm/llvm-project/pull/228873
`HandleSwiftAttr` checks the first argument with `checkStringLiteralArgumentAttr` without validating the argument count. Unlike declaration attributes, this path does not go through `checkCommonAttributeFeatures`, so a missing argument causes an out-of-bounds access in `ParsedAttr::getArg`. For example: ```c int * __attribute__((__swift_attr__)) a; ``` Before this change, compiling this code crashes. In assertion-enabled builds, it fails in `ParsedAttr::getArg` with: ```text Assertion `Arg < NumArgs && "Arg access out of range!"' failed. ``` Check that the attribute has exactly one argument in `HandleSwiftAttr` before reading it so that the same code produces a diagnostic instead: ```text error: '__swift_attr__' attribute takes one argument ``` Fixes #227549 >From 8e8619b7b04a609c081053904e392d778092567f Mon Sep 17 00:00:00 2001 From: Chen Miao <[email protected]> Date: Sun, 4 Oct 2026 19:30:03 +0800 Subject: [PATCH] [clang][Sema] Check swift_attr argument count in type contexts `HandleSwiftAttr` checks the first argument with `checkStringLiteralArgumentAttr` without validating the argument count. Unlike declaration attributes, this path does not go through `checkCommonAttributeFeatures`, so a missing argument causes an out-of-bounds access in `ParsedAttr::getArg`. For example: ```c int * __attribute__((__swift_attr__)) a; ``` Before this change, compiling this code crashes. In assertion-enabled builds, it fails in `ParsedAttr::getArg` with: ```text Assertion `Arg < NumArgs && "Arg access out of range!"' failed. ``` Check that the attribute has exactly one argument in `HandleSwiftAttr` before reading it so that the same code produces a diagnostic instead: ```text error: '__swift_attr__' attribute takes one argument ``` Fixes #227549 --- clang/lib/Sema/SemaType.cpp | 5 +++++ clang/test/Sema/attr-swift_attr.c | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 clang/test/Sema/attr-swift_attr.c diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 037583575d19f..fa47870da61a7 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -7431,6 +7431,11 @@ static void HandleSwiftAttr(TypeProcessingState &State, TypeAttrLocation TAL, } } + if (!PAttr.checkExactlyNumArgs(S, 1)) { + PAttr.setInvalid(); + return; + } + StringRef Str; if (!S.checkStringLiteralArgumentAttr(PAttr, 0, Str)) { PAttr.setInvalid(); diff --git a/clang/test/Sema/attr-swift_attr.c b/clang/test/Sema/attr-swift_attr.c new file mode 100644 index 0000000000000..a8e3c4f6755d2 --- /dev/null +++ b/clang/test/Sema/attr-swift_attr.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -x c++ -fsyntax-only -verify %s + +// Check argument validation when the attribute is attached to a pointer type. +// A missing argument must be diagnosed without crashing (regression for +// https://github.com/llvm/llvm-project/issues/227549). +int * __attribute__((__swift_attr__)) missing; // expected-error {{'__swift_attr__' attribute takes one argument}} +int * __attribute__((swift_attr())) empty; // expected-error {{'swift_attr' attribute takes one argument}} +int * __attribute__((swift_attr("@A", "@B"))) extra; // expected-error {{'swift_attr' attribute takes one argument}} +int * __attribute__((swift_attr(1))) non_string; // expected-error {{expected string literal as argument of 'swift_attr' attribute}} +int * __attribute__((swift_attr("@A"))) valid; + +// Declaration attributes should continue to use the common argument checks. +__attribute__((swift_attr)) int decl_missing; // expected-error {{'swift_attr' attribute takes one argument}} +__attribute__((swift_attr("@A", "@B"))) int decl_extra; // expected-error {{'swift_attr' attribute takes one argument}} +__attribute__((swift_attr("@A"))) int decl_valid; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
