Page MenuHomePhabricator

[analyzer] New flag to print all -analyzer-config options
ClosedPublic

Authored by Szelethus on Oct 15 2018, 11:29 AM.

Details

Summary

Title says it all, here's how it look like locally:

OVERVIEW: Clang Static Analyzer -analyzer-config Option List

USAGE: clang -cc1 [CLANG_OPTIONS] -analyzer-config <OPTION1=VALUE,OPTION2=VALUE,...>

       clang -cc1 [CLANG_OPTIONS] -analyzer-config OPTION1=VALUE, -analyzer-config OPTION2=VALUE, ...

       clang [CLANG_OPTIONS] -Xclang -analyzer-config -Xclang<OPTION1=VALUE,OPTION2=VALUE,...>

       clang [CLANG_OPTIONS] -Xclang -analyzer-config -Xclang OPTION1=VALUE, -Xclang -analyzer-config -Xclang OPTION2=VALUE, ...

OPTIONS:

  aggressive-binary-operation-simplification
                                (bool) Whether SValBuilder should rearrange
                                comparisons and additive operations of symbolic
                                expressions which consist of a sum of a
                                symbol and a concrete integer into the format
                                where symbols are on the left-hand side
                                and the integer is on the right. This is
                                only done if both symbols and both concrete
                                integers are signed, greater than or equal
                                to the quarter of the minimum value of the
                                type and less than or equal to the quarter
                                of the maximum value of that type. A + n
                                <OP> B + m becomes A - B <OP> m - n, where
                                A and B symbolic, n and m are integers.
                                <OP> is any of '==', '!=', '<', '<=', '>',
                                '>=', '+' or '-'. The rearrangement also
                                happens with '-' instead of '+' on either
                                or both side and also if any or both integers
                                are missing. (default: false)

  avoid-suppressing-null-argument-paths
                                (bool) Whether a bug report should not be
                                suppressed if its path includes a call with
                                a null argument, even if that call has a
                                null return. This option has no effect when
                                #shouldSuppressNullReturnPaths() is false.
                                This is a counter-heuristic to avoid false
                                negatives. (default: false)

  c++-allocator-inlining        (bool) Whether or not allocator call may
                                be considered for inlining. (default: true)

  c++-container-inlining        (bool) Whether or not methods of C++ container
                                objects may be considered for inlining.
                                (default: false)

  c++-inlining                  (string) Controls which C++ member functions
                                will be considered for inlining. Value:
                                "constructors", "destructors", "methods".
                                (default: "destructors")

  c++-shared_ptr-inlining       (bool) Whether or not the destructor of
                                C++ 'shared_ptr' may be considered for inlining.
                                This covers std::shared_ptr, std::tr1::shared_ptr,
                                and boost::shared_ptr, and indeed any destructor
                                named '~shared_ptr'. (default: false)

  c++-stdlib-inlining           (bool) Whether or not C++ standard library
                                functions may be considered for inlining.
                                (default: true)

  c++-temp-dtor-inlining        (bool) Whether C++ temporary destructors
                                should be inlined during analysis. If temporary
                                destructors are disabled in the CFG via
                                the 'cfg-temporary-dtors' option, temporary
                                destructors would not be inlined anyway.
                                (default: true)

  c++-template-inlining         (bool) Whether or not templated functions
                                may be considered for inlining. (default:
                                true)

  cfg-conditional-static-initializers
                                (bool) Whether 'static' initializers should
                                be in conditional logic in the CFG. (default:
                                true)

  cfg-implicit-dtors            (bool) Whether or not implicit destructors
                                for C++ objects should be included in the
                                CFG. (default: true)

  cfg-lifetime                  (bool) Whether or not end-of-lifetime information
                                should be included in the CFG. (default:
                                false)

  cfg-loopexit                  (bool) Whether or not the end of the loop
                                information should be included in the CFG.
                                (default: false)

  cfg-rich-constructors         (bool) Whether or not construction site
                                information should be included in the CFG
                                C++ constructor elements. (default: true)

  cfg-scopes                    (bool) Whether or not scope information
                                should be included in the CFG. (default:
                                false)

  cfg-temporary-dtors           (bool) Whether or not the destructors for
                                C++ temporary objects should be included
                                in the CFG. (default: true)

  crosscheck-with-z3            (bool) Whether bug reports should be crosschecked
                                with the Z3 constraint manager backend.
                                (default: false)

  ctu-dir                       (string) The directory containing the CTU
                                related files. (default: "")

  ctu-index-name                (string) the name of the file containing
                                the CTU index of functions. (default: "externalFnMap.txt")

  eagerly-assume                (bool) Whether we should eagerly assume
                                evaluations of conditionals, thus, bifurcating
                                the path. This indicates how the engine
                                should handle expressions such as: 'x =
                                (y != 0)'. When this is true then the subexpression
                                'y != 0' will be eagerly assumed to be true
                                or false, thus evaluating it to the integers
                                0 or 1 respectively. The upside is that
                                this can increase analysis precision until
                                we have a better way to lazily evaluate
                                such logic. The downside is that it eagerly
                                bifurcates paths. (default: true)

  elide-constructors            (bool) Whether elidable C++ copy-constructors
                                and move-constructors should be actually
                                elided during analysis. Both behaviors are
                                allowed by the C++ standard, and the analyzer,
                                like CodeGen, defaults to eliding. Starting
                                with C++17 some elisions become mandatory,
                                and in these cases the option will be ignored.
                                (default: true)

  experimental-enable-naive-ctu-analysis
                                (bool) Whether naive cross translation unit
                                analysis is enabled. This is an experimental
                                feature to inline functions from another
                                translation units. (default: false)

  exploration_strategy          (string) Value: "dfs", "bfs", "unexplored_first",
                                "unexplored_first_queue", "unexplored_first_location_queue",
                                "bfs_block_dfs_contents". (default: "unexplored_first_queue")

  faux-bodies                   (bool) Whether the analyzer engine should
                                synthesize fake bodies for well-known functions.
                                (default: true)

  graph-trim-interval           (unsigned) How often nodes in the ExplodedGraph
                                should be recycled to save memory. To disable
                                node reclamation, set the option to 0. (default:
                                1000)

  inline-lambdas                (bool) Whether lambdas should be inlined.
                                Otherwise a sink node will be generated
                                each time a LambdaExpr is visited. (default:
                                true)

  ipa                           (string) Controls the mode of inter-procedural
                                analysis. Value: "none", "basic-inlining",
                                "inlining", "dynamic", "dynamic-bifurcate".
                                (default: "inlining" in shallow mode, "dynamic-bifurcate"
                                in deep mode)

  ipa-always-inline-size        (unsigned) The size of the functions (in
                                basic blocks), which should be considered
                                to be small enough to always inline. (default:
                                3)

  max-inlinable-size            (unsigned) The bound on the number of basic
                                blocks in an inlined function. (default:
                                4 in shallow mode, 100 in deep mode)

  max-nodes                     (unsigned) The maximum number of nodes the
                                analyzer can generate while exploring a
                                top level function (for each exploded graph).
                                0 means no limit. (default: 75000 in shallow
                                mode, 225000 in deep mode)

  max-symbol-complexity         (unsigned) The maximum complexity of symbolic
                                constraint. (default: 35)

  max-times-inline-large        (unsigned) The maximum times a large function
                                could be inlined. (default: 32)

  min-cfg-size-treat-functions-as-large
                                (unsigned) The number of basic blocks a
                                function needs to have to be considered
                                large for the 'max-times-inline-large' config
                                option. (default: 14)

  mode                          (string) Controls the high-level analyzer
                                mode, which influences the default settings
                                for some of the lower-level config options
                                (such as IPAMode). Value: "deep", "shallow".
                                (default: "deep")

  model-path                    (string) The analyzer can inline an alternative
                                implementation written in C at the call
                                site if the called function's body is not
                                available. This is a path where to look
                                for those alternative implementations (called
                                models). (default: "")

  notes-as-events               (bool) Whether the bug reporter should transparently
                                treat extra note diagnostic pieces as event
                                diagnostic pieces. Useful when the diagnostic
                                consumer doesn't support the extra note
                                pieces. (default: false)

  objc-inlining                 (bool) Whether ObjectiveC inlining is enabled,
                                false otherwise. (default: true)

  prune-paths                   (bool) Whether irrelevant parts of a bug
                                report path should be pruned out of the
                                final output. (default: true)

  region-store-small-struct-limit
                                (unsigned) Returns the maximum number of
                                nodes the analyzer can generate while exploring
                                a top level function (for each exploded
                                graph). 0 means no limit. (default: 2)

  report-in-main-source-file    (bool) Whether or not the diagnostic report
                                should be always reported in the main source
                                file and not the headers. (default: false)

  serialize-stats               (bool) Whether the analyzer should serialize
                                statistics to plist output. Statistics would
                                be serialized in JSON format inside the
                                main dictionary under the statistics key.
                                Available only if compiled in assert mode
                                or with LLVM statistics explicitly enabled.
                                (default: false)

  stable-report-filename        (bool) Whether or not the report filename
                                should be random or not. (default: false)

  suppress-c++-stdlib           (bool) Whether or not diagnostics reported
                                within the C++ standard library should be
                                suppressed. (default: true)

  suppress-inlined-defensive-checks
                                (bool) Whether or not diagnostics containing
                                inlined defensive NULL checks should be
                                suppressed. (default: true)

  suppress-null-return-paths    (bool) Whether or not paths that go through
                                null returns should be suppressed. This
                                is a heuristic for avoiding bug reports
                                with paths that go through inlined functions
                                that are more defensive than their callers.
                                (default: true)

  unroll-loops                  (bool) Whether the analysis should try to
                                unroll loops with known bounds. (default:
                                false)

  widen-loops                   (bool) Whether the analysis should try to
                                widen loops. (default: false)

