https://github.com/mimischly7 updated 
https://github.com/llvm/llvm-project/pull/210871

>From be2659958856b404d4c1272eee341205197eb65c Mon Sep 17 00:00:00 2001
From: Mimis Chlympatsos <[email protected]>
Date: Mon, 20 Jul 2026 23:55:59 -0400
Subject: [PATCH 1/3] [clang][Sema] Handle alloc_align on all HasFunctionProto
 declarations

---
 clang/lib/Sema/SemaDeclAttr.cpp                      |  5 ++---
 clang/test/CodeGen/xfail-alloc-align-fn-pointers.cpp | 10 ----------
 clang/test/Sema/alloc-align-attr.c                   |  5 +++++
 clang/test/SemaCXX/alloc-align-attr.cpp              |  7 +++++++
 clang/test/SemaObjC/alloc-align-attr.m               |  8 ++++++++
 5 files changed, 22 insertions(+), 13 deletions(-)
 delete mode 100644 clang/test/CodeGen/xfail-alloc-align-fn-pointers.cpp
 create mode 100644 clang/test/SemaObjC/alloc-align-attr.m

diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 1b272b5416860..2716b5cf6528e 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1509,8 +1509,7 @@ void Sema::AddAllocAlignAttr(Decl *D, const 
AttributeCommonInfo &CI,
   }
 
   ParamIdx Idx;
-  const auto *FuncDecl = cast<FunctionDecl>(D);
-  if (!checkFunctionOrMethodParameterIndex(FuncDecl, CI,
+  if (!checkFunctionOrMethodParameterIndex(D, CI,
                                            /*AttrArgNum=*/1, ParamExpr, Idx))
     return;
 
@@ -1518,7 +1517,7 @@ void Sema::AddAllocAlignAttr(Decl *D, const 
AttributeCommonInfo &CI,
   if (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
       !Ty->isAlignValT()) {
     Diag(ParamExpr->getBeginLoc(), diag::err_attribute_integers_only)
-        << CI << FuncDecl->getParamDecl(Idx.getASTIndex())->getSourceRange();
+        << CI << getFunctionOrMethodParamRange(D, Idx.getASTIndex());
     return;
   }
 
diff --git a/clang/test/CodeGen/xfail-alloc-align-fn-pointers.cpp 
b/clang/test/CodeGen/xfail-alloc-align-fn-pointers.cpp
deleted file mode 100644
index 80067500284b1..0000000000000
--- a/clang/test/CodeGen/xfail-alloc-align-fn-pointers.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-
-// RUN: %clang_cc1 %s
-
-// FIXME: These should not crash!
-// XFAIL: *
-
-void aa_fn_ptr(char* (*member)(char*)  __attribute__((alloc_align(1))));
-
-struct Test;
-void aa_member_fn_ptr(char* (Test::*member)(char*)  
__attribute__((alloc_align(1))));
diff --git a/clang/test/Sema/alloc-align-attr.c 
b/clang/test/Sema/alloc-align-attr.c
index 377c4387814d1..ac1df240d2c72 100644
--- a/clang/test/Sema/alloc-align-attr.c
+++ b/clang/test/Sema/alloc-align-attr.c
@@ -3,8 +3,13 @@
 // return values
 void test_void_alloc_align(void) __attribute__((alloc_align(1))); // 
expected-warning {{'alloc_align' attribute only applies to return values that 
are pointers}}
 void *test_ptr_alloc_align(unsigned long long a) 
__attribute__((alloc_align(1))); // no-warning
+void *(*test_fn_ptr_alloc_align)(unsigned long long) 
__attribute__((alloc_align(1))); // no-warning
 
 int j __attribute__((alloc_align(1))); // expected-warning {{'alloc_align' 
attribute only applies to non-K&R-style functions}}
+// GH122058
+struct InvalidFunctionField {
+  void *f(unsigned long long) __attribute__((alloc_align(1))); // 
expected-error {{field 'f' declared as a function}}
+};
 void *test_no_params_zero(void) __attribute__((alloc_align(0))); // 
expected-error {{'alloc_align' attribute parameter 1 is out of bounds}}
 void *test_no_params(void) __attribute__((alloc_align(1))); // expected-error 
{{'alloc_align' attribute parameter 1 is out of bounds}}
 void *test_incorrect_param_type(float a) __attribute__((alloc_align(1))); // 
expected-error {{'alloc_align' attribute argument may only refer to a function 
parameter of integer type}}
diff --git a/clang/test/SemaCXX/alloc-align-attr.cpp 
b/clang/test/SemaCXX/alloc-align-attr.cpp
index ccc75369b8cfb..1cefa26fb076f 100644
--- a/clang/test/SemaCXX/alloc-align-attr.cpp
+++ b/clang/test/SemaCXX/alloc-align-attr.cpp
@@ -59,3 +59,10 @@ void foo() {
   f<int>(0); // expected-note {{in instantiation of function template 
specialization 'GH26612::f<int>' requested here}}
 }
 } // namespace GH26612
