如何在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
相关产品推荐
相关产品推荐