Diff Detail

Repository
rL LLVM

Event Timeline

Szelethus created this revision.Oct 15 2018, 11:29 AM
george.karpenkov requested changes to this revision.Oct 15 2018, 3:19 PM

+1, I think this is a great addition!

BTW in theory it should be possible to go wild on compile-time programming, and generate the entire description string at compile time,
but it does not seem to be worth it.

Also, you seem to be missing tests (at least to verify that the code does not crash).

Also, that's a lot of code for printing options. I understand it's hard to do wrapping properly, but I'm not sure whether it makes sense for half of the CheckerRegistration.cpp file to be doing option wrapping for help printing.
Could you look into simpler alternatives? (or if your wrapping printer is indeed indispensable, maybe it should go somewhere into llvm/lib/Support/format?)
I am not sure what would be a better solution here, maybe it's already possible to write something much smaller using components from lib/Support.

This revision now requires changes to proceed.Oct 15 2018, 3:19 PM

Cheers, thanks for the review!

Also, that's a lot of code for printing options. I understand it's hard to do wrapping properly, but I'm not sure whether it makes sense for half of the CheckerRegistration.cpp file to be doing option wrapping for help printing.
Could you look into simpler alternatives? (or if your wrapping printer is indeed indispensable, maybe it should go somewhere into llvm/lib/Support/format?)
I am not sure what would be a better solution here, maybe it's already possible to write something much smaller using components from lib/Support.

