On 11/15/19 6:22 PM, David Malcolm wrote:
This patch kit introduces a static analysis pass for GCC that can diagnose various kinds of problems in C code at compile-time (e.g. double-free, use-after-free, etc).
I haven't looked at the analyzer bits in any detail yet so I have just some very high-level questions. But first let me say I'm excited to see this project! :) It looks like the analyzer detects some of the same problems as some existing middle-end warnings (e.g., -Wnonnull, -Wuninitialized), and some that I have been working toward implementing (invalid uses of freed pointers such as returning them from functions or passing them to others), and others still that I have been thinking about as possible future projects (e.g., detecting uses of uninitialized arrays in string functions). What are your thoughts about this sort of overlap? Do you expect us to enhance both sets of warnings in parallel, or do you see us moving away from issuing warnings in the middle-end and toward making the analyzer the main source of these kinds of diagnostics? Maybe even replace some of the problematic middle-end warnings with the analyzer? What (if anything) should we do about warnings issued for the same problems by both the middle-end and the analyzer? Or about false negatives? E.g., a bug detected by the middle-end but not the analyzer or vice versa. What do you see as the biggest pros and cons of either approach? (Middle-end vs analyzer.) What limitations is the analyzer approach inherently subject to that the middle-end warnings aren't, and vice versa? How do we prioritize between the two approaches (e.g., choose where to add a new warning)? Martin
The analyzer runs as an IPA pass on the gimple SSA representation. It associates state machines with data, with transitions at certain statements and edges. It finds "interesting" interprocedural paths through the user's code, in which bogus state transitions happen. For example, given: free (ptr); free (ptr); at the first call, "ptr" transitions to the "freed" state, and at the second call the analyzer complains, since "ptr" is already in the "freed" state (unless "ptr" is NULL, in which case it stays in the NULL state for both calls). Specific state machines include: - a checker for malloc/free, for detecting double-free, resource leaks, use-after-free, etc (sm-malloc.cc), and - a checker for stdio's FILE stream API (sm-file.cc) There are also two state-machine-based checkers that are just proof-of-concept at this stage: - a checker for tracking exposure of sensitive data (e.g. writing passwords to log files aka CWE-532), and - a checker for tracking "taint", where data potentially under an attacker's control is used without sanitization for things like array indices (CWE-129). There's a separation between the state machines and the analysis engine, so it ought to be relatively easy to add new warnings. For any given diagnostic emitted by a state machine, the analysis engine generates the simplest feasible interprocedural path of control flow for triggering the diagnostic. Diagnostic paths ================ The patch kit adds support to GCC's diagnostic subsystem for optionally associating a "diagnostic_path" with a diagnostic. A diagnostic path describes a sequence of events predicted by the compiler that leads to the problem occurring, with their locations in the user's source, and text descriptions. For example, the following warning has a 6-event interprocedural path: malloc-ipa-8-unchecked.c: In function 'make_boxed_int': malloc-ipa-8-unchecked.c:21:13: warning: dereference of possibly-NULL 'result' [CWE-690] [-Wanalyzer-possible-null-dereference] 21 | result->i = i; | ~~~~~~~~~~^~~ 'make_boxed_int': events 1-2 | | 18 | make_boxed_int (int i) | | ^~~~~~~~~~~~~~ | | | | | (1) entry to 'make_boxed_int' | 19 | { | 20 | boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int)); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (2) calling 'wrapped_malloc' from 'make_boxed_int' | +--> 'wrapped_malloc': events 3-4 | | 7 | void *wrapped_malloc (size_t size) | | ^~~~~~~~~~~~~~ | | | | | (3) entry to 'wrapped_malloc' | 8 | { | 9 | return malloc (size); | | ~~~~~~~~~~~~~ | | | | | (4) this call could return NULL | <------+ | 'make_boxed_int': events 5-6 | | 20 | boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int)); | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (5) possible return of NULL to 'make_boxed_int' from 'wrapped_malloc' | 21 | result->i = i; | | ~~~~~~~~~~~~~ | | | | | (6) 'result' could be NULL: unchecked value from (4) | The diagnostic-printing code has consolidated the path into 3 runs of events (where the events are near each other and within the same function), using ASCII art to show the interprocedural call and return. A colorized version of the above can be seen at: https://dmalcolm.fedorapeople.org/gcc/2019-11-13/test.html Other examples can be seen at: https://dmalcolm.fedorapeople.org/gcc/2019-11-13/malloc-1.c.html https://dmalcolm.fedorapeople.org/gcc/2019-11-13/setjmp-4.c.html An example of detecting a historical double-free CVE can be seen at: https://dmalcolm.fedorapeople.org/gcc/2019-11-13/CVE-2005-1689.html (there are also some false positives in this report) Diagnostic metadata =================== The patch kit also adds the ability to associate additional metadata with a diagnostic. The only such metadata added by the patch kit are CWE classifications (for the new warnings), such as the CWE-690 in the warning above, or CWE-401 in this example: malloc-1.c: In function 'test_42a': malloc-1.c:466:1: warning: leak of 'p' [CWE-401] [-Wanalyzer-malloc-leak] 466 | } | ^ 'test_42a': events 1-2 | | 463 | void *p = malloc (1024); | | ^~~~~~~~~~~~~ | | | | | (1) allocated here |...... | 466 | } | | ~ | | | | | (2) 'p' leaks here; was allocated at (1) | If the terminal supports it, the above "CWE-401" is a clickable hyperlink to: https://cwe.mitre.org/data/definitions/401.html Scope ===== The checker is implemented as a GCC plugin. The patch kit adds support for "in-tree" plugins i.e. GCC plugins that would live in the GCC source tree and be shipped as part of the GCC tarball, with a new: --enable-plugins=[LIST OF PLUGIN NAMES] configure option, analogous to --enable-languages (the Makefile/configure machinery for handling in-tree GCC plugins is adapted from how we support frontends). The default is for no such plugins to be enabled, so the default would be that the checker isn't built - you'd have to opt-in to building it, with --enable-plugins=analyzer To mitigate feature creep, I've been focusing on implementing double-free detection, albeit with an eye to building something that can be developed into a more fully-featured static analyzer. For example, I haven't yet attempted to track buffer overflows in this version, but I believe that that could be added on top of this foundation. Many projects implement some kind of wrapper around malloc and free, so there is enough interprocedural support to cope with that, but only very primitive support for summarizing larger functions and planning/performing an efficient interprocedural analysis on non-trivial functions that have state-machine effects. In theory the analyzer can work with LTO, and perform cross-TU analysis. There's a bare-bones prototype of this in the testsuite, which finds a double-free spanning two TUs; see: https://dmalcolm.fedorapeople.org/gcc/2019-11-15/double-free-lto-1.STAR.c.html However this is just a proof-of-concept at this stage (see the internal docs for more notes on its limitations). User interface ============== --analyzer turns on all the analyzer warnings (it also enables the expensive traversal that they rely on); individual warnings are all prefixed "-Wanalyzer-" and can be turned off in the usual way e.g. -Wno-analyzer-use-after-free. Rationale ========= There's benefit in integrating a checker directly into the compiler, so that the programmer can see the diagnostics as he or she works on the code, rather than at some later point. I think that if the analyzer can be made sufficiently fast that many people would opt-in to deeper but more expensive warnings. (I'm aiming for 2x compile time as my rough estimate of what's reasonable in exchange for being told up-front about various kinds of pointer snafu). Correctness =========== The analyzer is neither sound nor complete, but does attempt to explore "interesting" paths through the code and generate meaningful diagnostics. There are no known ICEs, but there are bugs... (see the xfails and TODOs in the testsuite, and the "Limitations" section of the internal docs). Performance =========== Using --analyzer roughly doubles the compile time on various testcases I've tried (krb5, zlib), but also sometimes takes a lot longer (again, see the "Limitations" section of the internal docs; there are bugs...). Overview of patch kit ===================== Patch 01 contains user-facing documentation for the analyzer Patch 02 documents the implementation internals (to avoid having to repeat it here) Patches 03-15 are preliminary work. Patch 11 adds metadata support to GCC's diagnostic subsystem, so that the analyzer can associate CWE identifiers with diagnostics. Patch 12 adds diagnostic_path support to to GCC's diagnostic subsystem Patches 16-17 add support for in-tree plugins Patches 18-24 add the basics of the analyzer plugin itself Patches 25-48 adds the analysis "machinery" Patches 33-38 add the state machines (somewhat abstracted from the rest of the analyzer) Patch 49 adds the test suite for the analyzer The patches can also be seen on the git mirror as branch "dmalcolm/analyzer-v1" https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/dmalcolm/analyzer-v1 This is relative to r276961 (which predates the recent update to how params work). Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. The analyzer works on toy examples, and on some moderately-sized real world codebases (krb5 and zlib). I'd hoped to have tested it more deeply at this point (and dogfooded it), but given that GCC stage 1 is closing shortly I thought I ought to post what I have. It's not clear to me whether I should focus on: (a) pruning the scope of the checker so that it works well on *intra*procedural C examples (and bail on anything more complex), perhaps targetting GCC 10 as an optional extra hidden behind --enable-plugins=analyzer, or (b) work on deeper interprocedural analysis (and fixing efficiency issues with this). See also: https://gcc.gnu.org/wiki/DavidMalcolm/StaticAnalyzer (which currently duplicates much of the above). Thoughts? David David Malcolm (49): analyzer: user-facing documentation analyzer: internal documentation diagnostic_show_locus: move initial newline to callers sbitmap.h: add operator const sbitmap & to auto_sbitmap vec.h: add auto_delete_vec timevar.h: add auto_client_timevar class Replace label_text ctor with "borrow" and "take" Introduce pretty_printer::clone vfunc gimple const-correctness fixes Add -fdiagnostics-nn-line-numbers Add diagnostic_metadata and CWE support Add diagnostic paths function-tests.c: expose selftest::make_fndecl for use elsewhere hash-map-tests.c: add a selftest involving int_hash Add ordered_hash_map Add support for in-tree plugins Support for adding selftests via a plugin Add in-tree plugin: "analyzer" analyzer: new files: analyzer-selftests.{cc|h} analyzer: new builtins analyzer: command-line options analyzer: params.def: new parameters analyzer: logging support analyzer: new file: analyzer-pass.cc analyzer: new files: graphviz.{cc|h} analyzer: new files: digraph.{cc|h} and shortest-paths.h analyzer: new files: supergraph.{cc|h} analyzer: new files: analyzer.{cc|h} analyzer: new files: tristate.{cc|h} analyzer: new files: constraint-manager.{cc|h} analyzer: new files: region-model.{cc|h} analyzer: new files: pending-diagnostic.{cc|h} analyzer: new files: sm.{cc|h} analyzer: new file: sm-malloc.cc analyzer: new file: sm-file.cc analyzer: new file: sm-pattern-test.cc analyzer: new file: sm-sensitive.cc analyzer: new file: sm-taint.cc analyzer: new files: analysis-plan.{cc|h} analyzer: new files: call-string.{cc|h} analyzer: new files: program-point.{cc|h} analyzer: new files: program-state.{cc|h} analyzer: new file: exploded-graph.h analyzer: new files: state-purge.{cc|h} analyzer: new files: engine.{cc|h} analyzer: new files: checker-path.{cc|h} analyzer: new files: diagnostic-manager.{cc|h} gdbinit.in: add break-on-saved-diagnostic analyzer: test suite configure.ac | 6 + gcc/Makefile.in | 102 +- gcc/analyzer/Make-plugin.in | 181 + gcc/analyzer/analysis-plan.cc | 115 + gcc/analyzer/analysis-plan.h | 56 + gcc/analyzer/analyzer-logging.cc | 220 + gcc/analyzer/analyzer-logging.h | 256 + gcc/analyzer/analyzer-pass.cc | 103 + gcc/analyzer/analyzer-plugin.cc | 63 + gcc/analyzer/analyzer-selftests.cc | 61 + gcc/analyzer/analyzer-selftests.h | 46 + gcc/analyzer/analyzer.cc | 125 + gcc/analyzer/analyzer.h | 126 + gcc/analyzer/call-string.cc | 201 + gcc/analyzer/call-string.h | 74 + gcc/analyzer/checker-path.cc | 899 +++ gcc/analyzer/checker-path.h | 563 ++ gcc/analyzer/config-plugin.in | 34 + gcc/analyzer/constraint-manager.cc | 2263 ++++++ gcc/analyzer/constraint-manager.h | 248 + gcc/analyzer/diagnostic-manager.cc | 1117 +++ gcc/analyzer/diagnostic-manager.h | 116 + gcc/analyzer/digraph.cc | 189 + gcc/analyzer/digraph.h | 248 + gcc/analyzer/engine.cc | 3416 +++++++++ gcc/analyzer/engine.h | 26 + gcc/analyzer/exploded-graph.h | 754 ++ gcc/analyzer/graphviz.cc | 81 + gcc/analyzer/graphviz.h | 50 + gcc/analyzer/pending-diagnostic.cc | 61 + gcc/analyzer/pending-diagnostic.h | 265 + gcc/analyzer/plugin.opt | 161 + gcc/analyzer/program-point.cc | 490 ++ gcc/analyzer/program-point.h | 316 + gcc/analyzer/program-state.cc | 1284 ++++ gcc/analyzer/program-state.h | 360 + gcc/analyzer/region-model.cc | 7686 ++++++++++++++++++++ gcc/analyzer/region-model.h | 2076 ++++++ gcc/analyzer/shortest-paths.h | 147 + gcc/analyzer/sm-file.cc | 338 + gcc/analyzer/sm-malloc.cc | 799 ++ gcc/analyzer/sm-pattern-test.cc | 165 + gcc/analyzer/sm-sensitive.cc | 209 + gcc/analyzer/sm-taint.cc | 338 + gcc/analyzer/sm.cc | 135 + gcc/analyzer/sm.h | 160 + gcc/analyzer/state-purge.cc | 516 ++ gcc/analyzer/state-purge.h | 170 + gcc/analyzer/supergraph.cc | 936 +++ gcc/analyzer/supergraph.h | 560 ++ gcc/analyzer/tristate.cc | 222 + gcc/analyzer/tristate.h | 82 + gcc/builtins.def | 33 + gcc/c-family/c-format.c | 15 +- gcc/c-family/c-format.h | 1 + gcc/c-family/c-opts.c | 1 + gcc/c-family/c-pretty-print.c | 7 + gcc/c-family/c-pretty-print.h | 1 + gcc/c/c-objc-common.c | 4 +- gcc/common.opt | 31 + gcc/configure.ac | 172 +- gcc/coretypes.h | 1 + gcc/cp/cxx-pretty-print.c | 8 + gcc/cp/cxx-pretty-print.h | 2 + gcc/cp/error.c | 9 +- gcc/diagnostic-color.c | 3 +- gcc/diagnostic-core.h | 10 + gcc/diagnostic-event-id.h | 61 + gcc/diagnostic-format-json.cc | 33 +- gcc/diagnostic-metadata.h | 42 + gcc/diagnostic-path.h | 149 + gcc/diagnostic-show-locus.c | 219 +- gcc/diagnostic.c | 283 +- gcc/diagnostic.def | 5 + gcc/diagnostic.h | 43 +- gcc/doc/analyzer.texi | 470 ++ gcc/doc/gccint.texi | 2 + gcc/doc/install.texi | 9 + gcc/doc/invoke.texi | 600 +- gcc/dwarf2out.c | 1 + gcc/fortran/error.c | 1 + gcc/function-tests.c | 4 +- gcc/gcc-rich-location.c | 2 +- gcc/gcc-rich-location.h | 6 +- gcc/gcc.c | 13 + gcc/gdbinit.in | 10 + gcc/gimple-predict.h | 4 +- gcc/gimple-pretty-print.c | 159 +- gcc/gimple-pretty-print.h | 3 +- gcc/gimple.h | 156 +- gcc/hash-map-tests.c | 41 + gcc/lto-wrapper.c | 3 + gcc/opts.c | 16 + gcc/ordered-hash-map-tests.cc | 247 + gcc/ordered-hash-map.h | 184 + gcc/params.def | 25 + gcc/plugin.c | 2 + gcc/plugin.def | 3 + gcc/pretty-print.c | 66 + gcc/pretty-print.h | 4 + gcc/sbitmap.h | 1 + gcc/selftest-run-tests.c | 6 + gcc/selftest.h | 9 + .../gcc.dg/analyzer/CVE-2005-1689-minimal.c | 30 + gcc/testsuite/gcc.dg/analyzer/abort.c | 71 + gcc/testsuite/gcc.dg/analyzer/alloca-leak.c | 8 + .../gcc.dg/analyzer/analyzer-verbosity-0.c | 133 + .../gcc.dg/analyzer/analyzer-verbosity-1.c | 160 + .../gcc.dg/analyzer/analyzer-verbosity-2.c | 191 + gcc/testsuite/gcc.dg/analyzer/analyzer.exp | 49 + gcc/testsuite/gcc.dg/analyzer/attribute-nonnull.c | 57 + gcc/testsuite/gcc.dg/analyzer/call-summaries-1.c | 14 + gcc/testsuite/gcc.dg/analyzer/conditionals-2.c | 44 + gcc/testsuite/gcc.dg/analyzer/conditionals-3.c | 45 + .../gcc.dg/analyzer/conditionals-notrans.c | 158 + gcc/testsuite/gcc.dg/analyzer/conditionals-trans.c | 143 + gcc/testsuite/gcc.dg/analyzer/data-model-1.c | 1078 +++ gcc/testsuite/gcc.dg/analyzer/data-model-10.c | 17 + gcc/testsuite/gcc.dg/analyzer/data-model-11.c | 6 + gcc/testsuite/gcc.dg/analyzer/data-model-12.c | 13 + gcc/testsuite/gcc.dg/analyzer/data-model-13.c | 21 + gcc/testsuite/gcc.dg/analyzer/data-model-14.c | 24 + gcc/testsuite/gcc.dg/analyzer/data-model-15.c | 34 + gcc/testsuite/gcc.dg/analyzer/data-model-16.c | 50 + gcc/testsuite/gcc.dg/analyzer/data-model-17.c | 20 + gcc/testsuite/gcc.dg/analyzer/data-model-18.c | 20 + gcc/testsuite/gcc.dg/analyzer/data-model-19.c | 31 + gcc/testsuite/gcc.dg/analyzer/data-model-2.c | 13 + gcc/testsuite/gcc.dg/analyzer/data-model-3.c | 15 + gcc/testsuite/gcc.dg/analyzer/data-model-4.c | 16 + gcc/testsuite/gcc.dg/analyzer/data-model-5.c | 100 + gcc/testsuite/gcc.dg/analyzer/data-model-5b.c | 91 + gcc/testsuite/gcc.dg/analyzer/data-model-5c.c | 84 + gcc/testsuite/gcc.dg/analyzer/data-model-5d.c | 63 + gcc/testsuite/gcc.dg/analyzer/data-model-6.c | 13 + gcc/testsuite/gcc.dg/analyzer/data-model-7.c | 19 + gcc/testsuite/gcc.dg/analyzer/data-model-8.c | 24 + gcc/testsuite/gcc.dg/analyzer/data-model-9.c | 32 + gcc/testsuite/gcc.dg/analyzer/data-model-path-1.c | 13 + .../gcc.dg/analyzer/double-free-lto-1-a.c | 16 + .../gcc.dg/analyzer/double-free-lto-1-b.c | 8 + gcc/testsuite/gcc.dg/analyzer/double-free-lto-1.h | 1 + gcc/testsuite/gcc.dg/analyzer/equivalence.c | 29 + gcc/testsuite/gcc.dg/analyzer/explode-1.c | 60 + gcc/testsuite/gcc.dg/analyzer/explode-2.c | 50 + gcc/testsuite/gcc.dg/analyzer/factorial.c | 7 + gcc/testsuite/gcc.dg/analyzer/fibonacci.c | 9 + gcc/testsuite/gcc.dg/analyzer/fields.c | 41 + gcc/testsuite/gcc.dg/analyzer/file-1.c | 37 + gcc/testsuite/gcc.dg/analyzer/file-2.c | 18 + gcc/testsuite/gcc.dg/analyzer/function-ptr-1.c | 8 + gcc/testsuite/gcc.dg/analyzer/function-ptr-2.c | 43 + gcc/testsuite/gcc.dg/analyzer/function-ptr-3.c | 17 + gcc/testsuite/gcc.dg/analyzer/gzio-2.c | 11 + gcc/testsuite/gcc.dg/analyzer/gzio-3.c | 31 + gcc/testsuite/gcc.dg/analyzer/gzio-3a.c | 27 + gcc/testsuite/gcc.dg/analyzer/gzio.c | 17 + gcc/testsuite/gcc.dg/analyzer/infinite-recursion.c | 55 + gcc/testsuite/gcc.dg/analyzer/loop-2.c | 36 + gcc/testsuite/gcc.dg/analyzer/loop-2a.c | 39 + gcc/testsuite/gcc.dg/analyzer/loop-3.c | 17 + gcc/testsuite/gcc.dg/analyzer/loop-4.c | 41 + gcc/testsuite/gcc.dg/analyzer/loop.c | 33 + gcc/testsuite/gcc.dg/analyzer/malloc-1.c | 565 ++ gcc/testsuite/gcc.dg/analyzer/malloc-2.c | 23 + gcc/testsuite/gcc.dg/analyzer/malloc-3.c | 8 + gcc/testsuite/gcc.dg/analyzer/malloc-dce.c | 12 + gcc/testsuite/gcc.dg/analyzer/malloc-dedupe-1.c | 46 + gcc/testsuite/gcc.dg/analyzer/malloc-ipa-1.c | 24 + gcc/testsuite/gcc.dg/analyzer/malloc-ipa-10.c | 32 + gcc/testsuite/gcc.dg/analyzer/malloc-ipa-11.c | 95 + gcc/testsuite/gcc.dg/analyzer/malloc-ipa-12.c | 7 + gcc/testsuite/gcc.dg/analyzer/malloc-ipa-13.c | 30 + gcc/testsuite/gcc.dg/analyzer/malloc-ipa-2.c | 34 + gcc/testsuite/gcc.dg/analyzer/malloc-ipa-3.c | 23 + gcc/testsuite/gcc.dg/analyzer/malloc-ipa-4.c | 13 + gcc/testsuite/gcc.dg/analyzer/malloc-ipa-5.c | 13 + gcc/testsuite/gcc.dg/analyzer/malloc-ipa-6.c | 22 + gcc/testsuite/gcc.dg/analyzer/malloc-ipa-7.c | 29 + .../gcc.dg/analyzer/malloc-ipa-8-double-free.c | 172 + .../gcc.dg/analyzer/malloc-ipa-8-unchecked.c | 66 + gcc/testsuite/gcc.dg/analyzer/malloc-ipa-9.c | 18 + .../gcc.dg/analyzer/malloc-macro-inline-events.c | 45 + .../gcc.dg/analyzer/malloc-macro-separate-events.c | 15 + gcc/testsuite/gcc.dg/analyzer/malloc-macro.h | 2 + .../gcc.dg/analyzer/malloc-many-paths-1.c | 14 + .../gcc.dg/analyzer/malloc-many-paths-2.c | 30 + .../gcc.dg/analyzer/malloc-many-paths-3.c | 36 + gcc/testsuite/gcc.dg/analyzer/malloc-paths-1.c | 15 + gcc/testsuite/gcc.dg/analyzer/malloc-paths-10.c | 19 + gcc/testsuite/gcc.dg/analyzer/malloc-paths-2.c | 13 + gcc/testsuite/gcc.dg/analyzer/malloc-paths-3.c | 14 + gcc/testsuite/gcc.dg/analyzer/malloc-paths-4.c | 20 + gcc/testsuite/gcc.dg/analyzer/malloc-paths-5.c | 43 + gcc/testsuite/gcc.dg/analyzer/malloc-paths-6.c | 11 + gcc/testsuite/gcc.dg/analyzer/malloc-paths-7.c | 21 + gcc/testsuite/gcc.dg/analyzer/malloc-paths-8.c | 54 + gcc/testsuite/gcc.dg/analyzer/malloc-paths-9.c | 298 + gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-1a.c | 180 + gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-1b.c | 175 + gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-2.c | 178 + gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-3.c | 65 + gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-4.c | 40 + gcc/testsuite/gcc.dg/analyzer/operations.c | 42 + gcc/testsuite/gcc.dg/analyzer/params-2.c | 16 + gcc/testsuite/gcc.dg/analyzer/params.c | 32 + gcc/testsuite/gcc.dg/analyzer/paths-1.c | 16 + gcc/testsuite/gcc.dg/analyzer/paths-1a.c | 16 + gcc/testsuite/gcc.dg/analyzer/paths-2.c | 25 + gcc/testsuite/gcc.dg/analyzer/paths-3.c | 48 + gcc/testsuite/gcc.dg/analyzer/paths-4.c | 49 + gcc/testsuite/gcc.dg/analyzer/paths-5.c | 10 + gcc/testsuite/gcc.dg/analyzer/paths-6.c | 118 + gcc/testsuite/gcc.dg/analyzer/paths-7.c | 58 + gcc/testsuite/gcc.dg/analyzer/pattern-test-1.c | 28 + gcc/testsuite/gcc.dg/analyzer/pattern-test-2.c | 29 + gcc/testsuite/gcc.dg/analyzer/pointer-merging.c | 16 + gcc/testsuite/gcc.dg/analyzer/pr61861.c | 2 + gcc/testsuite/gcc.dg/analyzer/pragma-1.c | 26 + gcc/testsuite/gcc.dg/analyzer/scope-1.c | 23 + gcc/testsuite/gcc.dg/analyzer/sensitive-1.c | 33 + gcc/testsuite/gcc.dg/analyzer/setjmp-1.c | 1 + gcc/testsuite/gcc.dg/analyzer/setjmp-2.c | 97 + gcc/testsuite/gcc.dg/analyzer/setjmp-3.c | 106 + gcc/testsuite/gcc.dg/analyzer/setjmp-4.c | 107 + gcc/testsuite/gcc.dg/analyzer/setjmp-5.c | 65 + gcc/testsuite/gcc.dg/analyzer/setjmp-6.c | 31 + gcc/testsuite/gcc.dg/analyzer/setjmp-7.c | 36 + gcc/testsuite/gcc.dg/analyzer/setjmp-8.c | 107 + gcc/testsuite/gcc.dg/analyzer/setjmp-9.c | 109 + gcc/testsuite/gcc.dg/analyzer/switch.c | 28 + gcc/testsuite/gcc.dg/analyzer/taint-1.c | 128 + gcc/testsuite/gcc.dg/analyzer/zlib-1.c | 67 + gcc/testsuite/gcc.dg/analyzer/zlib-2.c | 51 + gcc/testsuite/gcc.dg/analyzer/zlib-3.c | 214 + gcc/testsuite/gcc.dg/analyzer/zlib-4.c | 20 + gcc/testsuite/gcc.dg/analyzer/zlib-5.c | 49 + gcc/testsuite/gcc.dg/analyzer/zlib-6.c | 47 + gcc/testsuite/gcc.dg/format/gcc_diag-10.c | 6 +- .../gcc.dg/plugin/diagnostic-path-format-default.c | 142 + .../diagnostic-path-format-inline-events-1.c | 142 + .../diagnostic-path-format-inline-events-2.c | 154 + .../diagnostic-path-format-inline-events-3.c | 153 + .../gcc.dg/plugin/diagnostic-path-format-none.c | 43 + .../diagnostic-path-format-separate-events.c | 44 + .../gcc.dg/plugin/diagnostic-test-paths-1.c | 38 + .../gcc.dg/plugin/diagnostic-test-paths-2.c | 56 + .../gcc.dg/plugin/diagnostic-test-paths-3.c | 38 + .../gcc.dg/plugin/diagnostic_plugin_test_paths.c | 379 + .../plugin/diagnostic_plugin_test_show_locus.c | 1 + gcc/testsuite/gcc.dg/plugin/plugin.exp | 10 + gcc/testsuite/lib/target-supports.exp | 8 + gcc/timevar.h | 33 + gcc/toplev.c | 8 + gcc/tree-diagnostic-path.cc | 809 ++ gcc/tree-diagnostic.c | 12 +- gcc/tree-diagnostic.h | 8 + gcc/tree-eh.c | 6 +- gcc/tree-eh.h | 4 +- gcc/tree-ssa-alias.h | 2 +- gcc/tree-ssa-structalias.c | 2 +- gcc/vec.c | 27 + gcc/vec.h | 35 + libcpp/include/line-map.h | 38 +- libcpp/line-map.c | 3 +- 265 files changed, 42181 insertions(+), 336 deletions(-) create mode 100644 gcc/analyzer/Make-plugin.in create mode 100644 gcc/analyzer/analysis-plan.cc create mode 100644 gcc/analyzer/analysis-plan.h create mode 100644 gcc/analyzer/analyzer-logging.cc create mode 100644 gcc/analyzer/analyzer-logging.h create mode 100644 gcc/analyzer/analyzer-pass.cc create mode 100644 gcc/analyzer/analyzer-plugin.cc create mode 100644 gcc/analyzer/analyzer-selftests.cc create mode 100644 gcc/analyzer/analyzer-selftests.h create mode 100644 gcc/analyzer/analyzer.cc create mode 100644 gcc/analyzer/analyzer.h create mode 100644 gcc/analyzer/call-string.cc create mode 100644 gcc/analyzer/call-string.h create mode 100644 gcc/analyzer/checker-path.cc create mode 100644 gcc/analyzer/checker-path.h create mode 100644 gcc/analyzer/config-plugin.in create mode 100644 gcc/analyzer/constraint-manager.cc create mode 100644 gcc/analyzer/constraint-manager.h create mode 100644 gcc/analyzer/diagnostic-manager.cc create mode 100644 gcc/analyzer/diagnostic-manager.h create mode 100644 gcc/analyzer/digraph.cc create mode 100644 gcc/analyzer/digraph.h create mode 100644 gcc/analyzer/engine.cc create mode 100644 gcc/analyzer/engine.h create mode 100644 gcc/analyzer/exploded-graph.h create mode 100644 gcc/analyzer/graphviz.cc create mode 100644 gcc/analyzer/graphviz.h create mode 100644 gcc/analyzer/pending-diagnostic.cc create mode 100644 gcc/analyzer/pending-diagnostic.h create mode 100644 gcc/analyzer/plugin.opt create mode 100644 gcc/analyzer/program-point.cc create mode 100644 gcc/analyzer/program-point.h create mode 100644 gcc/analyzer/program-state.cc create mode 100644 gcc/analyzer/program-state.h create mode 100644 gcc/analyzer/region-model.cc create mode 100644 gcc/analyzer/region-model.h create mode 100644 gcc/analyzer/shortest-paths.h create mode 100644 gcc/analyzer/sm-file.cc create mode 100644 gcc/analyzer/sm-malloc.cc create mode 100644 gcc/analyzer/sm-pattern-test.cc create mode 100644 gcc/analyzer/sm-sensitive.cc create mode 100644 gcc/analyzer/sm-taint.cc create mode 100644 gcc/analyzer/sm.cc create mode 100644 gcc/analyzer/sm.h create mode 100644 gcc/analyzer/state-purge.cc create mode 100644 gcc/analyzer/state-purge.h create mode 100644 gcc/analyzer/supergraph.cc create mode 100644 gcc/analyzer/supergraph.h create mode 100644 gcc/analyzer/tristate.cc create mode 100644 gcc/analyzer/tristate.h create mode 100644 gcc/diagnostic-event-id.h create mode 100644 gcc/diagnostic-metadata.h create mode 100644 gcc/diagnostic-path.h create mode 100644 gcc/doc/analyzer.texi create mode 100644 gcc/ordered-hash-map-tests.cc create mode 100644 gcc/ordered-hash-map.h create mode 100644 gcc/testsuite/gcc.dg/analyzer/CVE-2005-1689-minimal.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/abort.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/alloca-leak.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/analyzer-verbosity-0.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/analyzer-verbosity-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/analyzer-verbosity-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/analyzer.exp create mode 100644 gcc/testsuite/gcc.dg/analyzer/attribute-nonnull.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/call-summaries-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/conditionals-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/conditionals-3.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/conditionals-notrans.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/conditionals-trans.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-10.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-11.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-12.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-13.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-14.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-15.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-16.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-17.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-18.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-19.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-3.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-4.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-5.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-5b.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-5c.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-5d.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-6.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-7.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-8.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-9.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-path-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/double-free-lto-1-a.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/double-free-lto-1-b.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/double-free-lto-1.h create mode 100644 gcc/testsuite/gcc.dg/analyzer/equivalence.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/explode-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/explode-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/factorial.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/fibonacci.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/fields.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/file-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/file-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/function-ptr-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/function-ptr-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/function-ptr-3.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/gzio-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/gzio-3.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/gzio-3a.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/gzio.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/infinite-recursion.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/loop-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/loop-2a.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/loop-3.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/loop-4.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/loop.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-3.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-dce.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-dedupe-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-ipa-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-ipa-10.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-ipa-11.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-ipa-12.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-ipa-13.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-ipa-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-ipa-3.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-ipa-4.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-ipa-5.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-ipa-6.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-ipa-7.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8-double-free.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8-unchecked.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-ipa-9.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-macro-inline-events.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-macro-separate-events.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-macro.h create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-many-paths-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-many-paths-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-many-paths-3.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-paths-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-paths-10.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-paths-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-paths-3.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-paths-4.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-paths-5.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-paths-6.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-paths-7.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-paths-8.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-paths-9.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-1a.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-1b.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-3.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-4.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/operations.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/params-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/params.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/paths-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/paths-1a.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/paths-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/paths-3.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/paths-4.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/paths-5.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/paths-6.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/paths-7.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/pattern-test-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/pattern-test-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/pointer-merging.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr61861.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/pragma-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/scope-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/sensitive-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/setjmp-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/setjmp-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/setjmp-3.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/setjmp-4.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/setjmp-5.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/setjmp-6.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/setjmp-7.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/setjmp-8.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/setjmp-9.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/switch.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/taint-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/zlib-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/zlib-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/zlib-3.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/zlib-4.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/zlib-5.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/zlib-6.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-default.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-inline-events-1.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-inline-events-2.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-inline-events-3.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-none.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-separate-events.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-1.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-3.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c create mode 100644 gcc/tree-diagnostic-path.cc