+
+void test_function_pointer(
+    char *(*member)(char *) __attribute__((alloc_align(1)))); // 
expected-error {{'alloc_align' attribute argument may only refer to a function 
parameter of integer type}}
+
+struct Test;
+void test_member_function_pointer(
+    char *(Test::*member)(char *) __attribute__((alloc_align(1)))); // 
expected-error {{'alloc_align' attribute argument may only refer to a function 
parameter of integer type}}
diff --git a/clang/test/SemaObjC/alloc-align-attr.m 
b/clang/test/SemaObjC/alloc-align-attr.m
new file mode 100644
index 0000000000000..4180774c6e19d
--- /dev/null
+++ b/clang/test/SemaObjC/alloc-align-attr.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// expected-no-diagnostics
+
+@interface AllocAlignMethod
+- (void *)allocate:(unsigned long)alignment
+    __attribute__((alloc_align(1)));
+@end

>From daba8325e33ff89ae9b00ed1d0cc61146f02a7bb Mon Sep 17 00:00:00 2001
From: Mimis Chlympatsos <[email protected]>
Date: Wed, 22 Jul 2026 00:53:20 -0400
Subject: [PATCH 2/3] Update getFunctionOrMethodParam to handle Decl's which
 have underlying FunctionProtoType but are not one of FunctionDecl,
 ObjCMethodDecl, and BlockDecl. Needed for correct source range calculation
 invoked by AddAllocAlignAttr.

---
 clang/include/clang/Sema/Attr.h       | 32 +++++++++++++++++++++++++++
 clang/test/Misc/attr-source-range.cpp | 25 ++++++++++++++++++++-
 2 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Sema/Attr.h b/clang/include/clang/Sema/Attr.h
index 5836231818eec..eb24067d35668 100644
--- a/clang/include/clang/Sema/Attr.h
+++ b/clang/include/clang/Sema/Attr.h
@@ -19,6 +19,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/Basic/AttributeCommonInfo.h"
 #include "clang/Basic/DiagnosticSema.h"
 #include "clang/Basic/SourceLocation.h"
@@ -69,6 +70,10 @@ inline unsigned getFunctionOrMethodNumParams(const Decl *D) {
   return cast<ObjCMethodDecl>(D)->param_size();
 }
 
