Skip to content

Commit 10c2ac8

Browse files
committed
integrate clang analyzer
1 parent 0170191 commit 10c2ac8

File tree

2 files changed

+102
-10
lines changed

2 files changed

+102
-10
lines changed

win32/build/config.w32

+17-1
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,27 @@ if (PHP_SECURITY_FLAGS == "yes") {
212212
ADD_FLAG("LDFLAGS", "/NXCOMPAT /DYNAMICBASE ");
213213
}
214214

215-
/* XXX add and implement clang keyword for clang analyzer */
216215
ARG_WITH("analyzer", "Enable static analyzer. Pass vs for Visual Studio, pvs for PVS-Studio", "no");
217216
if (PHP_ANALYZER == "vs") {
218217
ADD_FLAG("CFLAGS", " /analyze ");
219218
ADD_FLAG("CFLAGS", " /wd6308 ");
219+
} else if (PHP_ANALYZER == "clang") {
220+
var clang_cl = false;
221+
222+
if (FSO.FileExists(PROGRAM_FILES + "\\LLVM\\bin\\clang-cl.exe")) {
223+
clang_cl = PROGRAM_FILES + "\\LLVM\\bin\\clang-cl.exe";
224+
} else if (FSO.FileExists(PROGRAM_FILES + "\\LLVM\\bin\\clang-cl.exe")) {
225+
clang_cl = PROGRAM_FILES + "\\LLVM\\bin\\clang-cl.exe";
226+
}
227+
228+
if (!clang_cl) {
229+
if (false == PATH_PROG('clang-cl', null, 'CLANG_CL')) {
230+
WARNING("Couldn't find clang binaries, static analyze was disabled");
231+
PHP_ANALYZER = "no";
232+
}
233+
} else {
234+
DEFINE("CLANG_CL", clang_cl);
235+
}
220236
} else if (PHP_ANALYZER == "pvs") {
221237
var pvs_studio = false;
222238

win32/build/confutils.js

+85-9
Original file line numberDiff line numberDiff line change
@@ -1526,19 +1526,37 @@ function ADD_SOURCES(dir, file_list, target, obj_dir)
15261526
ADD_FLAG(bd_flags_name, "/Fd" + sub_build + d);
15271527
}
15281528

1529+
if (PHP_ANALYZER == "clang") {
1530+
var analyzer_base_args = X64 ? "-m64" : "-m32";
1531+
1532+
analyzer_base_args += " --analyze";
1533+
1534+
var vc_ver;
1535+
if (VS_TOOLSET) {
1536+
vc_ver = VCVERS;
1537+
} else {
1538+
vc_ver = probe_binary(PATH_PROG('cl', null));
1539+
}
1540+
1541+
analyzer_base_args += " -fms-compatibility -fms-compatibility-version=" + vc_ver + " -fms-extensions";
1542+
}
1543+
15291544
if (PHP_MP_DISABLED) {
15301545
for (var j in srcs_by_dir[k]) {
15311546
src = file_list[srcs_by_dir[k][j]];
1532-
if (PHP_ANALYZER == "pvs") {
1533-
MFO.WriteLine("\t@\"$(PVS_STUDIO)\" --cl-params $(" + flags + ") $(CFLAGS) $(" + bd_flags_name + ") /c " + dir + "\\" + src + " --source-file " + dir + "\\" + src
1534-
+ " --cfg PVS-Studio.conf --errors-off \"V122 V117 V111\" ");
1535-
}
15361547

15371548
var _tmp = src.split("\\");
15381549
var filename = _tmp.pop();
15391550
obj = filename.replace(re, ".obj");
15401551

15411552
MFO.WriteLine("\t@$(CC) $(" + flags + ") $(CFLAGS) $(" + bd_flags_name + ") /c " + dir + "\\" + src + " /Fo" + sub_build + d + obj);
1553+
1554+
if ("clang" == PHP_ANALYZER) {
1555+
MFO.WriteLine("\t\"@$(CLANG_CL)\" " + analyzer_base_args + " $(" + flags + "_ANALYZER) $(CFLAGS_ANALYZER) $(" + bd_flags_name + "_ANALYZER) /c " + dir + "\\" + src);
1556+
}else if (PHP_ANALYZER == "pvs") {
1557+
MFO.WriteLine("\t@\"$(PVS_STUDIO)\" --cl-params $(" + flags + ") $(CFLAGS) $(" + bd_flags_name + ") /c " + dir + "\\" + src + " --source-file " + dir + "\\" + src
1558+
+ " --cfg PVS-Studio.conf --errors-off \"V122 V117 V111\" ");
1559+
}
15421560
}
15431561
} else {
15441562
/* TODO create a response file at least for the source files to work around the cmd line length limit. */
@@ -1548,6 +1566,10 @@ function ADD_SOURCES(dir, file_list, target, obj_dir)
15481566
}
15491567

