From: Ted Kremenek Date: Thu, 17 Feb 2011 02:28:30 +0000 (+0000) Subject: Begin overhaul of scan-build/ccc-analyzer's handling of checker options. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7fe679f300bd063d7edf7071d14c7f3823ef8cce;p=clang Begin overhaul of scan-build/ccc-analyzer's handling of checker options. We now rely on 'clang --analyze' to provide the default set of checkers. We're still working on the new '-analyzer-checker ' interface, and once that's ready we'll wire it up to scan-build. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125712 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/tools/scan-build/ccc-analyzer b/tools/scan-build/ccc-analyzer index f579e56e80..5601387d79 100755 --- a/tools/scan-build/ccc-analyzer +++ b/tools/scan-build/ccc-analyzer @@ -115,6 +115,7 @@ sub ProcessClangFailure { ##----------------------------------------------------------------------------## sub GetCCArgs { + my $mode = shift; my $Args = shift; pipe (FROM_CHILD, TO_PARENT); @@ -123,7 +124,7 @@ sub GetCCArgs { close FROM_CHILD; open(STDOUT,">&", \*TO_PARENT); open(STDERR,">&", \*TO_PARENT); - exec $Clang, "-###", "-fsyntax-only", @$Args; + exec $Clang, "-###", $mode, @$Args; } close(TO_PARENT); my $line; @@ -137,7 +138,7 @@ sub GetCCArgs { die "could not find clang line\n" if (!defined $line); # Strip the newline and initial whitspace - chomp $line; + chomp $line; $line =~ s/^\s+//; my @items = quotewords('\s+', 0, $line); my $cmd = shift @items; @@ -147,70 +148,72 @@ sub GetCCArgs { sub Analyze { my ($Clang, $Args, $AnalyzeArgs, $Lang, $Output, $Verbose, $HtmlDir, - $file, $Analyses) = @_; - - $Args = GetCCArgs($Args); + $file) = @_; - my $RunAnalyzer = 0; my $Cmd; my @CmdArgs; my @CmdArgsSansAnalyses; - + if ($Lang =~ /header/) { exit 0 if (!defined ($Output)); $Cmd = 'cp'; - push @CmdArgs,$file; + push @CmdArgs, $file; # Remove the PCH extension. $Output =~ s/[.]gch$//; - push @CmdArgs,$Output; - @CmdArgsSansAnalyses = @CmdArgs; + push @CmdArgs, $Output; + @CmdArgsSansAnalyses = @CmdArgs; } else { $Cmd = $Clang; - push @CmdArgs, "-cc1"; - push @CmdArgs,'-DIBOutlet=__attribute__((iboutlet))'; - push @CmdArgs, @$Args; - @CmdArgsSansAnalyses = @CmdArgs; - push @CmdArgs,'-analyze'; - push @CmdArgs,"-analyzer-display-progress"; - push @CmdArgs,"-analyzer-eagerly-assume"; - push @CmdArgs,"-analyzer-opt-analyze-nested-blocks"; - push @CmdArgs,(split /\s/,$Analyses); - - if (defined $ENV{"CCC_EXPERIMENTAL_CHECKS"}) { - push @CmdArgs,"-analyzer-experimental-internal-checks"; - push @CmdArgs,"-analyzer-experimental-checks"; + if ($Lang eq "objective-c" || $Lang eq "objective-c++") { + push @$Args,'-DIBOutlet=__attribute__((iboutlet))'; + push @$Args,'-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection)))'; + push @$Args,'-DIBAction=void)__attribute__((ibaction)'; } - - $RunAnalyzer = 1; - } - - # Add the analysis arguments passed down from scan-build. - foreach my $Arg (@$AnalyzeArgs) { - push @CmdArgs, $Arg; - } - - my @PrintArgs; - my $dir; - if ($RunAnalyzer) { + # Create arguments for doing regular parsing. + my $SyntaxArgs = GetCCArgs("-fsyntax-only", $Args); + @CmdArgsSansAnalyses = @CmdArgs; + push @CmdArgsSansAnalyses, @$SyntaxArgs; + + # Create arguments for doing static analysis. if (defined $ResultFile) { - push @CmdArgs,'-o'; - push @CmdArgs, $ResultFile; + push @$Args,'-o'; + push @$Args, $ResultFile; } elsif (defined $HtmlDir) { - push @CmdArgs,'-o'; - push @CmdArgs, $HtmlDir; + push @$Args,'-o'; + push @$Args, $HtmlDir; + } + push @$Args,"-Xclang"; + push @$Args,"-analyzer-display-progress"; + + foreach my $arg (@$AnalyzeArgs) { + push @$Args, "-Xclang"; + push @$Args, $arg; } + + # Display Ubiviz graph? + if (defined $ENV{'CCC_UBI'}) { + push @$Args, "-Xclang"; + push @$Args,"-analyzer-viz-egraph-ubigraph"; + } + + my $AnalysisArgs = GetCCArgs("--analyze", $Args); + push @CmdArgs, @$AnalysisArgs; } - + + my @PrintArgs; + my $dir; + if ($Verbose) { $dir = getcwd(); print STDERR "\n[LOCATION]: $dir\n"; push @PrintArgs,"'$Cmd'"; - foreach my $arg (@CmdArgs) { push @PrintArgs,"\'$arg\'"; } + foreach my $arg (@CmdArgs) { + push @PrintArgs,"\'$arg\'"; + } } - if ($Verbose == 1) { # We MUST print to stderr. Some clients use the stdout output of # gcc for various purposes. @@ -220,11 +223,7 @@ sub Analyze { elsif ($Verbose == 2) { print STDERR "#SHELL (cd '$dir' && @PrintArgs)\n"; } - - if (defined $ENV{'CCC_UBI'}) { - push @CmdArgs,"--analyzer-viz-egraph-ubigraph"; - } - + # Capture the STDERR of clang and send it to a temporary file. # Capture the STDOUT of clang and reroute it to ccc-analyzer's STDERR. # We save the output file in the 'crashes' directory if clang encounters @@ -237,13 +236,13 @@ sub Analyze { open(STDERR,">&", \*TO_PARENT); exec $Cmd, @CmdArgs; } - + close TO_PARENT; my ($ofh, $ofile) = tempfile("clang_output_XXXXXX", DIR => $HtmlDir); while () { print $ofh $_; - print STDERR $_; + print STDERR $_; } waitpid($pid,0); @@ -266,11 +265,11 @@ sub Analyze { # Check if there were any unhandled attributes. if (open(CHILD, $ofile)) { my %attributes_not_handled; - + # Don't flag warnings about the following attributes that we # know are currently not supported by Clang. $attributes_not_handled{"cdecl"} = 1; - + my $ppfile; while () { next if (! /warning: '([^\']+)' attribute ignored/); @@ -413,15 +412,12 @@ if ($Status) { exit($Status >> 8); } # Get the analysis options. my $Analyses = $ENV{'CCC_ANALYZER_ANALYSIS'}; -if (!defined($Analyses)) { $Analyses = '-analyzer-check-objc-mem'; } # Get the store model. my $StoreModel = $ENV{'CCC_ANALYZER_STORE_MODEL'}; -if (!defined $StoreModel) { $StoreModel = "region"; } # Get the constraints engine. my $ConstraintsModel = $ENV{'CCC_ANALYZER_CONSTRAINTS_MODEL'}; -if (!defined $ConstraintsModel) { $ConstraintsModel = "range"; } # Get the output format. my $OutputFormat = $ENV{'CCC_ANALYZER_OUTPUT_FORMAT'}; @@ -628,6 +624,10 @@ if ($Action eq 'compile' or $Action eq 'link') { if (defined $ConstraintsModel) { push @AnalyzeArgs, "-analyzer-constraints=$ConstraintsModel"; } + +# if (defined $Analyses) { +# push @AnalyzeArgs, split '\s+', $Analyses; +# } if (defined $OutputFormat) { push @AnalyzeArgs, "-analyzer-output=" . $OutputFormat; @@ -640,8 +640,8 @@ if ($Action eq 'compile' or $Action eq 'link') { } } - push @CmdArgs,@CompileOpts; - push @CmdArgs,$file; + push @CmdArgs, @CompileOpts; + push @CmdArgs, $file; if (scalar @Archs) { foreach my $arch (@Archs) { @@ -650,12 +650,12 @@ if ($Action eq 'compile' or $Action eq 'link') { push @NewArgs, $arch; push @NewArgs, @CmdArgs; Analyze($Clang, \@NewArgs, \@AnalyzeArgs, $FileLang, $Output, - $Verbose, $HtmlDir, $file, $Analyses); + $Verbose, $HtmlDir, $file); } } else { Analyze($Clang, \@CmdArgs, \@AnalyzeArgs, $FileLang, $Output, - $Verbose, $HtmlDir, $file, $Analyses); + $Verbose, $HtmlDir, $file); } } } diff --git a/tools/scan-build/scan-build b/tools/scan-build/scan-build index 843df9a841..80585b1f7c 100755 --- a/tools/scan-build/scan-build +++ b/tools/scan-build/scan-build @@ -99,32 +99,6 @@ else { } my $ClangCXX = $Clang . "++"; -my %AvailableAnalyses; - -# Query clang for analysis options. -open(PIPE, "-|", $Clang, "-cc1", "-help") or - DieDiag("Cannot execute '$Clang'\n"); - -while() { - if (/(-analyzer-check-[^\s]+)/) { - $AvailableAnalyses{$1} = 1; - next; - } -} -close (PIPE); - -my %AnalysesDefaultEnabled = ( - '-analyzer-check-dead-stores' => 1, - '-analyzer-check-objc-mem' => 1, - '-analyzer-check-objc-methodsigs' => 1, - '-analyzer-check-objc-self-init' => 1, - # Do not enable the missing -dealloc check by default. - # '-analyzer-check-objc-missing-dealloc' => 1, - '-analyzer-check-objc-unused-ivars' => 1, - '-analyzer-check-security-syntactic' => 1, - '-analyzer-check-idempotent-operations' => 1 -); - ##----------------------------------------------------------------------------## # GetHTMLRunDir - Construct an HTML directory name for the current sub-run. ##----------------------------------------------------------------------------## @@ -969,8 +943,6 @@ OPTIONS: -analyze-headers - Also analyze functions in #included files. - --experimental-checks - Enable experimental checks that are currently in heavy testing - -o - Target directory for HTML report files. Subdirectories will be created as needed to represent separate "runs" of the analyzer. If this option is not specified, a directory @@ -1031,22 +1003,10 @@ ADVANCED OPTIONS: -maxloop N - specifiy the number of times a block can be visited before giving up. Default is 3. Increase for more comprehensive coverage at a cost of speed. - -AVAILABLE ANALYSES (multiple analyses may be specified): - ENDTEXT - foreach my $Analysis (sort keys %AvailableAnalyses) { - if (defined $AnalysesDefaultEnabled{$Analysis}) { - print " (+)"; - } - else { - print " "; - } - - print " $Analysis\n"; - } - +# FIXME: Print out available analyesis. + print <= 3) { $ENV{'CCC_ANALYZER_LOG'} = 1; } -if (scalar(@AnalysesToRun) == 0) { - foreach my $key (keys %AnalysesDefaultEnabled) { - push @AnalysesToRun,$key; - } -} - if ($AnalyzeHeaders) { push @AnalysesToRun,"-analyzer-opt-analyze-headers"; }