Clang调试deadcode思路
首先描述下我的环境:Ubuntu16.04 llvm4.0 clang4.0全部使用源码安装方式
Clang的根目录,位于llvm-src下边的tools目录下。
因为需要找到真正的开关,下边我描述下我的思路:
在clang/lib/Analysis/reachableCode.cpp中,存着DeadCodeScan::findDeadCode的实现,如果功能开关打开的话,那个一定存在着这个类的初始化,然后进行调用,查找初始化这个类的地方
在reachableCode.cpp:683(代表reachableCode.cpp文件的第683行,以后不再进行赘述),存在以下代码:
DeadCodeScan DS(reachable, PP);
numReachable += DS.scanBackwards(block, CB);
if (numReachable == cfg->getNumBlockIDs())
return;
这段代码属于FindUnreachableCode()函数中。查看这个函数,发现并没有明显的开关,如果你愿意的话,可以调试下,断点肯定进不了这里。
继续向上查找,发现整个clang的project中仅有一次这个函数的调用在
clang/lib/Sema/AnalysisBasedWarnings.cpp文件中的CheckUnreachable()函数中对这个函数进行了调用,这个函数中也没有可能的开关。继续向上查找,发现在该文件的2050行中存在着CheckUnreachable的调用,粘一下这个块的代码:
if (P.enableCheckUnreachable) {
// Only check for unreachable code on non-template instantiations.
// Different template instantiations can effectively change the control-flow
// and it is very difficult to prove that a snippet of code in a template
// is unreachable for all instantiations.
bool isTemplateInstantiation = false;
if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D))
isTemplateInstantiation = Function->isTemplateInstantiation();
if (!isTemplateInstantiation)
CheckUnreachable(S, AC);
}
这次终于找到了一个明确的开关P.enableCheckUnreachable,查看一下enableCheckUnreachable,发现了这样一段代码
clang::sema::AnalysisBasedWarnings::Policy::Policy() {
enableCheckFallThrough = 1;
enableCheckUnreachable = 0;
enableThreadSafetyAnalysis = 0;
enableConsumedAnalysis = 0;
}
这里是比较明显的,默认初始化的话,enableCheckUnreachable 是0,是不会执行的,看看在执行过程中是否会有对这个值的更改,找到以下代码:
//AnalysisBasedWarnings.cpp:1995
if (P.enableCheckUnreachable || P.enableThreadSafetyAnalysis ||
P.enableConsumedAnalysis) {
// Unreachable code analysis and thread safety require a linearized CFG.
AC.getCFGBuildOptions().setAllAlwaysAdd();
}
在这里下断点,进行调试,
1955 if (P.enableCheckUnreachable || P.enableThreadSafetyAnalysis ||
(gdb) p P.enableCheckUnreachable
$1 = 0
(gdb) p P.enableThreadSafetyAnalysis
$2 = 0
(gdb) p P.enableConsumedAnalysis
$3 = 0
所以,结果就比较明显了,默认情况下,这个开关是没有打开的,需要的是修改这里的源码,重新编译。