+/// getFunctionOrMethodParam - Return parameter declaration for the given index
+/// of the passed Decl, which must have a FunctionProtoType. When the Decl is
+/// not a FunctionDecl/ObjCMethodDecl/BlockDecl, do best effort to find
+/// underlying FunctionProtoType using the Decl's TypeSourceInfo.
 inline const ParmVarDecl *getFunctionOrMethodParam(const Decl *D,
                                                    unsigned Idx) {
   if (const auto *FD = dyn_cast<FunctionDecl>(D))
@@ -77,6 +82,33 @@ inline const ParmVarDecl *getFunctionOrMethodParam(const 
Decl *D,
     return MD->getParamDecl(Idx);
   if (const auto *BD = dyn_cast<BlockDecl>(D))
     return BD->getParamDecl(Idx);
+
+  // Handle declarations that do not directly own parameters but have an
+  // underlying FunctionProtoType (e.g. function pointers).
+  const TypeSourceInfo *TSI = nullptr;
+  if (const auto *DD = dyn_cast<DeclaratorDecl>(D))
+    TSI = DD->getTypeSourceInfo();
+  else if (const auto *TD = dyn_cast<TypedefNameDecl>(D))
+    TSI = TD->getTypeSourceInfo();
+
+  if (!TSI)
+    return nullptr;
+
+  TypeLoc TL = TSI->getTypeLoc().getUnqualifiedLoc();
+
+  if (auto PTL = TL.getAsAdjusted<PointerTypeLoc>())
+    TL = PTL.getPointeeLoc();
+  else if (auto MPTL = TL.getAsAdjusted<MemberPointerTypeLoc>())
+    TL = MPTL.getPointeeLoc();
+  else if (auto RTL = TL.getAsAdjusted<ReferenceTypeLoc>())
+    TL = RTL.getPointeeLoc();
+  else if (auto BPTL = TL.getAsAdjusted<BlockPointerTypeLoc>())
+    TL = BPTL.getPointeeLoc();
+
+  if (auto FPTL = TL.getAsAdjusted<FunctionProtoTypeLoc>())
+    if (Idx < FPTL.getNumParams())
+      return FPTL.getParam(Idx);
+
   return nullptr;
 }
 
diff --git a/clang/test/Misc/attr-source-range.cpp 
b/clang/test/Misc/attr-source-range.cpp
index d5540ad64fa56..04484ea88df4b 100644
--- a/clang/test/Misc/attr-source-range.cpp
+++ b/clang/test/Misc/attr-source-range.cpp
@@ -1,4 +1,4 @@
-// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-print-source-range-info %s 
2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -fblocks -fsyntax-only 
-fdiagnostics-print-source-range-info %s 2>&1 | FileCheck %s
 
 void f(int i) __attribute__((format_arg(1)));
 // CHECK: attr-source-range.cpp:3:30:{3:41-3:42}{3:8-3:13}
@@ -14,3 +14,26 @@ void i(int j) __attribute__((nonnull(1)));
 
 void j(__attribute__((nonnull)) int i);
 // CHECK: attr-source-range.cpp:15:23:{15:8-15:38}
+
+void alloc_align_function_pointer(
+    char *(*fn)(char *) __attribute__((alloc_align(1))));
+// CHECK: 
attr-source-range.cpp:[[@LINE-1]]:52:{[[@LINE-1]]:17-[[@LINE-1]]:23}: error: 
'alloc_align' attribute argument may only refer to a function parameter of 
integer type
+
+// A top-level qualifier wraps the PointerTypeLoc in a QualifiedTypeLoc. Make
+// sure parameter lookup strips that wrapper before finding 
FunctionProtoTypeLoc.
+void alloc_align_qualified_function_pointer(
+    char *(*const fn)(char *) __attribute__((alloc_align(1))));
+// CHECK: 
attr-source-range.cpp:[[@LINE-1]]:58:{[[@LINE-1]]:23-[[@LINE-1]]:29}: error: 
'alloc_align' attribute argument may only refer to a function parameter of 
integer type
+
+struct S;
+void alloc_align_member_function_pointer(
+    char *(S::*fn)(char *) __attribute__((alloc_align(1))));
+// CHECK: 
attr-source-range.cpp:[[@LINE-1]]:55:{[[@LINE-1]]:20-[[@LINE-1]]:26}: error: 
'alloc_align' attribute argument may only refer to a function parameter of 
integer type
+
+void alloc_align_function_reference(
+    char *(&fn)(char *) __attribute__((alloc_align(1))));
+// CHECK: 
attr-source-range.cpp:[[@LINE-1]]:52:{[[@LINE-1]]:17-[[@LINE-1]]:23}: error: 
'alloc_align' attribute argument may only refer to a function parameter of 
integer type
+
+void alloc_align_block_pointer(
+    char *(^fn)(char *) __attribute__((alloc_align(1))));
+// CHECK: 
attr-source-range.cpp:[[@LINE-1]]:52:{[[@LINE-1]]:17-[[@LINE-1]]:23}: error: 
'alloc_align' attribute argument may only refer to a function parameter of 
integer type

>From f8bc073490b95f64487698c03c3ad327819834cf Mon Sep 17 00:00:00 2001
From: Mimis Chlympatsos <[email protected]>
Date: Wed, 22 Jul 2026 01:23:34 -0400
Subject: [PATCH 3/3] Update clang/test/SemaCXX/alloc-align-attr.cpp

Co-authored-by: Aaron Ballman <[email protected]>
---
 clang/test/SemaCXX/alloc-align-attr.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/test/SemaCXX/alloc-align-attr.cpp 
b/clang/test/SemaCXX/alloc-align-attr.cpp
index 1cefa26fb076f..631971053298b 100644
--- a/clang/test/SemaCXX/alloc-align-attr.cpp
+++ b/clang/test/SemaCXX/alloc-align-attr.cpp
@@ -62,6 +62,7 @@ void foo() {
 
 void test_function_pointer(
     char *(*member)(char *) __attribute__((alloc_align(1)))); // 
expected-error {{'alloc_align' attribute argument may only refer to a function 
parameter of integer type}}
+    char * (*another_member)(int) __attribute___((alloc_align(1))); // ok
 
 struct Test;
 void test_member_function_pointer(

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

Reply via email to