gpt4 book ai didi

clang-static-analyzer - 如何匹配指向空对象的指针?

转载 作者:行者123 更新时间:2023-12-04 15:49:53 25 4
gpt4 key购买 nike

我想匹配函数的特定参数可以为空的所有方式。现在我正在使用

hasArgument(
3,
anyOf(
cxxNullPtrLiteralExpr()
,integerLiteral() // Technically this would alert on a constant pointer; but that's madness
)
)

但是,这与以下代码不匹配:
void* nullObj = nullptr;
function(nullptr, false, false, nullObj);

是否可能/容易跟踪并匹配它?现在我有一个非常简单的匹配器,但我想这种类型的分析需要更多的逻辑?

最佳答案

高层回答

您不能只“匹配”值为 NULL 的表达式。 AST 匹配只能检查参数的语法,因此如果参数不是文字,您不知道它是否可能为 NULL。

相反,您需要使用查询 Clang SA 约束引擎的流敏感检查器。当值流经程序时,约束引擎会对其进行跟踪。

这种检查器的核心如下所示:

bool NullArgChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
ProgramStateRef state = C.getState();
auto SVal = C.getSVal(CE->getArg(0)).getAs<DefinedOrUnknownSVal>();
if (SVal) {
ConditionTruthVal Nullness = state->isNull(*SVal);
if (Nullness.isConstrainedTrue()) {

给定一个调用表达式 CE ,我们得到它的第一个参数,然后查询 CheckerContext用于符号值 SVal与第一个参数相关联。然后我们询问该值是否已知为 NULL。

完整示例

这是一个完整的示例检查器,每次它看到已知为 NULL 的值作为任何函数的第一个参数传递时都会报告警告。

NullArgChecker.cpp:
// NullArgChecker.cpp
// https://stackoverflow.com/questions/57665383/how-can-i-match-a-pointer-to-a-null-object

#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"

using namespace clang;
using namespace ento;

namespace {

class NullArgChecker : public Checker< eval::Call > {
mutable std::unique_ptr<BuiltinBug> BT_nullarg;

public:
NullArgChecker() {}
bool evalCall(const CallExpr *CE, CheckerContext &C) const;
};

} // end anonymous namespace


bool NullArgChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
ProgramStateRef state = C.getState();
auto SVal = C.getSVal(CE->getArg(0)).getAs<DefinedOrUnknownSVal>();
if (SVal) {
// This is the core of this example checker: we query the constraint
// engine to see if the symbolic value associated with the first
// argument is known to be NULL along the current path.
ConditionTruthVal Nullness = state->isNull(*SVal);
if (Nullness.isConstrainedTrue()) {
// Create a warning for this condition.
ExplodedNode *N = C.generateErrorNode();
if (N) {
if (!BT_nullarg) {
BT_nullarg.reset(new BuiltinBug(
this, "Null Argument", "The first argument is NULL."));
}
C.emitReport(llvm::make_unique<BugReport>(
*BT_nullarg, BT_nullarg->getDescription(), N));
}
}
}

return false;
}

void ento::registerNullArgChecker(CheckerManager &mgr) {
mgr.registerChecker<NullArgChecker>();
}

bool ento::shouldRegisterNullArgChecker(const LangOptions &LO) {
return true;
}

更改其他文件以将其 Hook :
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -148,6 +148,10 @@ def NonnullGlobalConstantsChecker: Checker<"NonnilStringCon
stants">,

let ParentPackage = CoreAlpha in {

+def NullArgChecker : Checker<"NullArg">,
+ HelpText<"Check for passing a NULL argument">,
+ Documentation<NotDocumented>;
+
def BoolAssignmentChecker : Checker<"BoolAssignment">,
HelpText<"Warn about assigning non-{0,1} values to Boolean variables">,
Documentation<HasAlphaDocumentation>;
--- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -62,6 +62,7 @@ add_clang_library(clangStaticAnalyzerCheckers
NonNullParamChecker.cpp
NonnullGlobalConstantsChecker.cpp
NullabilityChecker.cpp
+ NullArgChecker.cpp
NumberObjectConversionChecker.cpp
ObjCAtSyncChecker.cpp
ObjCAutoreleaseWriteChecker.cpp

用于测试的示例输入:
// nullargpp.cpp
// Testing NullArg checker with C++.

#include <stddef.h> // NULL

void somefunc(int*);

void nullarg1()
{
somefunc(NULL); // reported
somefunc(0); // reported
somefunc(nullptr); // reported
}

void nullarg2()
{
int *p = 0;
somefunc(p); // reported
}

void nullarg3(int *p)
{
if (p) {
somefunc(p); // not reported
}
else {
somefunc(p); // reported
}
}

void not_nullarg(int *p)
{
somefunc(p); // not reported
}

示例运行:
$ g++ -std=c++11 -E -o nullargpp.ii nullargpp.cpp
$ ~/bld/llvm-project/build/bin/clang -cc1 -analyze -analyzer-checker=alpha.core.NullArg nullargpp.ii
nullargpp.cpp:10:3: warning: The first argument is NULL
somefunc(
^~~~~~~~~
nullargpp.cpp:11:3: warning: The first argument is NULL
somefunc(0);
^~~~~~~~~~~
nullargpp.cpp:12:3: warning: The first argument is NULL
somefunc(nullptr);
^~~~~~~~~~~~~~~~~
nullargpp.cpp:18:3: warning: The first argument is NULL
somefunc(p);
^~~~~~~~~~~
nullargpp.cpp:27:5: warning: The first argument is NULL
somefunc(p);
^~~~~~~~~~~
5 warnings generated.

为获得最大的特异性,对 llvm-project commit 05efe0fdc4(2019 年 3 月)进行了上述更改,在 Linux 上运行,但应适用于任何 Clang v9。

关于clang-static-analyzer - 如何匹配指向空对象的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57665383/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com