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
