llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Aayush Shrivastava (iamaayushrivastava)

<details>
<summary>Changes</summary>

Fixes #<!-- -->199407

Remove ParamIdx from the `USE_DEFAULT_EQUALITY` default-comparison path and add 
an explicit `equalAttrArgs&lt;ParamIdx&gt;` specialization that safely handles 
invalid (unset) values.


---
Full diff: https://github.com/llvm/llvm-project/pull/199980.diff


2 Files Affected:

- (modified) clang/lib/AST/AttrImpl.cpp (+15-2) 
- (added) clang/test/Sema/gh199407.c (+7) 


``````````diff
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}}

``````````

</details>


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

Reply via email to