[clang] [clang][Sema] Handle alloc_align on all HasFunctionProto declarations (PR #210871)

Mimis Chlympatsos via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 21 22:23:19 PDT 2026


================
@@ -1509,16 +1509,15 @@ 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;
 
   QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex());
   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());
----------------
mimischly7 wrote:

@erichkeane and @AaronBallman thank you for the review. I see the problem. If I understand correctly, `getFunctionOrMethodParam` from `clang/include/clang/Sema/Attr.h` may be reached by `Decl`'s that have an underlying function (more precisely `hasFunctionProto(decl)` is true) but are not one of the three currently handled.

 Following @AaronBallman 's comment I modified `getFunctionOrMethodParam()` to (if we are not dealing with a `FunctionDecl`/`ObjCMethodDecl`/`BlockDecl`) use the `TypeSourceInfo` of the `Decl` to get a `TypeLoc` for the underlying function, which in turn gives us access to the parameter declarations. I decided to get the `FunctionProtoTypeLoc` instead of the superclass `FunctionTypeLoc`, because my understanding is that `FunctionType` has two subclasses `FunctionProtoType` and `FunctionNoProtoType`, and the latter has no info on parameters; so since the function `getFunctionOrMethodParam` is exactly meant to get some parameter it makes more sense to use directly `FunctionProtoType` (this hierarchy and logic is mirrored in the `Loc` counterparts `FunctionTypeLoc`, `FunctionProtoTypeLoc`, and `FunctionNoProtoTypeLoc`).

The logic is "best effort", it handles:
- normal function pointers
- pointer-to-member where the member is a function (e.g. `int (someclass::*memberfunc)(...) = ...;` in cpp)
- reference to function (e.g. `int (&ref)(int, int)` in cpp)
- block pointer (`int (^block)(int);` in objective)



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


More information about the cfe-commits mailing list