https://github.com/iamaayushrivastava created https://github.com/llvm/llvm-project/pull/199980
Fixes #199407 Remove ParamIdx from the `USE_DEFAULT_EQUALITY` default-comparison path and add an explicit `equalAttrArgs<ParamIdx>` specialization that safely handles invalid (unset) values. >From 4ea38e25881de5ec9b5e84872a79e5f902eac72d Mon Sep 17 00:00:00 2001 From: Aayush Shrivastava <[email protected]> Date: Wed, 27 May 2026 19:02:22 +0530 Subject: [PATCH] [clang] Fix crash comparing invalid ParamIdx in alloc_size structural equivalence --- clang/lib/AST/AttrImpl.cpp | 17 +++++++++++++++-- clang/test/Sema/gh199407.c | 7 +++++++ 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 clang/test/Sema/gh199407.c diff --git a/clang/lib/AST/AttrImpl.cpp b/clang/lib/AST/AttrImpl.cpp index 87afedba7b4b5..c14b2137c8408 100644 --- a/clang/lib/AST/AttrImpl.cpp +++ b/clang/lib/AST/AttrImpl.cpp @@ -291,8 +291,8 @@ namespace { // - VariadicOMPInteropInfoArgument #define USE_DEFAULT_EQUALITY \ (std::is_same_v<T, StringRef> || std::is_same_v<T, VersionTuple> || \ - std::is_same_v<T, IdentifierInfo *> || std::is_same_v<T, ParamIdx> || \ - std::is_same_v<T, char *> || std::is_enum_v<T> || std::is_integral_v<T>) + std::is_same_v<T, IdentifierInfo *> || std::is_same_v<T, char *> || \ + std::is_enum_v<T> || std::is_integral_v<T>) template <class T> typename std::enable_if_t<!USE_DEFAULT_EQUALITY, bool> @@ -306,6 +306,19 @@ equalAttrArgs(T A1, T A2, StructuralEquivalenceContext &Context) { return A1 == A2; } +// ParamIdx has an explicit specialization because it can be invalid (when +// representing an optional parameter that was not specified). Two invalid +// ParamIdx values compare equal; an invalid value is not equal to any valid +// one. ParamIdx::operator== asserts both sides are valid, so we must guard +// against the invalid case here before delegating to operator==. +template <> +bool equalAttrArgs<ParamIdx>(ParamIdx P1, ParamIdx P2, + StructuralEquivalenceContext &) { + if (!P1.isValid() || !P2.isValid()) + return P1.isValid() == P2.isValid(); + return P1 == P2; +} + template <class T> bool equalAttrArgs(T *A1_B, T *A1_E, T *A2_B, T *A2_E, StructuralEquivalenceContext &Context) { diff --git a/clang/test/Sema/gh199407.c b/clang/test/Sema/gh199407.c new file mode 100644 index 0000000000000..15f86657f7d3a --- /dev/null +++ b/clang/test/Sema/gh199407.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -std=c23 -fsyntax-only -verify %s + +// Regression test for https://github.com/llvm/llvm-project/issues/199407 + +#define FOO(Ty, Name) alignas(Ty) char Name[sizeof(Ty)] + +FOO(struct S { float *malloc(long) __attribute__((alloc_size(1))); }, buffer); // expected-error 2{{field 'malloc' declared as a function}} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
