Author: Aayush Shrivastava
Date: 2026-06-01T19:57:37+02:00
New Revision: 203c0668d4b098714d1748de766e890fe6296891

URL: 
https://github.com/llvm/llvm-project/commit/203c0668d4b098714d1748de766e890fe6296891
DIFF: 
https://github.com/llvm/llvm-project/commit/203c0668d4b098714d1748de766e890fe6296891.diff

LOG: [clang] Fix assertion crash in alloc_size structural equivalence check 
(#199407) (#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.

Added: 
    

Modified: 
    clang/lib/AST/AttrImpl.cpp
    clang/test/Sema/alloc-size.c
    clang/test/Sema/attr-nonnull.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/AttrImpl.cpp b/clang/lib/AST/AttrImpl.cpp
index 87afedba7b4b5..3a379891016f8 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,20 @@ equalAttrArgs(T A1, T A2, StructuralEquivalenceContext 
&Context) {
   return A1 == A2;
 }
 
+template <>
+bool equalAttrArgs<ParamIdx>(ParamIdx P1, ParamIdx P2,
+                             StructuralEquivalenceContext &) {
+  // ParamIdx can be invalid when representing an optional parameter that was
+  // not specified (e.g. the second argument of alloc_size(N)).
+  // ParamIdx::operator== asserts both sides are valid, so guard against the
+  // invalid case before delegating to it.
+  if (P1.isValid() != P2.isValid())
+    return false;
+  if (!P1.isValid())
+    return true;
+  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/alloc-size.c b/clang/test/Sema/alloc-size.c
index 93714894a630a..74e08cb9d22c2 100644
--- a/clang/test/Sema/alloc-size.c
+++ b/clang/test/Sema/alloc-size.c
@@ -58,3 +58,8 @@ int main() {
   my_malloc_fn_pointer_type f3 = fn2;
   my_other_malloc_fn_pointer_type f4 = fn2;
 }
+
+// Regression test for GH199407: structural equivalence of alloc_size attrs
+// with an unset optional ParamIdx must not crash.
+#define GH199407(Ty, Name) _Alignas(Ty) char Name[sizeof(Ty)]
+GH199407(struct GH199407S { float *f(long) __attribute__((alloc_size(1))); }, 
gbuf);  // expected-error 2{{field 'f' declared as a function}} 
expected-error{{redefinition of 'GH199407S'}} expected-note{{previous 
definition is here}}

diff  --git a/clang/test/Sema/attr-nonnull.c b/clang/test/Sema/attr-nonnull.c
index 865348daef10e..54f3cde0d12eb 100644
--- a/clang/test/Sema/attr-nonnull.c
+++ b/clang/test/Sema/attr-nonnull.c
@@ -6,3 +6,8 @@ void f1(int *a1, int *a2, int *a3, int *a4, int *a5, int *a6, 
int *a7,
         int *a15, int *a16) __attribute__((nonnull(1, 2, 3, 4, 5, 6, 7, 8, 9, 
10, 11, 12, 13, 14, 15, 16)));
 
 void f2(void) __attribute__((nonnull())); // expected-warning {{'nonnull' 
attribute applied to function with no pointer arguments}}
+
+// Regression test for GH199407: verify no crash when structural equivalence
+// checks nonnull attrs with VariadicParamIdx (always-valid) elements.
+#define GH199407(Ty, Name) _Alignas(Ty) char Name[sizeof(Ty)]
+GH199407(struct GH199407T { void *g(void *p) __attribute__((nonnull(1))); }, 
gbuf); // expected-error 2{{field 'g' declared as a function}} 
expected-error{{redefinition of 'GH199407T'}} expected-note{{previous 
definition is here}}


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to