Aye, the formatting looks a little ridiculous. I'm not making a good job selling this, but I'm somewhat surprised it even works. Thanks for the suggestions, I'll take a look -- I wanted to find an existing solution while writing this, but didn't try hard enough.

dkrupp added a subscriber: dkrupp.Oct 16 2018, 1:51 AM
Szelethus updated this revision to Diff 169925.Oct 16 2018, 4:56 PM
Szelethus edited the summary of this revision. (Show Details)

Using llvm::formatted_raw_ostream to drastically simplify the previous solution.

The actual output changed a little bit too, now I'm printing a newline at the first space after the width of the line exceeds 70. Updated the summary accordingly.

Szelethus updated this revision to Diff 169927.Oct 16 2018, 5:06 PM
Szelethus edited the summary of this revision. (Show Details)

Added a test.

nhaehnle removed a subscriber: nhaehnle.Oct 17 2018, 3:25 AM
NoQ accepted this revision.Oct 19 2018, 6:52 PM

I'll use this.

And i think it's unfair to give users -analyzer-config and not give them a list of options. Users should be able to discover either both or none of the two. If a user goes far enough to start digging into non-driver options, such user only benefits from knowing what the options are.

There's a separate story about dumping options in a machine-readable way, as discussed in the developer meeting, so that GUIs/wrappers could assert their own internal consistency.

include/clang/Driver/CC1Options.td
132 ↗(On Diff #169927)

I'm in favor of analyzer-config-help, similar to -analyzer-checker-help so that it was easier to remember.

Overall looks good, minor comments inline.

lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
166 ↗(On Diff #169927)

Is analyzer-config a cc1 or a driver argument? Just make sure if it is cc1, to add the corresponding flags or the -Xclang passthrough in the help string.

195 ↗(On Diff #169927)

Redundant braces.

Szelethus updated this revision to Diff 170432.Oct 22 2018, 8:50 AM
Szelethus edited the summary of this revision. (Show Details)

Fixes according to inline comments, type and default value are generated now.

Szelethus marked 3 inline comments as done.Oct 22 2018, 8:56 AM
Szelethus updated this revision to Diff 170438.Oct 22 2018, 9:00 AM

Good to go, with minor nits inline.

lib/FrontendTool/ExecuteCompilerInvocation.cpp
255 ↗(On Diff #170438)

Hm, should we return here?
If there are errors, which are only printed in the next part, should they still be printed?

test/Analysis/analyzer-list-configs.c
13 ↗(On Diff #170438)

Just to be sure, I would hardcode checking for at least the first option here.

This revision is now accepted and ready to land.Oct 22 2018, 10:53 AM
Szelethus updated this revision to Diff 171611.Oct 29 2018, 4:27 PM

Hardcoded the first entry as suggested by @george.karpenkov.

Szelethus marked 2 inline comments as done.Oct 29 2018, 4:27 PM

Thanks! :)

lib/FrontendTool/ExecuteCompilerInvocation.cpp
255 ↗(On Diff #170438)

I'd prefer to return as every other option. I think the user, if -analyzer-config-help was supplied, is only interested in a config option list.

This revision was automatically updated to reflect the committed changes.
This revision was automatically updated to reflect the committed changes.
Szelethus marked an inline comment as done.