[clang] [analyzer][NFC] Document and centralize the CallEvent argument/parameter index mapping (PR #221252)
DonĂ¡t Nagy via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 11 04:10:18 PDT 2026
================
@@ -466,52 +474,71 @@ static SVal castArgToParamTypeIfNeeded(const CallEvent &Call, unsigned ArgIdx,
return ArgVal;
// Only do this cast if the number arguments at the callsite matches with
- // the parameters at the runtime definition.
+ // the parameters at the runtime definition. Note that this point is only
+ // reached for C functions without a prototype, so the argument indices
+ // and the declared parameter indices coincide.
if (Call.getNumArgs() != Definition->getNumParams())
return UnknownVal();
- const Expr *ArgExpr = Call.getArgExpr(ArgIdx);
- const ParmVarDecl *Param = Definition->getParamDecl(ArgIdx);
+ const ParmVarDecl *Param = Definition->getParamDecl(DeclParamIdx);
return SVB.evalCast(ArgVal, Param->getType(), ArgExpr->getType());
}
+/// Binds the value of a single argument to the region of the parameter it
+/// initializes in the callee's stack frame.
+///
+/// \param ParamDecl the declared parameter initialized by this argument.
+/// \param DeclParamIdx index of \p ParamDecl among the callee's declared
+/// parameters. See CallEvent::getDeclaredParameterIndex().
+static void addParameterValueToBindings(const StackFrame *CalleeSF,
+ CallEvent::BindingsTy &Bindings,
+ SValBuilder &SVB, const CallEvent &Call,
+ const ParmVarDecl *ParamDecl,
+ unsigned DeclParamIdx, unsigned Idx) {
+ assert(ParamDecl && "Formal parameter has no decl?");
+
+ // TODO: Support allocator calls.
+ if (Call.getKind() != CE_CXXAllocator)
+ if (Call.isArgumentConstructedDirectly(Call.getASTArgumentIndex(Idx)))
+ return;
+
+ SVal ArgVal = Call.getArgSVal(Idx);
+ // TODO: Allocators should receive the correct size and possibly alignment,
+ // determined in compile-time but not represented as arg-expressions,
+ // which makes getArgSVal() fail and return UnknownVal.
+ if (ArgVal.isUnknown())
+ return;
+ const Expr *ArgExpr = Call.getArgExpr(Idx);
+ // Cast the argument value to match the type of the parameter in some
+ // edge-cases.
+ ArgVal = castArgToParamTypeIfNeeded(Call, DeclParamIdx, ArgExpr, ArgVal, SVB);
+
+ Loc ParamLoc = SVB.makeLoc(SVB.getRegionManager().getParamVarRegion(
+ Call.getOriginExpr(), DeclParamIdx, CalleeSF));
+ Bindings.emplace_back(ParamLoc,
+ processArgument(ArgVal, ArgExpr, ParamDecl, SVB));
+}
+
static void addParameterValuesToBindings(const StackFrame *CalleeSF,
CallEvent::BindingsTy &Bindings,
SValBuilder &SVB,
const CallEvent &Call,
ArrayRef<ParmVarDecl *> parameters) {
- MemRegionManager &MRMgr = SVB.getRegionManager();
-
- // If the function has fewer parameters than the call has arguments, we simply
- // do not bind any values to them.
- unsigned NumArgs = Call.getNumArgs();
- unsigned Idx = 0;
- ArrayRef<ParmVarDecl*>::iterator I = parameters.begin(), E = parameters.end();
- for (; I != E && Idx < NumArgs; ++I, ++Idx) {
- assert(*I && "Formal parameter has no decl?");
-
- // TODO: Support allocator calls.
- if (Call.getKind() != CE_CXXAllocator)
- if (Call.isArgumentConstructedDirectly(Call.getASTArgumentIndex(Idx)))
- continue;
-
- // TODO: Allocators should receive the correct size and possibly alignment,
- // determined in compile-time but not represented as arg-expressions,
- // which makes getArgSVal() fail and return UnknownVal.
- SVal ArgVal = Call.getArgSVal(Idx);
- const Expr *ArgExpr = Call.getArgExpr(Idx);
-
- if (ArgVal.isUnknown())
+ for (unsigned Idx = 0, NumArgs = Call.getNumArgs(); Idx != NumArgs; ++Idx) {
+ // An argument that doesn't initialize a declared parameter, such as the
+ // object argument of an overloaded operator call.
----------------
NagyDonat wrote:
Good point, you're right that it is mentioned there.
https://github.com/llvm/llvm-project/pull/221252
More information about the cfe-commits
mailing list