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

Reply via email to