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

如何在OCLint自定义规则中检查clang::Expr是否为NULL并获取ASTContext

自定义OCLint规则:检查表达式是否为NULL指针常量及ASTContext获取方法

需求场景

需要实现自定义OCLint规则,捕获类似以下的空指针检查语句:

char *str = strdup("Hello, world!");
if (str == NULL) {   // 目标捕获语句
    ...
}

核心问题解决

1. 获取ASTContext

oclint::AbstractASTVisitorRule继承自oclint::AbstractRule,而AbstractRule提供了直接获取ASTContext&的方法astContext(),无需额外复杂操作,在规则类的方法中直接调用即可。

2. 检查表达式是否为NULL指针常量

利用clang::Expr::isNullPointerConstant方法,结合ASTContext完成判断,具体实现步骤如下:

  • 识别二元操作符==(对应clang::BinaryOperator的BO_EQ类型);
  • 忽略表达式的括号和隐式类型转换,避免干扰判断;
  • 检查操作符的任意一侧是否为NULL指针常量;
  • 结合另一侧是否为指针变量引用,匹配目标场景。

代码示例

#include "oclint/AbstractASTVisitorRule.h"
#include "oclint/RuleSet.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"

using namespace clang;
using namespace oclint;

class NullPointerCheckRule : public AbstractASTVisitorRule<NullPointerCheckRule>
{
public:
    const string name() const override { return "null pointer check"; }
    int priority() const override { return 3; }
    int category() const override { return 1; }

    bool VisitBinaryOperator(BinaryOperator *BO)
    {
        // 过滤非等于操作的二元表达式
        if (BO->getOpcode() != BO_EQ)
        {
            return true;
        }

        // 忽略括号和隐式类型转换,获取纯净的左右操作数
        Expr *lhs = BO->getLHS()->IgnoreParenImpCasts();
        Expr *rhs = BO->getRHS()->IgnoreParenImpCasts();

        // 获取ASTContext
        ASTContext &ctx = astContext();
        // 检查任意一侧是否为NULL指针常量
        bool isNullConstant = lhs->isNullPointerConstant(ctx, NPC_None) || 
                              rhs->isNullPointerConstant(ctx, NPC_None);
        
        // 检查另一侧是否为变量引用(匹配目标场景)
        if (isNullConstant && (isa<DeclRefExpr>(lhs) || isa<DeclRefExpr>(rhs)))
        {
            // 上报违规
            addViolation(BO, this, "Detected explicit null pointer check against a pointer variable");
        }

        return true;
    }
};

static RuleSet rules(new NullPointerCheckRule());

关键说明

  • IgnoreParenImpCasts():去除表达式周围的括号和隐式类型转换,确保判断的是原始表达式;
  • NullPointerConstantValueDependence参数:
    • NPC_None:不考虑值依赖场景,适用于普通代码;
    • NPC_ValueDependent:用于处理模板等值依赖的代码场景;
  • astContext():直接从父类继承的方法,无需额外初始化,可在任何访问AST节点的方法中调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 08:22:42