blob: 800f38b5ba241fe2c7ddf217350b62610f97b41e [file] [log] [blame]
Ted Kremenekf7ffd662008-07-19 06:11:04 +00001#!/usr/bin/env perl
Ted Kremenek5efdf842008-03-25 22:35:32 +00002#
Chandler Carruth2946cd72019-01-19 08:50:56 +00003# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4# See https://llvm.org/LICENSE.txt for license information.
5# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Ted Kremenek5efdf842008-03-25 22:35:32 +00006#
7##===----------------------------------------------------------------------===##
8#
Ted Kremenekf7ffd662008-07-19 06:11:04 +00009# A script designed to interpose between the build system and gcc. It invokes
10# both gcc and the static analyzer.
Ted Kremenek5efdf842008-03-25 22:35:32 +000011#
12##===----------------------------------------------------------------------===##
13
Ted Kremenekf7ffd662008-07-19 06:11:04 +000014use strict;
15use warnings;
Ted Kremenekf65a0c62009-12-15 02:35:54 +000016use FindBin;
Ted Kremenek23432d42008-09-21 19:56:14 +000017use Cwd qw/ getcwd abs_path /;
Ted Kremenek994c8e32008-08-08 20:46:42 +000018use File::Temp qw/ tempfile /;
19use File::Path qw / mkpath /;
Ted Kremenek13747162009-01-21 00:42:24 +000020use File::Basename;
Ted Kremenek25421bb2009-05-11 23:29:51 +000021use Text::ParseWords;
Ted Kremenek6aa1ad02008-08-25 20:44:31 +000022
Ted Kremenekf65a0c62009-12-15 02:35:54 +000023##===----------------------------------------------------------------------===##
Anton Yartsev84f90422015-07-01 22:35:29 +000024# List form 'system' with STDOUT and STDERR captured.
25##===----------------------------------------------------------------------===##
26
27sub silent_system {
28 my $HtmlDir = shift;
29 my $Command = shift;
30
31 # Save STDOUT and STDERR and redirect to a temporary file.
32 open OLDOUT, ">&", \*STDOUT;
33 open OLDERR, ">&", \*STDERR;
34 my ($TmpFH, $TmpFile) = tempfile("temp_buf_XXXXXX",
35 DIR => $HtmlDir,
36 UNLINK => 1);
37 open(STDOUT, ">$TmpFile");
38 open(STDERR, ">&", \*STDOUT);
39
40 # Invoke 'system', STDOUT and STDERR are output to a temporary file.
41 system $Command, @_;
42
43 # Restore STDOUT and STDERR.
44 open STDOUT, ">&", \*OLDOUT;
45 open STDERR, ">&", \*OLDERR;
46
47 return $TmpFH;
48}
49
50##===----------------------------------------------------------------------===##
Ted Kremenekf65a0c62009-12-15 02:35:54 +000051# Compiler command setup.
52##===----------------------------------------------------------------------===##
53
Sylvestre Ledru9e075292014-08-08 17:15:13 +000054# Search in the PATH if the compiler exists
55sub SearchInPath {
56 my $file = shift;
57 foreach my $dir (split (':', $ENV{PATH})) {
58 if (-x "$dir/$file") {
59 return 1;
60 }
61 }
62 return 0;
63}
64
Ted Kremenekf65a0c62009-12-15 02:35:54 +000065my $Compiler;
66my $Clang;
Anna Zaks1d391522012-01-06 01:54:05 +000067my $DefaultCCompiler;
68my $DefaultCXXCompiler;
Jordan Rosea63f2292014-01-07 21:39:51 +000069my $IsCXX;
Ted Kremenek0270a082015-08-08 17:58:47 +000070my $AnalyzerTarget;
Ted Kremenek67978552014-12-31 08:19:08 +000071
72# If on OSX, use xcrun to determine the SDK root.
Ted Kremenek398f46f2014-12-31 07:44:51 +000073my $UseXCRUN = 0;
Anna Zaks1d391522012-01-06 01:54:05 +000074
Sylvestre Ledru82e547e2014-02-18 17:21:45 +000075if (`uname -a` =~ m/Darwin/) {
Jordan Rose85ff8f22012-11-28 19:12:44 +000076 $DefaultCCompiler = 'clang';
77 $DefaultCXXCompiler = 'clang++';
Ted Kremenek67978552014-12-31 08:19:08 +000078 # Older versions of OSX do not have xcrun to
79 # query the SDK location.
Ted Kremenek398f46f2014-12-31 07:44:51 +000080 if (-x "/usr/bin/xcrun") {
81 $UseXCRUN = 1;
82 }
Anna Zaks1d391522012-01-06 01:54:05 +000083} else {
Jordan Rose85ff8f22012-11-28 19:12:44 +000084 $DefaultCCompiler = 'gcc';
85 $DefaultCXXCompiler = 'g++';
Anna Zaks1d391522012-01-06 01:54:05 +000086}
Ted Kremenekf65a0c62009-12-15 02:35:54 +000087
88if ($FindBin::Script =~ /c\+\+-analyzer/) {
89 $Compiler = $ENV{'CCC_CXX'};
Sylvestre Ledru9e075292014-08-08 17:15:13 +000090 if (!defined $Compiler || (! -x $Compiler && ! SearchInPath($Compiler))) { $Compiler = $DefaultCXXCompiler; }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +000091
Ted Kremenekf65a0c62009-12-15 02:35:54 +000092 $Clang = $ENV{'CLANG_CXX'};
Sylvestre Ledru3ea1dae2014-02-18 17:45:06 +000093 if (!defined $Clang || ! -x $Clang) { $Clang = 'clang++'; }
Jordan Rosea63f2292014-01-07 21:39:51 +000094
95 $IsCXX = 1
Ted Kremenekf65a0c62009-12-15 02:35:54 +000096}
97else {
98 $Compiler = $ENV{'CCC_CC'};
Sylvestre Ledru9e075292014-08-08 17:15:13 +000099 if (!defined $Compiler || (! -x $Compiler && ! SearchInPath($Compiler))) { $Compiler = $DefaultCCompiler; }
Ted Kremenekf65a0c62009-12-15 02:35:54 +0000100
101 $Clang = $ENV{'CLANG'};
Sylvestre Ledru3ea1dae2014-02-18 17:45:06 +0000102 if (!defined $Clang || ! -x $Clang) { $Clang = 'clang'; }
Jordan Rosea63f2292014-01-07 21:39:51 +0000103
104 $IsCXX = 0
Ted Kremenekf65a0c62009-12-15 02:35:54 +0000105}
106
Ted Kremenek0270a082015-08-08 17:58:47 +0000107$AnalyzerTarget = $ENV{'CLANG_ANALYZER_TARGET'};
108
Ted Kremenekf65a0c62009-12-15 02:35:54 +0000109##===----------------------------------------------------------------------===##
110# Cleanup.
111##===----------------------------------------------------------------------===##
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000112
113my $ReportFailures = $ENV{'CCC_REPORT_FAILURES'};
114if (!defined $ReportFailures) { $ReportFailures = 1; }
115
Ted Kremenek13747162009-01-21 00:42:24 +0000116my $CleanupFile;
117my $ResultFile;
118
119# Remove any stale files at exit.
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000120END {
Artem Dergachev8b49e0f2019-08-08 20:22:32 +0000121 if (defined $ResultFile && -z $ResultFile) {
Sylvestre Ledrudf70a7b2014-05-23 16:10:00 +0000122 unlink($ResultFile);
Anna Zaks45ce1bf2011-09-09 18:43:53 +0000123 }
124 if (defined $CleanupFile) {
Sylvestre Ledrudf70a7b2014-05-23 16:10:00 +0000125 unlink($CleanupFile);
Ted Kremenek13747162009-01-21 00:42:24 +0000126 }
127}
128
Ted Kremenek994c8e32008-08-08 20:46:42 +0000129##----------------------------------------------------------------------------##
130# Process Clang Crashes.
131##----------------------------------------------------------------------------##
132
133sub GetPPExt {
134 my $Lang = shift;
Ted Kremenek22a8a4b2009-12-16 18:32:41 +0000135 if ($Lang =~ /objective-c\+\+/) { return ".mii" };
Ted Kremenek994c8e32008-08-08 20:46:42 +0000136 if ($Lang =~ /objective-c/) { return ".mi"; }
Ted Kremenekdca68162009-12-16 05:02:47 +0000137 if ($Lang =~ /c\+\+/) { return ".ii"; }
Ted Kremenek994c8e32008-08-08 20:46:42 +0000138 return ".i";
139}
140
Ted Kremenekce6b8652009-04-28 17:37:44 +0000141# Set this to 1 if we want to include 'parser rejects' files.
142my $IncludeParserRejects = 0;
Ted Kremenek725fb432009-01-27 01:19:08 +0000143my $ParserRejects = "Parser Rejects";
Ted Kremenek13ed6f12009-02-17 23:31:05 +0000144my $AttributeIgnored = "Attribute Ignored";
Anna Zaks9fed0842011-11-07 22:38:10 +0000145my $OtherError = "Other Error";
Ted Kremenek725fb432009-01-27 01:19:08 +0000146
Ted Kremenek5abf5462008-08-18 18:38:29 +0000147sub ProcessClangFailure {
Ted Kremenek5c512e62009-12-11 22:44:53 +0000148 my ($Clang, $Lang, $file, $Args, $HtmlDir, $ErrorType, $ofile) = @_;
Ted Kremenek13ed6f12009-02-17 23:31:05 +0000149 my $Dir = "$HtmlDir/failures";
Ted Kremenek994c8e32008-08-08 20:46:42 +0000150 mkpath $Dir;
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000151
Ted Kremenek725fb432009-01-27 01:19:08 +0000152 my $prefix = "clang_crash";
Ted Kremenek13ed6f12009-02-17 23:31:05 +0000153 if ($ErrorType eq $ParserRejects) {
154 $prefix = "clang_parser_rejects";
155 }
156 elsif ($ErrorType eq $AttributeIgnored) {
157 $prefix = "clang_attribute_ignored";
158 }
Anna Zaks9fed0842011-11-07 22:38:10 +0000159 elsif ($ErrorType eq $OtherError) {
160 $prefix = "clang_other_error";
161 }
Ted Kremenek72e4b0b2008-09-25 00:51:44 +0000162
Ted Kremenek0799d4f2009-07-28 00:14:21 +0000163 # Generate the preprocessed file with Clang.
Ted Kremenek725fb432009-01-27 01:19:08 +0000164 my ($PPH, $PPFile) = tempfile( $prefix . "_XXXXXX",
165 SUFFIX => GetPPExt($Lang),
166 DIR => $Dir);
Ted Kremenek994c8e32008-08-08 20:46:42 +0000167 close ($PPH);
Anton Yartsev321b1762015-06-17 23:12:33 +0000168 system $Clang, @$Args, "-E", "-o", $PPFile;
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000169
Ted Kremenek72e4b0b2008-09-25 00:51:44 +0000170 # Create the info file.
Ted Kremenek1ad3b3d2008-09-25 00:25:16 +0000171 open (OUT, ">", "$PPFile.info.txt") or die "Cannot open $PPFile.info.txt\n";
Ted Kremenek32c11812008-09-21 18:04:49 +0000172 print OUT abs_path($file), "\n";
Ted Kremenek5abf5462008-08-18 18:38:29 +0000173 print OUT "$ErrorType\n";
Ted Kremenekb3c98d32008-08-18 20:55:25 +0000174 print OUT "@$Args\n";
Ted Kremenek994c8e32008-08-08 20:46:42 +0000175 close OUT;
Ted Kremenek1ad3b3d2008-09-25 00:25:16 +0000176 `uname -a >> $PPFile.info.txt 2>&1`;
Anton Yartsev84f90422015-07-01 22:35:29 +0000177 `"$Compiler" -v >> $PPFile.info.txt 2>&1`;
Sylvestre Ledrudf70a7b2014-05-23 16:10:00 +0000178 rename($ofile, "$PPFile.stderr.txt");
Ted Kremenek13ed6f12009-02-17 23:31:05 +0000179 return (basename $PPFile);
Ted Kremenek994c8e32008-08-08 20:46:42 +0000180}
Ted Kremenek5efdf842008-03-25 22:35:32 +0000181
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000182##----------------------------------------------------------------------------##
183# Running the analyzer.
184##----------------------------------------------------------------------------##
Ted Kremenek5efdf842008-03-25 22:35:32 +0000185
Ted Kremenek1f991f02009-05-09 19:19:28 +0000186sub GetCCArgs {
Anton Yartsev84f90422015-07-01 22:35:29 +0000187 my $HtmlDir = shift;
Ted Kremenek42ec9142011-02-17 02:28:30 +0000188 my $mode = shift;
Ted Kremenek1f991f02009-05-09 19:19:28 +0000189 my $Args = shift;
Ted Kremenek1f991f02009-05-09 19:19:28 +0000190 my $line;
Anton Yartsev84f90422015-07-01 22:35:29 +0000191 my $OutputStream = silent_system($HtmlDir, $Clang, "-###", $mode, @$Args);
192 while (<$OutputStream>) {
Jordan Rose0d7d09f2014-03-20 17:43:54 +0000193 next if (!/\s"?-cc1"?\s/);
Ted Kremenek1f991f02009-05-09 19:19:28 +0000194 $line = $_;
195 }
Ted Kremenekf92b4462009-12-11 23:12:52 +0000196 die "could not find clang line\n" if (!defined $line);
Anton Yartsev0cb7c8a2014-01-23 14:12:48 +0000197 # Strip leading and trailing whitespace characters.
198 $line =~ s/^\s+|\s+$//g;
Anton Yartsev22f61892015-05-05 19:43:37 +0000199 my @items = quotewords('\s+', 0, $line);
Ted Kremenek1f991f02009-05-09 19:19:28 +0000200 my $cmd = shift @items;
Ted Kremenekf92b4462009-12-11 23:12:52 +0000201 die "cannot find 'clang' in 'clang' command\n" if (!($cmd =~ /clang/));
Ted Kremenek1f991f02009-05-09 19:19:28 +0000202 return \@items;
203}
204
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000205sub Analyze {
Ted Kremenek339f7c32011-03-10 21:10:08 +0000206 my ($Clang, $OriginalArgs, $AnalyzeArgs, $Lang, $Output, $Verbose, $HtmlDir,
Ted Kremenek42ec9142011-02-17 02:28:30 +0000207 $file) = @_;
Seo Sanghyeonb7bf0f32008-04-04 11:02:21 +0000208
Ted Kremenek339f7c32011-03-10 21:10:08 +0000209 my @Args = @$OriginalArgs;
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000210 my $Cmd;
211 my @CmdArgs;
Ted Kremenek994c8e32008-08-08 20:46:42 +0000212 my @CmdArgsSansAnalyses;
Ted Kremenek42ec9142011-02-17 02:28:30 +0000213
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000214 if ($Lang =~ /header/) {
215 exit 0 if (!defined ($Output));
216 $Cmd = 'cp';
Ted Kremenek42ec9142011-02-17 02:28:30 +0000217 push @CmdArgs, $file;
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000218 # Remove the PCH extension.
219 $Output =~ s/[.]gch$//;
Ted Kremenek42ec9142011-02-17 02:28:30 +0000220 push @CmdArgs, $Output;
221 @CmdArgsSansAnalyses = @CmdArgs;
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000222 }
223 else {
Ted Kremenek5c512e62009-12-11 22:44:53 +0000224 $Cmd = $Clang;
Ted Kremenek42ec9142011-02-17 02:28:30 +0000225
226 # Create arguments for doing regular parsing.
Anton Yartsev84f90422015-07-01 22:35:29 +0000227 my $SyntaxArgs = GetCCArgs($HtmlDir, "-fsyntax-only", \@Args);
Ted Kremenek339f7c32011-03-10 21:10:08 +0000228 @CmdArgsSansAnalyses = @$SyntaxArgs;
229
Ted Kremenek42ec9142011-02-17 02:28:30 +0000230 # Create arguments for doing static analysis.
231 if (defined $ResultFile) {
Ted Kremenekd4bcb4f2011-03-16 21:10:42 +0000232 push @Args, '-o', $ResultFile;
Ted Kremenek42ec9142011-02-17 02:28:30 +0000233 }
234 elsif (defined $HtmlDir) {
Ted Kremenekd4bcb4f2011-03-16 21:10:42 +0000235 push @Args, '-o', $HtmlDir;
Ted Kremenek42ec9142011-02-17 02:28:30 +0000236 }
Ted Kremenek9acb3462011-03-21 20:12:21 +0000237 if ($Verbose) {
238 push @Args, "-Xclang", "-analyzer-display-progress";
239 }
Ted Kremenek42ec9142011-02-17 02:28:30 +0000240
241 foreach my $arg (@$AnalyzeArgs) {
Ted Kremenekd4bcb4f2011-03-16 21:10:42 +0000242 push @Args, "-Xclang", $arg;
Ted Kremenek4ef13f82009-11-13 18:46:29 +0000243 }
Ted Kremenekd4bcb4f2011-03-16 21:10:42 +0000244
Ted Kremenek0270a082015-08-08 17:58:47 +0000245 if (defined $AnalyzerTarget) {
246 push @Args, "-target", $AnalyzerTarget;
247 }
248
Anton Yartsev84f90422015-07-01 22:35:29 +0000249 my $AnalysisArgs = GetCCArgs($HtmlDir, "--analyze", \@Args);
Ted Kremenek339f7c32011-03-10 21:10:08 +0000250 @CmdArgs = @$AnalysisArgs;
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000251 }
Ted Kremenek42ec9142011-02-17 02:28:30 +0000252
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000253 my @PrintArgs;
254 my $dir;
Ted Kremenek7ac29bb2009-08-02 05:42:46 +0000255
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000256 if ($Verbose) {
257 $dir = getcwd();
258 print STDERR "\n[LOCATION]: $dir\n";
259 push @PrintArgs,"'$Cmd'";
Ted Kremenek42ec9142011-02-17 02:28:30 +0000260 foreach my $arg (@CmdArgs) {
261 push @PrintArgs,"\'$arg\'";
262 }
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000263 }
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000264 if ($Verbose == 1) {
Ted Kremenekf18f4602008-05-24 15:58:54 +0000265 # We MUST print to stderr. Some clients use the stdout output of
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000266 # gcc for various purposes.
Ted Kremenek339f7c32011-03-10 21:10:08 +0000267 print STDERR join(' ', @PrintArgs);
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000268 print STDERR "\n";
269 }
270 elsif ($Verbose == 2) {
271 print STDERR "#SHELL (cd '$dir' && @PrintArgs)\n";
272 }
Ted Kremenek42ec9142011-02-17 02:28:30 +0000273
Anton Yartsev84f90422015-07-01 22:35:29 +0000274 # Save STDOUT and STDERR of clang to a temporary file and reroute
275 # all clang output to ccc-analyzer's STDERR.
Ted Kremenek370de842008-09-04 00:02:34 +0000276 # We save the output file in the 'crashes' directory if clang encounters
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000277 # any problems with the file.
Ted Kremenek4ab81cb2008-09-11 23:05:26 +0000278 my ($ofh, $ofile) = tempfile("clang_output_XXXXXX", DIR => $HtmlDir);
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000279
Anton Yartsev84f90422015-07-01 22:35:29 +0000280 my $OutputStream = silent_system($HtmlDir, $Cmd, @CmdArgs);
281 while ( <$OutputStream> ) {
Ted Kremenek4ab81cb2008-09-11 23:05:26 +0000282 print $ofh $_;
Ted Kremenek42ec9142011-02-17 02:28:30 +0000283 print STDERR $_;
Ted Kremenek4ab81cb2008-09-11 23:05:26 +0000284 }
Ted Kremenek370de842008-09-04 00:02:34 +0000285 my $Result = $?;
Anton Yartsev84f90422015-07-01 22:35:29 +0000286 close $ofh;
Ted Kremenek370de842008-09-04 00:02:34 +0000287
288 # Did the command die because of a signal?
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000289 if ($ReportFailures) {
Ted Kremenek5c512e62009-12-11 22:44:53 +0000290 if ($Result & 127 and $Cmd eq $Clang and defined $HtmlDir) {
291 ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses,
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000292 $HtmlDir, "Crash", $ofile);
Ted Kremenek078b8872009-02-27 06:17:38 +0000293 }
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000294 elsif ($Result) {
295 if ($IncludeParserRejects && !($file =~/conftest/)) {
Ted Kremenek5c512e62009-12-11 22:44:53 +0000296 ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses,
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000297 $HtmlDir, $ParserRejects, $ofile);
Anna Zaks9fed0842011-11-07 22:38:10 +0000298 } else {
299 ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses,
Jordan Rose85ff8f22012-11-28 19:12:44 +0000300 $HtmlDir, $OtherError, $ofile);
Ted Kremenek13ed6f12009-02-17 23:31:05 +0000301 }
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000302 }
303 else {
304 # Check if there were any unhandled attributes.
305 if (open(CHILD, $ofile)) {
306 my %attributes_not_handled;
Ted Kremenek42ec9142011-02-17 02:28:30 +0000307
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000308 # Don't flag warnings about the following attributes that we
309 # know are currently not supported by Clang.
310 $attributes_not_handled{"cdecl"} = 1;
Ted Kremenek42ec9142011-02-17 02:28:30 +0000311
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000312 my $ppfile;
313 while (<CHILD>) {
314 next if (! /warning: '([^\']+)' attribute ignored/);
315
316 # Have we already spotted this unhandled attribute?
317 next if (defined $attributes_not_handled{$1});
318 $attributes_not_handled{$1} = 1;
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000319
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000320 # Get the name of the attribute file.
321 my $dir = "$HtmlDir/failures";
322 my $afile = "$dir/attribute_ignored_$1.txt";
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000323
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000324 # Only create another preprocessed file if the attribute file
325 # doesn't exist yet.
326 next if (-e $afile);
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000327
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000328 # Add this file to the list of files that contained this attribute.
329 # Generate a preprocessed file if we haven't already.
330 if (!(defined $ppfile)) {
Ted Kremenek5c512e62009-12-11 22:44:53 +0000331 $ppfile = ProcessClangFailure($Clang, $Lang, $file,
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000332 \@CmdArgsSansAnalyses,
333 $HtmlDir, $AttributeIgnored, $ofile);
334 }
335
336 mkpath $dir;
337 open(AFILE, ">$afile");
338 print AFILE "$ppfile\n";
339 close(AFILE);
340 }
341 close CHILD;
342 }
Ted Kremenek13ed6f12009-02-17 23:31:05 +0000343 }
344 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000345
Ted Kremenek90fc8a42009-08-04 00:55:59 +0000346 unlink($ofile);
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000347}
Ted Kremenekf18f4602008-05-24 15:58:54 +0000348
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000349##----------------------------------------------------------------------------##
350# Lookup tables.
351##----------------------------------------------------------------------------##
352
353my %CompileOptionMap = (
354 '-nostdinc' => 0,
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000355 '-include' => 1,
356 '-idirafter' => 1,
Ted Kremeneke869a182010-06-08 18:27:55 +0000357 '-imacros' => 1,
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000358 '-iprefix' => 1,
359 '-iquote' => 1,
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000360 '-iwithprefix' => 1,
361 '-iwithprefixbefore' => 1
362);
363
364my %LinkerOptionMap = (
Ted Kremenek415287d2012-03-06 20:06:12 +0000365 '-framework' => 1,
366 '-fobjc-link-runtime' => 0
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000367);
368
369my %CompilerLinkerOptionMap = (
Jordan Rose525121f2013-07-12 16:07:33 +0000370 '-Wwrite-strings' => 0,
Jordan Rose05b3a8b2013-07-11 23:56:12 +0000371 '-ftrapv-handler' => 1, # specifically call out separated -f flag
Ted Kremenek7c88d2a2012-08-07 19:27:08 +0000372 '-mios-simulator-version-min' => 0, # This really has 1 argument, but always has '='
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000373 '-isysroot' => 1,
374 '-arch' => 1,
Charles Davisdde71b92010-03-02 15:26:41 +0000375 '-m32' => 0,
376 '-m64' => 0,
Benjamin Kramer75e4bb12012-09-19 22:56:24 +0000377 '-stdlib' => 0, # This is really a 1 argument, but always has '='
Jordan Rose57ee6d22014-05-12 17:04:44 +0000378 '--sysroot' => 1,
Jordan Rose687fc9a2013-08-08 16:06:26 +0000379 '-target' => 1,
Ted Kremenek6b2e07a2008-09-29 22:45:28 +0000380 '-v' => 0,
Daniel Dunbar497ff132009-04-10 19:52:24 +0000381 '-mmacosx-version-min' => 0, # This is really a 1 argument, but always has '='
Petr Hosek5326bb42017-05-26 19:25:32 +0000382 '-miphoneos-version-min' => 0, # This is really a 1 argument, but always has '='
383 '--target' => 0
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000384);
385
386my %IgnoredOptionMap = (
Ted Kremenek4a154b22008-07-24 03:52:21 +0000387 '-MT' => 1, # Ignore these preprocessor options.
388 '-MF' => 1,
389
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000390 '-fsyntax-only' => 0,
391 '-save-temps' => 0,
392 '-install_name' => 1,
393 '-exported_symbols_list' => 1,
394 '-current_version' => 1,
395 '-compatibility_version' => 1,
396 '-init' => 1,
397 '-e' => 1,
398 '-seg1addr' => 1,
399 '-bundle_loader' => 1,
400 '-multiply_defined' => 1,
401 '-sectorder' => 3,
402 '--param' => 1,
Anna Zaks3a7f73d2012-01-06 01:54:02 +0000403 '-u' => 1,
404 '--serialize-diagnostics' => 1
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000405);
406
407my %LangMap = (
Jordan Rosea63f2292014-01-07 21:39:51 +0000408 'c' => $IsCXX ? 'c++' : 'c',
Shantonu Sendf44f742010-07-03 03:08:23 +0000409 'cp' => 'c++',
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000410 'cpp' => 'c++',
Anna Zaksd6827412012-04-14 16:30:00 +0000411 'cxx' => 'c++',
412 'txx' => 'c++',
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000413 'cc' => 'c++',
Jordan Rosedbbbf5512012-11-28 19:12:29 +0000414 'C' => 'c++',
Jordan Rosea63f2292014-01-07 21:39:51 +0000415 'ii' => 'c++-cpp-output',
Jonathan Roelofs9cf63022018-01-29 16:37:53 +0000416 'i' => $IsCXX ? 'c++-cpp-output' : 'cpp-output',
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000417 'm' => 'objective-c',
Anna Zaks5efad632011-08-31 23:53:24 +0000418 'mi' => 'objective-c-cpp-output',
Jordan Rosea63f2292014-01-07 21:39:51 +0000419 'mm' => 'objective-c++',
420 'mii' => 'objective-c++-cpp-output',
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000421);
422
Ted Kremenek8b89a652008-09-29 16:15:20 +0000423my %UniqueOptions = (
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000424 '-isysroot' => 0
Ted Kremenek8b89a652008-09-29 16:15:20 +0000425);
426
Ted Kremenekadccbca2010-03-08 19:06:44 +0000427##----------------------------------------------------------------------------##
428# Languages accepted.
429##----------------------------------------------------------------------------##
430
Ted Kremenekdc99ec42009-05-11 21:08:34 +0000431my %LangsAccepted = (
432 "objective-c" => 1,
Ted Kremenekd33c4d32011-08-11 22:47:20 +0000433 "c" => 1,
434 "c++" => 1,
Ted Kremenek38d77472014-02-25 19:16:33 +0000435 "objective-c++" => 1,
Jonathan Roelofs9cf63022018-01-29 16:37:53 +0000436 "cpp-output" => 1,
Ted Kremenek38d77472014-02-25 19:16:33 +0000437 "objective-c-cpp-output" => 1,
438 "c++-cpp-output" => 1
Ted Kremenekdc99ec42009-05-11 21:08:34 +0000439);
440
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000441##----------------------------------------------------------------------------##
442# Main Logic.
443##----------------------------------------------------------------------------##
444
445my $Action = 'link';
446my @CompileOpts;
447my @LinkOpts;
448my @Files;
449my $Lang;
450my $Output;
Ted Kremenek8b89a652008-09-29 16:15:20 +0000451my %Uniqued;
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000452
453# Forward arguments to gcc.
Ted Kremenekf65a0c62009-12-15 02:35:54 +0000454my $Status = system($Compiler,@ARGV);
Jordan Rose1187b952013-07-03 16:42:02 +0000455if (defined $ENV{'CCC_ANALYZER_LOG'}) {
456 print STDERR "$Compiler @ARGV\n";
Tom Carea5f13c862010-09-29 23:48:31 +0000457}
Ted Kremenek1a422782008-08-28 01:18:44 +0000458if ($Status) { exit($Status >> 8); }
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000459
460# Get the analysis options.
461my $Analyses = $ENV{'CCC_ANALYZER_ANALYSIS'};
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000462
Anna Zaks268f1542012-05-25 01:13:50 +0000463# Get the plugins to load.
464my $Plugins = $ENV{'CCC_ANALYZER_PLUGINS'};
465
Zhongxing Xuad4c3de2008-10-27 14:26:32 +0000466# Get the store model.
467my $StoreModel = $ENV{'CCC_ANALYZER_STORE_MODEL'};
Ted Kremenekb5351812009-02-17 04:27:41 +0000468
469# Get the constraints engine.
470my $ConstraintsModel = $ENV{'CCC_ANALYZER_CONSTRAINTS_MODEL'};
Zhongxing Xuad4c3de2008-10-27 14:26:32 +0000471
Anna Zaks7aa36872012-06-22 22:08:12 +0000472#Get the internal stats setting.
473my $InternalStats = $ENV{'CCC_ANALYZER_INTERNAL_STATS'};
474
Ted Kremenek90230552008-11-04 00:02:53 +0000475# Get the output format.
476my $OutputFormat = $ENV{'CCC_ANALYZER_OUTPUT_FORMAT'};
Ted Kremenekd3d16aa2009-02-17 05:01:10 +0000477if (!defined $OutputFormat) { $OutputFormat = "html"; }
Ted Kremenek90230552008-11-04 00:02:53 +0000478
Jordan Rose3dcbca32013-12-13 17:16:28 +0000479# Get the config options.
480my $ConfigOptions = $ENV{'CCC_ANALYZER_CONFIG'};
481
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000482# Determine the level of verbosity.
483my $Verbose = 0;
Jordan Rose1187b952013-07-03 16:42:02 +0000484if (defined $ENV{'CCC_ANALYZER_VERBOSE'}) { $Verbose = 1; }
485if (defined $ENV{'CCC_ANALYZER_LOG'}) { $Verbose = 2; }
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000486
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000487# Get the HTML output directory.
488my $HtmlDir = $ENV{'CCC_ANALYZER_HTML'};
489
Yury Gribova6560eb2016-02-18 11:08:46 +0000490# Get force-analyze-debug-code option.
491my $ForceAnalyzeDebugCode = $ENV{'CCC_ANALYZER_FORCE_ANALYZE_DEBUG_CODE'};
492
Ted Kremenek9b15eff2009-02-24 22:07:12 +0000493my %DisabledArchs = ('ppc' => 1, 'ppc64' => 1);
Ted Kremenek15146a52008-09-25 20:17:57 +0000494my %ArchsSeen;
Ted Kremenek9b15eff2009-02-24 22:07:12 +0000495my $HadArch = 0;
Ted Kremenek398f46f2014-12-31 07:44:51 +0000496my $HasSDK = 0;
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000497
498# Process the arguments.
499foreach (my $i = 0; $i < scalar(@ARGV); ++$i) {
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000500 my $Arg = $ARGV[$i];
Artem Dergachev473d0d72019-09-05 00:44:56 +0000501 my @ArgParts = split /=/,$Arg,2;
Sylvestre Ledruea27b932019-09-13 09:31:19 +0000502 my $ArgKey = $ArgParts[0];
Ted Kremenekad4a57d2008-10-19 06:42:38 +0000503
Anna Zaks50b09562015-03-28 02:17:21 +0000504 # Be friendly to "" in the argument list.
505 if (!defined($ArgKey)) {
506 next;
507 }
508
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000509 # Modes ccc-analyzer supports
Ted Kremenekba8d7fc2009-08-04 00:57:12 +0000510 if ($Arg =~ /^-(E|MM?)$/) { $Action = 'preprocess'; }
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000511 elsif ($Arg eq '-c') { $Action = 'compile'; }
512 elsif ($Arg =~ /^-print-prog-name/) { exit 0; }
Ted Kremenek15146a52008-09-25 20:17:57 +0000513
514 # Specially handle duplicate cases of -arch
515 if ($Arg eq "-arch") {
516 my $arch = $ARGV[$i+1];
Ted Kremenek9b15eff2009-02-24 22:07:12 +0000517 # We don't want to process 'ppc' because of Clang's lack of support
518 # for Altivec (also some #defines won't likely be defined correctly, etc.)
519 if (!(defined $DisabledArchs{$arch})) { $ArchsSeen{$arch} = 1; }
520 $HadArch = 1;
Ted Kremenek15146a52008-09-25 20:17:57 +0000521 ++$i;
522 next;
523 }
524
Ted Kremenek398f46f2014-12-31 07:44:51 +0000525 # On OSX/iOS, record if an SDK path was specified. This
526 # is innocuous for other platforms, so the check just happens.
527 if ($Arg =~ /^-isysroot/) {
528 $HasSDK = 1;
529 }
530
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000531 # Options with possible arguments that should pass through to compiler.
Ted Kremenekad4a57d2008-10-19 06:42:38 +0000532 if (defined $CompileOptionMap{$ArgKey}) {
533 my $Cnt = $CompileOptionMap{$ArgKey};
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000534 push @CompileOpts,$Arg;
535 while ($Cnt > 0) { ++$i; --$Cnt; push @CompileOpts, $ARGV[$i]; }
536 next;
537 }
Ted Kremenek3cfba5b2013-02-14 00:32:25 +0000538 # Handle the case where there isn't a space after -iquote
Jordan Rose69ab7262014-03-19 17:42:26 +0000539 if ($Arg =~ /^-iquote.*/) {
Ted Kremenek3cfba5b2013-02-14 00:32:25 +0000540 push @CompileOpts,$Arg;
541 next;
542 }
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000543
544 # Options with possible arguments that should pass through to linker.
Ted Kremenekad4a57d2008-10-19 06:42:38 +0000545 if (defined $LinkerOptionMap{$ArgKey}) {
546 my $Cnt = $LinkerOptionMap{$ArgKey};
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000547 push @LinkOpts,$Arg;
548 while ($Cnt > 0) { ++$i; --$Cnt; push @LinkOpts, $ARGV[$i]; }
549 next;
550 }
551
552 # Options with possible arguments that should pass through to both compiler
553 # and the linker.
Ted Kremenekad4a57d2008-10-19 06:42:38 +0000554 if (defined $CompilerLinkerOptionMap{$ArgKey}) {
555 my $Cnt = $CompilerLinkerOptionMap{$ArgKey};
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000556
Ted Kremenek8b89a652008-09-29 16:15:20 +0000557 # Check if this is an option that should have a unique value, and if so
558 # determine if the value was checked before.
559 if ($UniqueOptions{$Arg}) {
560 if (defined $Uniqued{$Arg}) {
561 $i += $Cnt;
562 next;
563 }
564 $Uniqued{$Arg} = 1;
565 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000566
567 push @CompileOpts,$Arg;
Ted Kremenek887c49d2008-09-29 23:06:09 +0000568 push @LinkOpts,$Arg;
569
Artem Dergachev473d0d72019-09-05 00:44:56 +0000570 if (scalar @ArgParts == 1) {
571 while ($Cnt > 0) {
572 ++$i; --$Cnt;
573 push @CompileOpts, $ARGV[$i];
574 push @LinkOpts, $ARGV[$i];
575 }
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000576 }
577 next;
578 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000579
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000580 # Ignored options.
Ted Kremenekad4a57d2008-10-19 06:42:38 +0000581 if (defined $IgnoredOptionMap{$ArgKey}) {
582 my $Cnt = $IgnoredOptionMap{$ArgKey};
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000583 while ($Cnt > 0) {
584 ++$i; --$Cnt;
585 }
586 next;
587 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000588
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000589 # Compile mode flags.
Devin Coughlin8e850d42015-10-26 17:19:51 +0000590 if ($Arg =~ /^-(?:[DIU]|isystem)(.*)$/) {
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000591 my $Tmp = $Arg;
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000592 if ($1 eq '') {
593 # FIXME: Check if we are going off the end.
594 ++$i;
595 $Tmp = $Arg . $ARGV[$i];
596 }
597 push @CompileOpts,$Tmp;
598 next;
599 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000600
Jordan Rose69ab7262014-03-19 17:42:26 +0000601 if ($Arg =~ /^-m.*/) {
Jordan Rose476bbb022013-10-22 18:55:18 +0000602 push @CompileOpts,$Arg;
603 next;
604 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000605
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000606 # Language.
607 if ($Arg eq '-x') {
608 $Lang = $ARGV[$i+1];
609 ++$i; next;
610 }
Ted Kremenekf18f4602008-05-24 15:58:54 +0000611
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000612 # Output file.
613 if ($Arg eq '-o') {
614 ++$i;
615 $Output = $ARGV[$i];
616 next;
617 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000618
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000619 # Get the link mode.
620 if ($Arg =~ /^-[l,L,O]/) {
621 if ($Arg eq '-O') { push @LinkOpts,'-O1'; }
622 elsif ($Arg eq '-Os') { push @LinkOpts,'-O2'; }
623 else { push @LinkOpts,$Arg; }
Jordan Rose05b3a8b2013-07-11 23:56:12 +0000624
625 # Must pass this along for the __OPTIMIZE__ macro
626 if ($Arg =~ /^-O/) { push @CompileOpts,$Arg; }
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000627 next;
628 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000629
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000630 if ($Arg =~ /^-std=/) {
631 push @CompileOpts,$Arg;
632 next;
633 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000634
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000635 # Get the compiler/link mode.
636 if ($Arg =~ /^-F(.+)$/) {
637 my $Tmp = $Arg;
638 if ($1 eq '') {
639 # FIXME: Check if we are going off the end.
640 ++$i;
641 $Tmp = $Arg . $ARGV[$i];
642 }
643 push @CompileOpts,$Tmp;
644 push @LinkOpts,$Tmp;
645 next;
646 }
Ted Kremenekf18f4602008-05-24 15:58:54 +0000647
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000648 # Input files.
649 if ($Arg eq '-filelist') {
650 # FIXME: Make sure we aren't walking off the end.
651 open(IN, $ARGV[$i+1]);
652 while (<IN>) { s/\015?\012//; push @Files,$_; }
653 close(IN);
Ted Kremenekd0d72562009-08-14 18:20:50 +0000654 ++$i;
655 next;
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000656 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000657
Jordan Rose05b3a8b2013-07-11 23:56:12 +0000658 if ($Arg =~ /^-f/) {
659 push @CompileOpts,$Arg;
660 push @LinkOpts,$Arg;
661 next;
662 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000663
Ted Kremenekd0d72562009-08-14 18:20:50 +0000664 # Handle -Wno-. We don't care about extra warnings, but
665 # we should suppress ones that we don't want to see.
666 if ($Arg =~ /^-Wno-/) {
667 push @CompileOpts, $Arg;
668 next;
669 }
670
Devin Coughlin26c5df22015-10-25 01:30:18 +0000671 # Handle -Xclang some-arg. Add both arguments to the compiler options.
672 if ($Arg =~ /^-Xclang$/) {
673 # FIXME: Check if we are going off the end.
674 ++$i;
675 push @CompileOpts, $Arg;
676 push @CompileOpts, $ARGV[$i];
677 next;
678 }
679
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000680 if (!($Arg =~ /^-/)) {
Ted Kremenekd0d72562009-08-14 18:20:50 +0000681 push @Files, $Arg;
682 next;
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000683 }
684}
Ted Kremenekf18f4602008-05-24 15:58:54 +0000685
Yury Gribova6560eb2016-02-18 11:08:46 +0000686# Forcedly enable debugging if requested by user.
687if ($ForceAnalyzeDebugCode) {
688 push @CompileOpts, '-UNDEBUG';
689}
690
Ted Kremenek398f46f2014-12-31 07:44:51 +0000691# If we are on OSX and have an installation where the
692# default SDK is inferred by xcrun use xcrun to infer
693# the SDK.
694if (not $HasSDK and $UseXCRUN) {
695 my $sdk = `/usr/bin/xcrun --show-sdk-path -sdk macosx`;
696 chomp $sdk;
697 push @CompileOpts, "-isysroot", $sdk;
698}
699
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000700if ($Action eq 'compile' or $Action eq 'link') {
Ted Kremenek9b15eff2009-02-24 22:07:12 +0000701 my @Archs = keys %ArchsSeen;
702 # Skip the file if we don't support the architectures specified.
Ted Kremenek86cb75a2009-02-25 00:10:37 +0000703 exit 0 if ($HadArch && scalar(@Archs) == 0);
Jordan Rose85ff8f22012-11-28 19:12:44 +0000704
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000705 foreach my $file (@Files) {
706 # Determine the language for the file.
707 my $FileLang = $Lang;
708
709 if (!defined($FileLang)) {
710 # Infer the language from the extension.
711 if ($file =~ /[.]([^.]+)$/) {
712 $FileLang = $LangMap{$1};
713 }
714 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000715
Ted Kremenek14015de2010-02-12 00:10:34 +0000716 # FileLang still not defined? Skip the file.
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000717 next if (!defined $FileLang);
Ted Kremenek14015de2010-02-12 00:10:34 +0000718
719 # Language not accepted?
Ted Kremenekdc99ec42009-05-11 21:08:34 +0000720 next if (!defined $LangsAccepted{$FileLang});
Ted Kremenek14015de2010-02-12 00:10:34 +0000721
Ted Kremenek46727df2009-05-15 04:20:31 +0000722 my @CmdArgs;
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000723 my @AnalyzeArgs;
724
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000725 if ($FileLang ne 'unknown') {
Ted Kremenekd4bcb4f2011-03-16 21:10:42 +0000726 push @CmdArgs, '-x', $FileLang;
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000727 }
Ted Kremenek5efdf842008-03-25 22:35:32 +0000728
Zhongxing Xuad4c3de2008-10-27 14:26:32 +0000729 if (defined $StoreModel) {
Ted Kremenekb5351812009-02-17 04:27:41 +0000730 push @AnalyzeArgs, "-analyzer-store=$StoreModel";
Zhongxing Xuad4c3de2008-10-27 14:26:32 +0000731 }
Ted Kremenekb5351812009-02-17 04:27:41 +0000732
733 if (defined $ConstraintsModel) {
734 push @AnalyzeArgs, "-analyzer-constraints=$ConstraintsModel";
735 }
Anna Zaks7aa36872012-06-22 22:08:12 +0000736
737 if (defined $InternalStats) {
738 push @AnalyzeArgs, "-analyzer-stats";
739 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000740
Anna Zaks5efad632011-08-31 23:53:24 +0000741 if (defined $Analyses) {
742 push @AnalyzeArgs, split '\s+', $Analyses;
743 }
Ted Kremenekb5351812009-02-17 04:27:41 +0000744
Anna Zaks268f1542012-05-25 01:13:50 +0000745 if (defined $Plugins) {
746 push @AnalyzeArgs, split '\s+', $Plugins;
747 }
748
Ted Kremenek90230552008-11-04 00:02:53 +0000749 if (defined $OutputFormat) {
Ted Kremenekb5351812009-02-17 04:27:41 +0000750 push @AnalyzeArgs, "-analyzer-output=" . $OutputFormat;
Aaron Ballman7d880862018-12-13 20:55:34 +0000751 if ($OutputFormat =~ /plist/ || $OutputFormat =~ /sarif/) {
Ted Kremenek13747162009-01-21 00:42:24 +0000752 # Change "Output" to be a file.
Aaron Ballman7d880862018-12-13 20:55:34 +0000753 my $Suffix = $OutputFormat =~ /plist/ ? ".plist" : ".sarif";
754 my ($h, $f) = tempfile("report-XXXXXX", SUFFIX => $Suffix,
Ted Kremenek13747162009-01-21 00:42:24 +0000755 DIR => $HtmlDir);
756 $ResultFile = $f;
Alp Tokerf6a24ce2013-12-05 16:25:25 +0000757 # If the HtmlDir is not set, we should clean up the plist files.
Aaron Ballman70964d42019-07-24 20:03:27 +0000758 if (!defined $HtmlDir || $HtmlDir eq "") {
Jordan Rose85ff8f22012-11-28 19:12:44 +0000759 $CleanupFile = $f;
Anna Zaks45ce1bf2011-09-09 18:43:53 +0000760 }
Ted Kremenek13747162009-01-21 00:42:24 +0000761 }
Ted Kremenek90230552008-11-04 00:02:53 +0000762 }
Jordan Rose3dcbca32013-12-13 17:16:28 +0000763 if (defined $ConfigOptions) {
764 push @AnalyzeArgs, split '\s+', $ConfigOptions;
765 }
Zhongxing Xuad4c3de2008-10-27 14:26:32 +0000766
Ted Kremenek42ec9142011-02-17 02:28:30 +0000767 push @CmdArgs, @CompileOpts;
768 push @CmdArgs, $file;
Zhongxing Xuad4c3de2008-10-27 14:26:32 +0000769
Ted Kremenek15146a52008-09-25 20:17:57 +0000770 if (scalar @Archs) {
771 foreach my $arch (@Archs) {
772 my @NewArgs;
Ted Kremenekd4bcb4f2011-03-16 21:10:42 +0000773 push @NewArgs, '-arch', $arch;
Ted Kremenek46727df2009-05-15 04:20:31 +0000774 push @NewArgs, @CmdArgs;
Ted Kremenek5c512e62009-12-11 22:44:53 +0000775 Analyze($Clang, \@NewArgs, \@AnalyzeArgs, $FileLang, $Output,
Ted Kremenek42ec9142011-02-17 02:28:30 +0000776 $Verbose, $HtmlDir, $file);
Ted Kremenek15146a52008-09-25 20:17:57 +0000777 }
778 }
779 else {
Ted Kremenek5c512e62009-12-11 22:44:53 +0000780 Analyze($Clang, \@CmdArgs, \@AnalyzeArgs, $FileLang, $Output,
Ted Kremenek42ec9142011-02-17 02:28:30 +0000781 $Verbose, $HtmlDir, $file);
Ted Kremenek15146a52008-09-25 20:17:57 +0000782 }
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000783 }
784}