开源 企业版 高校版 私有云 模力方舟 AI 队友
代码拉取完成,页面将自动刷新
捐赠
捐赠前请先登录
扫描微信二维码支付
取消
支付完成
支付提示
将跳转至支付宝完成支付
确定
取消
1 Star 0 Fork 4

CodeTiger/Cppcheck

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
已有帐号? 立即登录
文件
master
分支 (95)
标签 (95)
master
main
remove_tinyxml_use_stl_flag
fp-uninit
cleanup-threadsafety
gui-platform
11734
tokenizer-alignas
11013
typedef-function
11707
11443
11700
qml
check-level-doc
check-level
color
performance-valueflow
cleanup
valueflow-too-many-ifs
2.10.3
2.10.2
2.10.1
2.10
2.9.3
2.9.2
2.9.1
2.9
2.8.2
2.8.1
2.8
2.7.5
2.7.4
2.7.3
2.7.2
2.7.1
2.7
2.6.3
2.6.2
2.6.1
master
分支 (95)
标签 (95)
master
main
remove_tinyxml_use_stl_flag
fp-uninit
cleanup-threadsafety
gui-platform
11734
tokenizer-alignas
11013
typedef-function
11707
11443
11700
qml
check-level-doc
check-level
color
performance-valueflow
cleanup
valueflow-too-many-ifs
2.10.3
2.10.2
2.10.1
2.10
2.9.3
2.9.2
2.9.1
2.9
2.8.2
2.8.1
2.8
2.7.5
2.7.4
2.7.3
2.7.2
2.7.1
2.7
2.6.3
2.6.2
2.6.1
克隆/下载
克隆/下载
提示
下载代码请复制以下命令到终端执行
为确保你提交的代码身份被 Gitee 正确识别,请执行以下命令完成配置
初次使用 SSH 协议进行代码克隆、推送等操作时,需按下述提示完成 SSH 配置
1 生成 RSA 密钥
2 获取 RSA 公钥内容,并配置到 SSH公钥
在 Gitee 上使用 SVN,请访问 使用指南
使用 HTTPS 协议时,命令行会出现如下账号密码验证步骤。基于安全考虑,Gitee 建议 配置并使用私人令牌 替代登录密码进行克隆、推送等操作
Username for 'https://gitee.com': userName
Password for 'https://userName@gitee.com': # 私人令牌
master
分支 (95)
标签 (95)
master
main
remove_tinyxml_use_stl_flag
fp-uninit
cleanup-threadsafety
gui-platform
11734
tokenizer-alignas
11013
typedef-function
11707
11443
11700
qml
check-level-doc
check-level
color
performance-valueflow
cleanup
valueflow-too-many-ifs
2.10.3
2.10.2
2.10.1
2.10
2.9.3
2.9.2
2.9.1
2.9
2.8.2
2.8.1
2.8
2.7.5
2.7.4
2.7.3
2.7.2
2.7.1
2.7
2.6.3
2.6.2
2.6.1
cppcheck
/
lib
/
pathanalysis.cpp
cppcheck
/
lib
/
pathanalysis.cpp
pathanalysis.cpp 6.85 KB
一键复制 编辑 原始数据 按行查看 历史
PKEuS 提交于 2020年05月11日 02:32 +08:00 . Refactorization: Moved code from header to source
#include "pathanalysis.h"
#include "astutils.h"
#include "symboldatabase.h"
#include "token.h"
#include "valueflow.h"
#include <algorithm>
const Scope* PathAnalysis::findOuterScope(const Scope * scope)
{
if (!scope)
return nullptr;
if (scope->isLocal() && scope->type != Scope::eSwitch)
return findOuterScope(scope->nestedIn);
return scope;
}
static const Token* assignExpr(const Token* tok)
{
while (tok->astParent() && astIsLHS(tok)) {
if (Token::Match(tok->astParent(), "%assign%"))
return tok->astParent();
tok = tok->astParent();
}
return nullptr;
}
std::pair<bool, bool> PathAnalysis::checkCond(const Token * tok, bool& known)
{
if (tok->hasKnownIntValue()) {
known = true;
return std::make_pair(tok->values().front().intvalue, !tok->values().front().intvalue);
}
auto it = std::find_if(tok->values().begin(), tok->values().end(), [](const ValueFlow::Value& v) {
return v.isIntValue();
});
// If all possible values are the same, then assume all paths have the same value
if (it != tok->values().end() && std::all_of(it, tok->values().end(), [&](const ValueFlow::Value& v) {
if (v.isIntValue())
return v.intvalue == it->intvalue;
return true;
})) {
known = false;
return std::make_pair(it->intvalue, !it->intvalue);
}
return std::make_pair(true, true);
}
PathAnalysis::Progress PathAnalysis::forwardRecursive(const Token* tok, Info info, const std::function<PathAnalysis::Progress(const Info&)>& f) const
{
if (!tok)
return Progress::Continue;
if (tok->astOperand1() && forwardRecursive(tok->astOperand1(), info, f) == Progress::Break)
return Progress::Break;
info.tok = tok;
if (f(info) == Progress::Break)
return Progress::Break;
if (tok->astOperand2() && forwardRecursive(tok->astOperand2(), info, f) == Progress::Break)
return Progress::Break;
return Progress::Continue;
}
PathAnalysis::Progress PathAnalysis::forwardRange(const Token* startToken, const Token* endToken, Info info, const std::function<PathAnalysis::Progress(const Info&)>& f) const
{
for (const Token *tok = startToken; tok && tok != endToken; tok = tok->next()) {
if (Token::Match(tok, "asm|goto|break|continue"))
return Progress::Break;
else if (Token::Match(tok, "return|throw")) {
forwardRecursive(tok, info, f);
return Progress::Break;
// Evaluate RHS of assignment before LHS
} else if (const Token* assignTok = assignExpr(tok)) {
if (forwardRecursive(assignTok->astOperand2(), info, f) == Progress::Break)
return Progress::Break;
if (forwardRecursive(assignTok->astOperand1(), info, f) == Progress::Break)
return Progress::Break;
tok = nextAfterAstRightmostLeaf(assignTok);
if (!tok)
return Progress::Break;
} else if (Token::simpleMatch(tok, "}") && Token::simpleMatch(tok->link()->previous(), ") {") && Token::Match(tok->link()->linkAt(-1)->previous(), "if|while|for (")) {
const Token * blockStart = tok->link()->linkAt(-1)->previous();
const Token * condTok = getCondTok(blockStart);
if (!condTok)
continue;
info.errorPath.emplace_back(condTok, "Assuming condition is true.");
// Traverse a loop a second time
if (Token::Match(blockStart, "for|while (")) {
const Token* endCond = blockStart->linkAt(1);
bool traverseLoop = true;
// Only traverse simple for loops
if (Token::simpleMatch(blockStart, "for") && !Token::Match(endCond->tokAt(-3), "; ++|--|%var% %var%|++|-- ) {"))
traverseLoop = false;
// Traverse loop a second time
if (traverseLoop) {
// Traverse condition
if (forwardRecursive(condTok, info, f) == Progress::Break)
return Progress::Break;
// TODO: Should we traverse the body: forwardRange(tok->link(), tok, info, f)?
}
}
if (Token::simpleMatch(tok, "} else {")) {
tok = tok->linkAt(2);
}
} else if (Token::Match(tok, "if|while|for (") && Token::simpleMatch(tok->next()->link(), ") {")) {
const Token * endCond = tok->next()->link();
const Token * endBlock = endCond->next()->link();
const Token * condTok = getCondTok(tok);
if (!condTok)
continue;
// Traverse condition
if (forwardRange(tok->next(), tok->next()->link(), info, f) == Progress::Break)
return Progress::Break;
Info i = info;
i.known = false;
i.errorPath.emplace_back(condTok, "Assuming condition is true.");
// Check if condition is true or false
bool checkThen = false;
bool checkElse = false;
std::tie(checkThen, checkElse) = checkCond(condTok, i.known);
// Traverse then block
if (checkThen) {
if (forwardRange(endCond->next(), endBlock, i, f) == Progress::Break)
return Progress::Break;
}
// Traverse else block
if (Token::simpleMatch(endBlock, "} else {")) {
if (checkElse) {
i.errorPath.back().second = "Assuming condition is false.";
Progress result = forwardRange(endCond->next(), endBlock, i, f);
if (result == Progress::Break)
return Progress::Break;
}
tok = endBlock->linkAt(2);
} else {
tok = endBlock;
}
} else if (Token::simpleMatch(tok, "} else {")) {
tok = tok->linkAt(2);
} else {
info.tok = tok;
if (f(info) == Progress::Break)
return Progress::Break;
}
// Prevent infinite recursion
if (tok->next() == start)
break;
}
return Progress::Continue;
}
void PathAnalysis::forward(const std::function<Progress(const Info&)>& f) const
{
const Scope * endScope = findOuterScope(start->scope());
if (!endScope)
return;
const Token * endToken = endScope->bodyEnd;
Info info{start, ErrorPath{}, true};
forwardRange(start, endToken, info, f);
}
bool reaches(const Token * start, const Token * dest, const Library& library, ErrorPath* errorPath)
{
PathAnalysis::Info info = PathAnalysis{start, library} .forwardFind([&](const PathAnalysis::Info& i) {
return (i.tok == dest);
});
if (!info.tok)
return false;
if (errorPath)
errorPath->insert(errorPath->end(), info.errorPath.begin(), info.errorPath.end());
return true;
}
Loading...
举报
举报成功
我们将于2个工作日内通过站内信反馈结果给你!
请认真填写举报原因,尽可能描述详细。
请选择举报类型
取消
发送
误判申诉

此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。

如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。

取消
提交

简介

暂无描述
暂无标签
GPL-3.0
使用 GPL-3.0 开源许可协议
取消

发行版

暂无发行版

贡献者

全部

近期动态

不能加载更多了
编辑仓库简介
简介内容
主页
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/codepool/cppcheck.git
git@gitee.com:codepool/cppcheck.git
codepool
cppcheck
Cppcheck
master
点此查找更多帮助

搜索帮助

评论
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册

AltStyle によって変換されたページ (->オリジナル) /