15501568
MFO.WriteLine("\t$(CC) $(" + flags + ") $(CFLAGS) /Fo" + sub_build + d + " $(" + bd_flags_name + ") /c " + src_line);
1569+
1570+
if ("clang" == PHP_ANALYZER) {
1571+
MFO.WriteLine("\t\"$(CLANG_CL)\" " + analyzer_base_args + " $(" + flags + "_ANALYZER) $(CFLAGS_ANALYZER) $(" + bd_flags_name + "_ANALYZER) /c " + src_line);
1572+
}
15511573
}
15521574
}
15531575

@@ -1729,6 +1751,8 @@ function write_summary()
17291751
}
17301752
if (PHP_ANALYZER == "vs") {
17311753
ar[5] = ['Static analyzer', 'Visual Studio'];
1754+
} else if (PHP_ANALYZER == "clang") {
1755+
ar[5] = ['Static analyzer', 'clang'];
17321756
} else if (PHP_ANALYZER == "pvs") {
17331757
ar[5] = ['Static analyzer', 'PVS-Studio'];
17341758
} else {
@@ -2057,6 +2081,54 @@ function generate_phpize()
20572081
CJ.Close();
20582082
}
20592083

2084+
function handle_analyzer_makefile_flags(fd, key, val)
2085+
{
2086+
var relevant = false;
2087+
2088+
/* VS integrates /analyze with the bulid process,
2089+
no further action is required. */
2090+
if ("no" == PHP_ANALYZER || "vs" == PHP_ANALYZER) {
2091+
return;
2092+
}
2093+
2094+
if (key.match("CFLAGS")) {
2095+
var new_val = val;
2096+
var reg = /\$\(([^\)]+)\)/g;
2097+
while (r = reg.exec(val)) {
2098+
var repl = "$(" + r[1] + "_ANALYZER)"
2099+
new_val = new_val.replace(r[0], repl);
2100+
}
2101+
val = new_val;
2102+
2103+
if ("clang" == PHP_ANALYZER) {
2104+
val = val.replace(/\/FD /, "")
2105+
.replace(/\/Fp.+? /, "")
2106+
.replace(/\/Fo.+? /, "")
2107+
.replace(/\/Fd.+? /, "")
2108+
//.replace(/\/Fd.+?/, " ")
2109+
.replace(/\/FR.+? /, "")
2110+
.replace("/guard:cf ", "")
2111+
.replace(/\/MP \d+ /, "")
2112+
.replace(/\/MP /, "")
2113+
.replace("/LD ", "");
2114+
}
2115+
2116+
relevant = true;
2117+
} else if (key.match("BASE_INCLUDES")) {
2118+
relevant = true;
2119+
}
2120+
2121+
if (!relevant) {
2122+
return;
2123+
}
2124+
2125+
key += "_ANALYZER";
2126+
//WARNING("KEY: " + key + " VAL: " + val);
2127+
2128+
fd.WriteLine(key + "=" + val + " ");
2129+
fd.WriteBlankLines(1);
2130+
}
2131+
20602132
/* Generate the Makefile */
20612133
function generate_makefile()
20622134
{
@@ -2072,12 +2144,16 @@ function generate_makefile()
20722144
// The trailing space is needed to prevent the trailing backslash
20732145
// that is part of the build dir flags (CFLAGS_BD_XXX) from being
20742146
// seen as a line continuation character
2075-
MF.WriteLine(keys[i] + "=" +
2076-
/* \s+\/ eliminates extra whitespace caused when using \ for string continuation,
2077-
whereby \/ is the start of the next compiler switch */
2078-
trim(configure_subst.Item(keys[i])).replace(/\s+\//gm, " /") + " "
2079-
);
2147+
2148+
/* \s+\/ eliminates extra whitespace caused when using \ for string continuation,
2149+
whereby \/ is the start of the next compiler switch */
2150+
var val = trim(configure_subst.Item(keys[i])).replace(/\s+\//gm, " /");
2151+
2152+
MF.WriteLine(keys[i] + "=" + val + " ");
20802153
MF.WriteBlankLines(1);
2154+
2155+
/* If static analyze is enabled, add analyzer specific stuff to the Makefile. */
2156+
handle_analyzer_makefile_flags(MF, keys[i], val);
20812157
}
20822158

20832159
MF.WriteBlankLines(1);

0 commit comments

Comments
 (0)