[clang] [analyzer] Simplify CallEvent castArgToParamTypeIfNeeded (PR #120981)

Balazs Benics via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 23 08:43:50 PST 2024


https://github.com/steakhal created https://github.com/llvm/llvm-project/pull/120981

I noticed recently that this code (that I wrote xD) uses the `getRuntimeDefinition()` which isn't quite necessary for the simple task this function was designed for.

Why would it be better not using this API here?
I'm experimenting with improving how virtual functions are inlined, where depending on our ability of deducing the dynamic type of the object we may end up with inaccurate type information. Such inaccuracy would mean that we may have multiple runtime definitions. After that, this code would become ambiguous.

To resolve this, I decided to refactor this and use a simpler - but equivalent approach.

>From 08e384f0827c023bd8e0bf755ce6ea73e6ac6fa2 Mon Sep 17 00:00:00 2001
From: Balazs Benics <benicsbalazs at gmail.com>
Date: Mon, 23 Dec 2024 17:38:11 +0100
Subject: [PATCH] [analyzer] Simplify CallEvent castArgToParamTypeIfNeeded

I noticed recently that this code (that I wrote xD) uses the
`getRuntimeDefinition()` which isn't quite necessary for the simple task
this function was designed for.

Why would it be better not using this API here?
I'm experimenting with improving how virtual functions are inlined,
where depending on our ability of deducing the dynamic type of the
object we may end up with inaccurate type information.
Such inaccuracy would mean that we may have multiple runtime
definitions. After that, this code would become ambiguous.

To resolve this, I decided to refactor this and use a simpler - but
equivalent approach.
---
 clang/lib/StaticAnalyzer/Core/CallEvent.cpp | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
index 0fdef7487b9814..bb4a39f68280cd 100644
--- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -435,27 +435,27 @@ static SVal processArgument(SVal Value, const Expr *ArgumentExpr,
 /// runtime definition don't match in terms of argument and parameter count.
 static SVal castArgToParamTypeIfNeeded(const CallEvent &Call, unsigned ArgIdx,
                                        SVal ArgVal, SValBuilder &SVB) {
-  const FunctionDecl *RTDecl =
-      Call.getRuntimeDefinition().getDecl()->getAsFunction();
   const auto *CallExprDecl = dyn_cast_or_null<FunctionDecl>(Call.getDecl());
-
-  if (!RTDecl || !CallExprDecl)
+  if (!CallExprDecl)
     return ArgVal;
 
+  const FunctionDecl *Definition = CallExprDecl;
+  Definition->hasBody(Definition);
+
   // The function decl of the Call (in the AST) will not have any parameter
   // declarations, if it was 'only' declared without a prototype. However, the
   // engine will find the appropriate runtime definition - basically a
   // redeclaration, which has a function body (and a function prototype).
-  if (CallExprDecl->hasPrototype() || !RTDecl->hasPrototype())
+  if (CallExprDecl->hasPrototype() || !Definition->hasPrototype())
     return ArgVal;
 
   // Only do this cast if the number arguments at the callsite matches with
   // the parameters at the runtime definition.
-  if (Call.getNumArgs() != RTDecl->getNumParams())
+  if (Call.getNumArgs() != Definition->getNumParams())
     return UnknownVal();
 
   const Expr *ArgExpr = Call.getArgExpr(ArgIdx);
-  const ParmVarDecl *Param = RTDecl->getParamDecl(ArgIdx);
+  const ParmVarDecl *Param = Definition->getParamDecl(ArgIdx);
   return SVB.evalCast(ArgVal, Param->getType(), ArgExpr->getType());
 }
 



More information about the cfe-commits mailing list