You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从clang::ento::nonloc::ConcreteInt类型SVal获取源MemRegion?

在Clang静态分析器中追踪ConcreteInt的源MemRegion方案

核心思路:在初始化阶段绑定常量与来源区域

当变量被初始化为常量时,Clang静态分析器默认会生成nonloc::ConcreteInt,不会保留它的来源信息。要解决这个问题,得在变量初始化的早期阶段就把常量和对应的源MemRegion绑定,而不是等到checkBind阶段再补救,具体可以从这几个方向入手:

1. 用checkPostStmt拦截变量声明语句

针对DeclStmt类型的语句,直接从AST里拿到变量的初始化表达式:

  • 如果初始化的是另一个变量(比如int a = b;),直接提取这个变量对应的MemRegion;
  • 如果是字面量(比如int a = 5;),就把这个字面量和当前变量的MemRegion关联起来,存在ProgramState里,后续在checkBind里就能通过这个关联找到来源。

代码示例:

void checkPostStmt(const DeclStmt *DS, CheckerContext &C) const {
  for (const auto *D : DS->decls()) {
    if (const auto *VD = dyn_cast<VarDecl>(D)) {
      if (VD->hasInit()) {
        const Expr *InitE = VD->getInit();
        SVal InitVal = C.getSVal(InitE);
        MemRegion *VarRegion = C.getSVal(VD).getAsRegion();
        if (const auto *CI = InitVal.getAs<nonloc::ConcreteInt>()) {
          // 用自定义的State扩展存储关联关系
          ProgramStateRef NewState = C.getState()->set<ConcreteIntRegionMap>(CI->getValue(), VarRegion);
          C.addTransition(NewState);
        }
      }
    }
  }
}

2. 自定义符号包裹ConcreteInt,携带来源信息

如果要更严谨的路径敏感追踪,可以自己写一个SymExpr的子类,把ConcreteInt和对应的MemRegion打包在一起。在初始化变量的时候,不用默认的ConcreteInt,而是用这个自定义符号,后续分析时只要识别出这个自定义符号,就能拿到来源区域。

步骤大概是:

  • 定义ConcreteIntWithRegionSym类,继承SymExpr,包含ConcreteInt和MemRegion*成员;
  • 在变量初始化回调里,把原本的ConcreteInt替换成这个自定义符号;
  • 在checkBind或者其他检查点里,判断符号类型,提取里面的MemRegion。

3. 尝试从SVal的符号依赖链溯源

有些情况下,ConcreteInt可能隐含符号依赖(比如常量来自宏或者其他变量的传递),可以试试调用SVal::getAsSymbol()或者遍历符号依赖树,看看能不能找到关联的MemRegion。不过这个方法对纯字面量初始化的场景作用不大,更适合有变量传递的情况。

注意点

  • 所有修改都不能破坏原有路径敏感分析的流程,只能在现有ProgramState上添加自定义数据;
  • 全局变量、静态变量的初始化要单独处理,比如在checkBeginFunction或者checkEndTranslationUnit回调里做;
  • 存储关联关系的时候,一定要用Clang提供的ProgramState扩展机制,别自己乱存导致内存泄漏或者状态不一致。

内容的提问来源于stack exchange,提问作者Gruber

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 18:22:31