[PATCH] D136603: [analyzer] Model cast after LValueToRValueBitCasts

Gabor Marton via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 25 08:28:12 PDT 2022


martong added a comment.

I am not sure, if the `ExprEngine::VisitCast` is the proper place to add these new modifications and call SValBuilder's evalCast. I think it might be better positioned in `RegionStoreManager::getBinding`. Considering, we already do a cast evaluation for certain kind of memregions there before returning with the stored value. (Actually, this is again a legacy hack, which is needed because we do not emit all SymbolCasts and thus we store the SVals with an improper type).

  if (const FieldRegion* FR = dyn_cast<FieldRegion>(R))
    return svalBuilder.evalCast(getBindingForField(B, FR), T, QualType{});
  
  if (const ElementRegion* ER = dyn_cast<ElementRegion>(R)) {
    // FIXME: Here we actually perform an implicit conversion from the loaded
    // value to the element type.  Eventually we want to compose these values
    // more intelligently.  For example, an 'element' can encompass multiple
    // bound regions (e.g., several bound bytes), or could be a subset of
    // a larger value.
    return svalBuilder.evalCast(getBindingForElement(B, ER), T, QualType{});
  }
  
  if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R)) {
    // FIXME: Here we actually perform an implicit conversion from the loaded
    // value to the ivar type.  What we should model is stores to ivars
    // that blow past the extent of the ivar.  If the address of the ivar is
    // reinterpretted, it is possible we stored a different value that could
    // fit within the ivar.  Either we need to cast these when storing them
    // or reinterpret them lazily (as we do here).
    return svalBuilder.evalCast(getBindingForObjCIvar(B, IVR), T, QualType{});
  }
  
  if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
    // FIXME: Here we actually perform an implicit conversion from the loaded
    // value to the variable type.  What we should model is stores to variables
    // that blow past the extent of the variable.  If the address of the
    // variable is reinterpretted, it is possible we stored a different value
    // that could fit within the variable.  Either we need to cast these when
    // storing them or reinterpret them lazily (as we do here).
    return svalBuilder.evalCast(getBindingForVar(B, VR), T, QualType{});
  }

I think a new if block for `SymRegion` should be put here to continue the hack.



================
Comment at: clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp:301-315
+      ExplodedNodeSet Tmp;
+      evalLocation(Tmp, CastE, CastE, subExprNode, state, *Location, true);
+      if (Tmp.empty())
+        return;
+
+      // Proceed with the load.
+      StmtNodeBuilder Bldr(Tmp, Dst, *currBldrCtx);
----------------
I think it might be possible to refactor `evalLoad` by returning with a `tuple` or with a special `struct`. I guess you should return a vector of `SVal`s as one tuple member. Then you could reuse the function in both cases before calling `generateNode` on the result. But, this might be a code that is too complicated, I'll let you decide if this is worth the hassle to avoid the code repetition.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D136603/new/

https://reviews.llvm.org/D136603



More information about the cfe-commits mailing list