https://gcc.gnu.org/g:3cd267446755ab6b2c59936a718d34c8bc474ca5
commit r15-533-g3cd267446755ab6b2c59936a718d34c8bc474ca5 Author: David Malcolm <dmalc...@redhat.com> Date: Wed May 15 21:22:51 2024 -0400 diagnostics: simplify output of purely intraprocedural execution paths Diagnostic path printing was added in r10-5901-g4bc1899b2e883f. As of that commit, with -fdiagnostics-path-format=inline-events (the default), we print a vertical line to the left of the source line numbering, visualizing the stack depth and interprocedural calls and returns as indentation changes. For cases where the events on a thread are purely interprocedural, this line does nothing except take up space and complicate the output. This patch adds logic to omit it for such cases, simpifying the output, and, I believe, improving readability. gcc/ChangeLog: * diagnostic-path.h: Update leading comment to reflect intraprocedural cases. Fix typo in comment. * doc/invoke.texi: Update intraprocedural example. gcc/testsuite/ChangeLog: * c-c++-common/analyzer/allocation-size-multiline-1.c: Update expected results for purely intraprocedural path. * c-c++-common/analyzer/allocation-size-multiline-2.c: Likewise. * c-c++-common/analyzer/allocation-size-multiline-3.c: Likewise. * c-c++-common/analyzer/analyzer-verbosity-0.c: Likewise. * c-c++-common/analyzer/analyzer-verbosity-1.c: Likewise. * c-c++-common/analyzer/analyzer-verbosity-2.c: Likewise. * c-c++-common/analyzer/analyzer-verbosity-3.c: Likewise. * c-c++-common/analyzer/malloc-macro-inline-events.c: Likewise. Doing so for this file requires a rewrite since the paths prefixing the "in expansion of macro" lines become the only thing on their line and so are no longer pruned by multiline.exp logic for pruning extra content on non-blank lines. * c-c++-common/analyzer/malloc-paths-9-noexcept.c: Likewise. * c-c++-common/analyzer/setjmp-2.c: Likewise. * gcc.dg/analyzer/malloc-paths-9.c: Likewise. * gcc.dg/analyzer/out-of-bounds-multiline-2.c: Likewise. * gcc.dg/plugin/diagnostic-test-paths-2.c: Likewise. gcc/ChangeLog: * tree-diagnostic-path.cc (per_thread_summary::interprocedural_p): New. (thread_event_printer::print_swimlane_for_event_range): Don't indent and print the stack depth line if this thread's events are purely intraprocedural. (selftest::test_intraprocedural_path): Update expected output. Signed-off-by: David Malcolm <dmalc...@redhat.com> Diff: --- gcc/diagnostic-path.h | 32 +- gcc/doc/invoke.texi | 30 +- .../analyzer/allocation-size-multiline-1.c | 68 +-- .../analyzer/allocation-size-multiline-2.c | 72 +-- .../analyzer/allocation-size-multiline-3.c | 48 +- .../c-c++-common/analyzer/analyzer-verbosity-0.c | 40 +- .../c-c++-common/analyzer/analyzer-verbosity-1.c | 40 +- .../c-c++-common/analyzer/analyzer-verbosity-2.c | 40 +- .../c-c++-common/analyzer/analyzer-verbosity-3.c | 40 +- .../analyzer/malloc-macro-inline-events.c | 83 +-- .../analyzer/malloc-paths-9-noexcept.c | 604 ++++++++++----------- gcc/testsuite/c-c++-common/analyzer/setjmp-2.c | 140 +++-- gcc/testsuite/gcc.dg/analyzer/malloc-paths-9.c | 302 +++++------ .../gcc.dg/analyzer/out-of-bounds-multiline-2.c | 21 +- .../gcc.dg/plugin/diagnostic-test-paths-2.c | 30 +- gcc/tree-diagnostic-path.cc | 86 ++- 16 files changed, 799 insertions(+), 877 deletions(-) diff --git a/gcc/diagnostic-path.h b/gcc/diagnostic-path.h index fb7abe88ed32..696991c6d736 100644 --- a/gcc/diagnostic-path.h +++ b/gcc/diagnostic-path.h @@ -41,22 +41,20 @@ class sarif_object; 29 | PyList_Append(list, item); | ^~~~~~~~~~~~~~~~~~~~~~~~~ 'demo': events 1-3 - | - | 25 | list = PyList_New(0); - | | ^~~~~~~~~~~~~ - | | | - | | (1) when 'PyList_New' fails, returning NULL - | 26 | - | 27 | for (i = 0; i < count; i++) { - | | ~~~ - | | | - | | (2) when 'i < count' - | 28 | item = PyLong_FromLong(random()); - | 29 | PyList_Append(list, item); - | | ~~~~~~~~~~~~~~~~~~~~~~~~~ - | | | - | | (3) when calling 'PyList_Append', passing NULL from (1) as argument 1 - | + 25 | list = PyList_New(0); + | ^~~~~~~~~~~~~ + | | + | (1) when 'PyList_New' fails, returning NULL + 26 | + 27 | for (i = 0; i < count; i++) { + | ~~~ + | | + | (2) when 'i < count' + 28 | item = PyLong_FromLong(random()); + 29 | PyList_Append(list, item); + | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | | + | (3) when calling 'PyList_Append', passing NULL from (1) as argument 1 The diagnostic-printing code has consolidated the path into a single run of events, since all the events are near each other and within the same @@ -146,7 +144,7 @@ class diagnostic_event virtual tree get_fndecl () const = 0; - /* Stack depth, so that consumers can visualizes the interprocedural + /* Stack depth, so that consumers can visualize the interprocedural calls, returns, and frame nesting. */ virtual int get_stack_depth () const = 0; diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index cedc1a28c834..bcf518ac279a 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -5598,22 +5598,20 @@ For example, the same events as above might be printed as: @smallexample 'test': events 1-3 - | - | 25 | list = PyList_New(0); - | | ^~~~~~~~~~~~~ - | | | - | | (1) when 'PyList_New' fails, returning NULL - | 26 | - | 27 | for (i = 0; i < count; i++) @{ - | | ~~~ - | | | - | | (2) when 'i < count' - | 28 | item = PyLong_FromLong(random()); - | 29 | PyList_Append(list, item); - | | ~~~~~~~~~~~~~~~~~~~~~~~~~ - | | | - | | (3) when calling 'PyList_Append', passing NULL from (1) as argument 1 - | + 25 | list = PyList_New(0); + | ^~~~~~~~~~~~~ + | | + | (1) when 'PyList_New' fails, returning NULL + 26 | + 27 | for (i = 0; i < count; i++) @{ + | ~~~ + | | + | (2) when 'i < count' + 28 | item = PyLong_FromLong(random()); + 29 | PyList_Append(list, item); + | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | | + | (3) when calling 'PyList_Append', passing NULL from (1) as argument 1 @end smallexample Interprocedural control flow is shown by grouping the events by stack frame, diff --git a/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-1.c b/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-1.c index de1a49c436e8..bc8319471757 100644 --- a/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-1.c @@ -12,25 +12,21 @@ void test_constant_1 (void) int32_t *ptr = (int32_t *) __builtin_malloc (1); ^~~~~~~~~~~~~~~~~~~~ 'test_constant_1': events 1-2 - | - | int32_t *ptr = (int32_t *) __builtin_malloc (1); - | ^~~~~~~~~~~~~~~~~~~~ - | | - | (1) allocated 1 byte here - | (2) assigned to 'int32_t *' - | + int32_t *ptr = (int32_t *) __builtin_malloc (1); + ^~~~~~~~~~~~~~~~~~~~ + | + (1) allocated 1 byte here + (2) assigned to 'int32_t *' { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } int32_t *ptr = (int32_t *) __builtin_malloc (1); ~~~~~~~~~~~~~~~~~^~~ 'void test_constant_1()': events 1-2 - | - | int32_t *ptr = (int32_t *) __builtin_malloc (1); - | ~~~~~~~~~~~~~~~~~^~~ - | | - | (1) allocated 1 byte here - | (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' - | + int32_t *ptr = (int32_t *) __builtin_malloc (1); + ~~~~~~~~~~~~~~~~~^~~ + | + (1) allocated 1 byte here + (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' { dg-end-multiline-output "" { target c++ } } */ void test_constant_2 (void) @@ -43,26 +39,22 @@ void test_constant_2 (void) int32_t *ptr = (int32_t *) __builtin_malloc (2); ^~~~~~~~~~~~~~~~~~~~ 'test_constant_2': events 1-2 - | - | int32_t *ptr = (int32_t *) __builtin_malloc (2); - | ^~~~~~~~~~~~~~~~~~~~ - | | - | (1) allocated 2 bytes here - | (2) assigned to 'int32_t *' - | + int32_t *ptr = (int32_t *) __builtin_malloc (2); + ^~~~~~~~~~~~~~~~~~~~ + | + (1) allocated 2 bytes here + (2) assigned to 'int32_t *' { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } int32_t *ptr = (int32_t *) __builtin_malloc (2); ~~~~~~~~~~~~~~~~~^~~ 'void test_constant_2()': events 1-2 - | - | int32_t *ptr = (int32_t *) __builtin_malloc (2); - | ~~~~~~~~~~~~~~~~~^~~ - | | - | (1) allocated 2 bytes here - | (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' - | + int32_t *ptr = (int32_t *) __builtin_malloc (2); + ~~~~~~~~~~~~~~~~~^~~ + | + (1) allocated 2 bytes here + (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' { dg-end-multiline-output "" { target c++ } } */ void test_symbolic (int n) @@ -75,22 +67,18 @@ void test_symbolic (int n) int32_t *ptr = (int32_t *) __builtin_malloc (n * 2); ^~~~~~~~~~~~~~~~~~~~~~~~ 'test_symbolic': event 1 - | - | int32_t *ptr = (int32_t *) __builtin_malloc (n * 2); - | ^~~~~~~~~~~~~~~~~~~~~~~~ - | | - | (1) allocated 'n * 2' bytes and assigned to 'int32_t *' - | + int32_t *ptr = (int32_t *) __builtin_malloc (n * 2); + ^~~~~~~~~~~~~~~~~~~~~~~~ + | + (1) allocated 'n * 2' bytes and assigned to 'int32_t *' { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } int32_t *ptr = (int32_t *) __builtin_malloc (n * 2); ~~~~~~~~~~~~~~~~~^~~~~~~ 'void test_symbolic(int)': event 1 - | - | int32_t *ptr = (int32_t *) __builtin_malloc (n * 2); - | ~~~~~~~~~~~~~~~~~^~~~~~~ - | | - | (1) allocated '(n * 2)' bytes and assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' - | + int32_t *ptr = (int32_t *) __builtin_malloc (n * 2); + ~~~~~~~~~~~~~~~~~^~~~~~~ + | + (1) allocated '(n * 2)' bytes and assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-2.c b/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-2.c index a5def2764fe6..cfd6b4f6f4f3 100644 --- a/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-2.c +++ b/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-2.c @@ -12,25 +12,21 @@ void test_constant_1 (void) int32_t *ptr = (int32_t *) __builtin_alloca (1); ^~~~~~~~~~~~~~~~~~~~ 'test_constant_1': events 1-2 - | - | int32_t *ptr = (int32_t *) __builtin_alloca (1); - | ^~~~~~~~~~~~~~~~~~~~ - | | - | (1) allocated 1 byte here - | (2) assigned to 'int32_t *' - | + int32_t *ptr = (int32_t *) __builtin_alloca (1); + ^~~~~~~~~~~~~~~~~~~~ + | + (1) allocated 1 byte here + (2) assigned to 'int32_t *' { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } int32_t *ptr = (int32_t *) __builtin_alloca (1); ~~~~~~~~~~~~~~~~~^~~ 'void test_constant_1()': events 1-2 - | - | int32_t *ptr = (int32_t *) __builtin_alloca (1); - | ~~~~~~~~~~~~~~~~~^~~ - | | - | (1) allocated 1 byte here - | (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' - | + int32_t *ptr = (int32_t *) __builtin_alloca (1); + ~~~~~~~~~~~~~~~~~^~~ + | + (1) allocated 1 byte here + (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' { dg-end-multiline-output "" { target c++ } } */ void test_constant_2 (void) @@ -42,25 +38,21 @@ void test_constant_2 (void) int32_t *ptr = (int32_t *) __builtin_alloca (2); ^~~~~~~~~~~~~~~~~~~~ 'test_constant_2': events 1-2 - | - | int32_t *ptr = (int32_t *) __builtin_alloca (2); - | ^~~~~~~~~~~~~~~~~~~~ - | | - | (1) allocated 2 bytes here - | (2) assigned to 'int32_t *' - | + int32_t *ptr = (int32_t *) __builtin_alloca (2); + ^~~~~~~~~~~~~~~~~~~~ + | + (1) allocated 2 bytes here + (2) assigned to 'int32_t *' { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } int32_t *ptr = (int32_t *) __builtin_alloca (2); ~~~~~~~~~~~~~~~~~^~~ 'void test_constant_2()': events 1-2 - | - | int32_t *ptr = (int32_t *) __builtin_alloca (2); - | ~~~~~~~~~~~~~~~~~^~~ - | | - | (1) allocated 2 bytes here - | (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' - | + int32_t *ptr = (int32_t *) __builtin_alloca (2); + ~~~~~~~~~~~~~~~~~^~~ + | + (1) allocated 2 bytes here + (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' { dg-end-multiline-output "" { target c++ } } */ void test_symbolic (int n) @@ -72,25 +64,21 @@ void test_symbolic (int n) int32_t *ptr = (int32_t *) __builtin_alloca (n * 2); ^~~~~~~~~~~~~~~~~~~~~~~~ 'test_symbolic': events 1-2 - | - | int32_t *ptr = (int32_t *) __builtin_alloca (n * 2); - | ^~~~~~~~~~~~~~~~~~~~~~~~ - | | - | (1) allocated 'n * 2' bytes here - | (2) assigned to 'int32_t *' - | + int32_t *ptr = (int32_t *) __builtin_alloca (n * 2); + ^~~~~~~~~~~~~~~~~~~~~~~~ + | + (1) allocated 'n * 2' bytes here + (2) assigned to 'int32_t *' { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } int32_t *ptr = (int32_t *) __builtin_alloca (n * 2); ~~~~~~~~~~~~~~~~~^~~~~~~ 'void test_symbolic(int)': events 1-2 - | - | int32_t *ptr = (int32_t *) __builtin_alloca (n * 2); - | ~~~~~~~~~~~~~~~~~^~~~~~~ - | | - | (1) allocated '(n * 2)' bytes here - | (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' - | + int32_t *ptr = (int32_t *) __builtin_alloca (n * 2); + ~~~~~~~~~~~~~~~~~^~~~~~~ + | + (1) allocated '(n * 2)' bytes here + (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' { dg-end-multiline-output "" { target c++ } } */ /* FIXME: am getting a duplicate warning here for some reason diff --git a/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-3.c b/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-3.c index 3cf7fb004240..eeb52192fd44 100644 --- a/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-3.c +++ b/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-3.c @@ -16,25 +16,21 @@ void test_constant_99 (void) int32_t *ptr = (int32_t *) alloca (99); ^~~~~~ 'test_constant_99': events 1-2 - | - | int32_t *ptr = (int32_t *) alloca (99); - | ^~~~~~ - | | - | (1) allocated 99 bytes here - | (2) assigned to 'int32_t *' {aka '{re:long :re?}int *'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' - | + int32_t *ptr = (int32_t *) alloca (99); + ^~~~~~ + | + (1) allocated 99 bytes here + (2) assigned to 'int32_t *' {aka '{re:long :re?}int *'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } int32_t *ptr = (int32_t *) alloca (99); ^~~~~~ 'void test_constant_99()': events 1-2 - | - | int32_t *ptr = (int32_t *) alloca (99); - | ^~~~~~ - | | - | (1) allocated 99 bytes here - | (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' - | + int32_t *ptr = (int32_t *) alloca (99); + ^~~~~~ + | + (1) allocated 99 bytes here + (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' { dg-end-multiline-output "" { target c++ } } */ void test_symbolic (int n) @@ -46,23 +42,19 @@ void test_symbolic (int n) int32_t *ptr = (int32_t *) alloca (n * 2); ^~~~~~ 'test_symbolic': events 1-2 - | - | int32_t *ptr = (int32_t *) alloca (n * 2); - | ^~~~~~ - | | - | (1) allocated 'n * 2' bytes here - | (2) assigned to 'int32_t *' {aka '{re:long :re?}int *'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' - | + int32_t *ptr = (int32_t *) alloca (n * 2); + ^~~~~~ + | + (1) allocated 'n * 2' bytes here + (2) assigned to 'int32_t *' {aka '{re:long :re?}int *'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } int32_t *ptr = (int32_t *) alloca (n * 2); ^~~~~~ 'void test_symbolic(int)': events 1-2 - | - | int32_t *ptr = (int32_t *) alloca (n * 2); - | ^~~~~~ - | | - | (1) allocated '(n * 2)' bytes here - | (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' - | + int32_t *ptr = (int32_t *) alloca (n * 2); + ^~~~~~ + | + (1) allocated '(n * 2)' bytes here + (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-0.c b/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-0.c index 24fe84deb14f..acc41567f48d 100644 --- a/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-0.c +++ b/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-0.c @@ -227,31 +227,27 @@ void test_3 (void *ptr) NN | free (ptr); | ^~~~~~~~~~ 'test_3': events 1-2 - | - | NN | free (ptr); - | | ^~~~~~~~~~ - | | | - | | (1) first 'free' here - | NN | called_by_test_3 (); - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (2) second 'free' here; first 'free' was at (1) - | + NN | free (ptr); + | ^~~~~~~~~~ + | | + | (1) first 'free' here + NN | called_by_test_3 (); + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (2) second 'free' here; first 'free' was at (1) { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } NN | free (ptr); | ~~~~~^~~~~ 'void test_3(void*)': events 1-2 - | - | NN | free (ptr); - | | ~~~~~^~~~~ - | | | - | | (1) first 'free' here - | NN | called_by_test_3 (); - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (2) second 'free' here; first 'free' was at (1) - | + NN | free (ptr); + | ~~~~~^~~~~ + | | + | (1) first 'free' here + NN | called_by_test_3 (); + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (2) second 'free' here; first 'free' was at (1) { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-1.c b/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-1.c index e13437052584..27b885dc9554 100644 --- a/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-1.c @@ -285,31 +285,27 @@ void test_3 (void *ptr) NN | free (ptr); | ^~~~~~~~~~ 'test_3': events 1-2 - | - | NN | free (ptr); - | | ^~~~~~~~~~ - | | | - | | (1) first 'free' here - | NN | called_by_test_3 (); - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (2) second 'free' here; first 'free' was at (1) - | + NN | free (ptr); + | ^~~~~~~~~~ + | | + | (1) first 'free' here + NN | called_by_test_3 (); + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (2) second 'free' here; first 'free' was at (1) { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } NN | free (ptr); | ~~~~~^~~~~ 'void test_3(void*)': events 1-2 - | - | NN | free (ptr); - | | ~~~~~^~~~~ - | | | - | | (1) first 'free' here - | NN | called_by_test_3 (); - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (2) second 'free' here; first 'free' was at (1) - | + NN | free (ptr); + | ~~~~~^~~~~ + | | + | (1) first 'free' here + NN | called_by_test_3 (); + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (2) second 'free' here; first 'free' was at (1) { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-2.c b/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-2.c index 0fd865485df9..d2dc522cc1aa 100644 --- a/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-2.c +++ b/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-2.c @@ -345,31 +345,27 @@ void test_3 (void *ptr) NN | free (ptr); | ^~~~~~~~~~ 'test_3': events 1-2 - | - | NN | free (ptr); - | | ^~~~~~~~~~ - | | | - | | (1) first 'free' here - | NN | called_by_test_3 (); - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (2) second 'free' here; first 'free' was at (1) - | + NN | free (ptr); + | ^~~~~~~~~~ + | | + | (1) first 'free' here + NN | called_by_test_3 (); + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (2) second 'free' here; first 'free' was at (1) { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } NN | free (ptr); | ~~~~~^~~~~ 'void test_3(void*)': events 1-2 - | - | NN | free (ptr); - | | ~~~~~^~~~~ - | | | - | | (1) first 'free' here - | NN | called_by_test_3 (); - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (2) second 'free' here; first 'free' was at (1) - | + NN | free (ptr); + | ~~~~~^~~~~ + | | + | (1) first 'free' here + NN | called_by_test_3 (); + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (2) second 'free' here; first 'free' was at (1) { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-3.c b/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-3.c index ac699ec544e1..3661f1fd485b 100644 --- a/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-3.c +++ b/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-3.c @@ -345,31 +345,27 @@ void test_3 (void *ptr) NN | free (ptr); | ^~~~~~~~~~ 'test_3': events 1-2 - | - | NN | free (ptr); - | | ^~~~~~~~~~ - | | | - | | (1) first 'free' here - | NN | called_by_test_3 (); - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (2) second 'free' here; first 'free' was at (1) - | + NN | free (ptr); + | ^~~~~~~~~~ + | | + | (1) first 'free' here + NN | called_by_test_3 (); + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (2) second 'free' here; first 'free' was at (1) { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } NN | free (ptr); | ~~~~~^~~~~ 'void test_3(void*)': events 1-2 - | - | NN | free (ptr); - | | ~~~~~^~~~~ - | | | - | | (1) first 'free' here - | NN | called_by_test_3 (); - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (2) second 'free' here; first 'free' was at (1) - | + NN | free (ptr); + | ~~~~~^~~~~ + | | + | (1) first 'free' here + NN | called_by_test_3 (); + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (2) second 'free' here; first 'free' was at (1) { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/c-c++-common/analyzer/malloc-macro-inline-events.c b/gcc/testsuite/c-c++-common/analyzer/malloc-macro-inline-events.c index d00d076b209a..8620bc919a5b 100644 --- a/gcc/testsuite/c-c++-common/analyzer/malloc-macro-inline-events.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-macro-inline-events.c @@ -17,51 +17,58 @@ void test (void *ptr) | ^~~~~~~~~ NN | WRAPPED_FREE (ptr); | ^~~~~~~~~~~~ - 'test': event 1 - | - | - | NN | #define WRAPPED_FREE(PTR) free(PTR) - | | ^~~~~~~~~ - | | | - | | (1) first 'free' here - | NN | WRAPPED_FREE (ptr); - | | ^~~~~~~~~~~~ - | - 'test': event 2 - | - | - | NN | #define WRAPPED_FREE(PTR) free(PTR) - | | ^~~~~~~~~ - | | | - | | (2) second 'free' here; first 'free' was at (1) - | NN | WRAPPED_FREE (ptr); - | | ^~~~~~~~~~~~ - | { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } NN | #define WRAPPED_FREE(PTR) free(PTR) | ~~~~^~~~~ NN | WRAPPED_FREE (ptr); | ^~~~~~~~~~~~ + { dg-end-multiline-output "" { target c++ } } */ + /* { dg-begin-multiline-output "" } + 'test': event 1 + { dg-end-multiline-output "" { target c } } */ + /* { dg-begin-multiline-output "" } 'void test(void*)': event 1 - | - | - | NN | #define WRAPPED_FREE(PTR) free(PTR) - | | ~~~~^~~~~ - | | | - | | (1) first 'free' here - | NN | WRAPPED_FREE (ptr); - | | ^~~~~~~~~~~~ - | + { dg-end-multiline-output "" { target c++ } } */ + /* { dg-prune-output "\[^\n\r\]*malloc-macro.h\[^\n\r\]*" } */ + /* { dg-begin-multiline-output "" } + NN | #define WRAPPED_FREE(PTR) free(PTR) + | ^~~~~~~~~ + | | + | (1) first 'free' here + NN | WRAPPED_FREE (ptr); + | ^~~~~~~~~~~~ + { dg-end-multiline-output "" { target c } } */ + /* { dg-begin-multiline-output "" } + NN | #define WRAPPED_FREE(PTR) free(PTR) + | ~~~~^~~~~ + | | + | (1) first 'free' here + NN | WRAPPED_FREE (ptr); + | ^~~~~~~~~~~~ + { dg-end-multiline-output "" { target c++ } } */ + /* { dg-prune-output "\[^\n\r\]*malloc-macro.h\[^\n\r\]*" } */ + /* { dg-begin-multiline-output "" } + 'test': event 2 + { dg-end-multiline-output "" { target c } } */ + /* { dg-begin-multiline-output "" } 'void test(void*)': event 2 - | - | - | NN | #define WRAPPED_FREE(PTR) free(PTR) - | | ~~~~^~~~~ - | | | - | | (2) second 'free' here; first 'free' was at (1) - | NN | WRAPPED_FREE (ptr); - | | ^~~~~~~~~~~~ - | + { dg-end-multiline-output "" { target c++ } } */ + /* { dg-prune-output "\[^\n\r\]*malloc-macro.h\[^\n\r\]*" } */ + /* { dg-begin-multiline-output "" } + NN | #define WRAPPED_FREE(PTR) free(PTR) + | ^~~~~~~~~ + | | + | (2) second 'free' here; first 'free' was at (1) + NN | WRAPPED_FREE (ptr); + | ^~~~~~~~~~~~ + { dg-end-multiline-output "" { target c } } */ + /* { dg-begin-multiline-output "" } + NN | #define WRAPPED_FREE(PTR) free(PTR) + | ~~~~^~~~~ + | | + | (2) second 'free' here; first 'free' was at (1) + NN | WRAPPED_FREE (ptr); + | ^~~~~~~~~~~~ { dg-end-multiline-output "" { target c++ } } */ } diff --git a/gcc/testsuite/c-c++-common/analyzer/malloc-paths-9-noexcept.c b/gcc/testsuite/c-c++-common/analyzer/malloc-paths-9-noexcept.c index f914ed6216fa..57d25f436a08 100644 --- a/gcc/testsuite/c-c++-common/analyzer/malloc-paths-9-noexcept.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-paths-9-noexcept.c @@ -13,39 +13,35 @@ void test_1 (void) NN | free (ptr); | ^~~~~~~~~~ 'test_1': events 1-3 - | - | NN | void *ptr = malloc (1024); - | | ^~~~~~~~~~~~~ - | | | - | | (1) allocated here - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (2) first 'free' here - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (3) second 'free' here; first 'free' was at (2) - | + NN | void *ptr = malloc (1024); + | ^~~~~~~~~~~~~ + | | + | (1) allocated here + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (2) first 'free' here + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (3) second 'free' here; first 'free' was at (2) { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } NN | free (ptr); | ~~~~~^~~~~ 'void test_1()': events 1-3 - | - | NN | void *ptr = malloc (1024); - | | ~~~~~~~^~~~~~ - | | | - | | (1) allocated here - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (2) first 'free' here - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (3) second 'free' here; first 'free' was at (2) - | + NN | void *ptr = malloc (1024); + | ~~~~~~~^~~~~~ + | | + | (1) allocated here + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (2) first 'free' here + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (3) second 'free' here; first 'free' was at (2) { dg-end-multiline-output "" { target c++ } } */ void test_2 (int x, int y) @@ -62,59 +58,55 @@ void test_2 (int x, int y) NN | free (ptr); | ^~~~~~~~~~ 'test_2': events 1-7 - | - | NN | void *ptr = malloc (1024); - | | ^~~~~~~~~~~~~ - | | | - | | (1) allocated here - | NN | if (x) - | | ~ - | | | - | | (2) following 'true' branch (when 'x != 0')... - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (3) ...to here - | | (4) first 'free' here - | NN | if (y) - | | ~ - | | | - | | (5) following 'true' branch (when 'y != 0')... - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (6) ...to here - | | (7) second 'free' here; first 'free' was at (4) - | + NN | void *ptr = malloc (1024); + | ^~~~~~~~~~~~~ + | | + | (1) allocated here + NN | if (x) + | ~ + | | + | (2) following 'true' branch (when 'x != 0')... + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (3) ...to here + | (4) first 'free' here + NN | if (y) + | ~ + | | + | (5) following 'true' branch (when 'y != 0')... + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (6) ...to here + | (7) second 'free' here; first 'free' was at (4) { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } NN | free (ptr); | ~~~~~^~~~~ 'void test_2(int, int)': events 1-7 - | - | NN | void *ptr = malloc (1024); - | | ~~~~~~~^~~~~~ - | | | - | | (1) allocated here - | NN | if (x) - | | ~~ - | | | - | | (2) following 'true' branch (when 'x != 0')... - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (3) ...to here - | | (4) first 'free' here - | NN | if (y) - | | ~~ - | | | - | | (5) following 'true' branch (when 'y != 0')... - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (6) ...to here - | | (7) second 'free' here; first 'free' was at (4) - | + NN | void *ptr = malloc (1024); + | ~~~~~~~^~~~~~ + | | + | (1) allocated here + NN | if (x) + | ~~ + | | + | (2) following 'true' branch (when 'x != 0')... + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (3) ...to here + | (4) first 'free' here + NN | if (y) + | ~~ + | | + | (5) following 'true' branch (when 'y != 0')... + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (6) ...to here + | (7) second 'free' here; first 'free' was at (4) { dg-end-multiline-output "" { target c++ } } */ /* "leak of 'ptr'. */ @@ -122,55 +114,51 @@ void test_2 (int x, int y) NN | } | ^ 'test_2': events 1-6 - | - | NN | void *ptr = malloc (1024); - | | ^~~~~~~~~~~~~ - | | | - | | (1) allocated here - | NN | if (x) - | | ~ - | | | - | | (2) following 'false' branch (when 'x == 0')... - | NN | free (ptr); - | NN | if (y) - | | ~ - | | | - | | (3) ...to here - | | (4) following 'false' branch (when 'y == 0')... - | NN | free (ptr); - | NN | } - | | ~ - | | | - | | (5) ...to here - | | (6) 'ptr' leaks here; was allocated at (1) - | + NN | void *ptr = malloc (1024); + | ^~~~~~~~~~~~~ + | | + | (1) allocated here + NN | if (x) + | ~ + | | + | (2) following 'false' branch (when 'x == 0')... + NN | free (ptr); + NN | if (y) + | ~ + | | + | (3) ...to here + | (4) following 'false' branch (when 'y == 0')... + NN | free (ptr); + NN | } + | ~ + | | + | (5) ...to here + | (6) 'ptr' leaks here; was allocated at (1) { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } NN | } | ^ 'void test_2(int, int)': events 1-6 - | - | NN | void *ptr = malloc (1024); - | | ~~~~~~~^~~~~~ - | | | - | | (1) allocated here - | NN | if (x) - | | ~~ - | | | - | | (2) following 'false' branch (when 'x == 0')... - | NN | free (ptr); - | NN | if (y) - | | ~~ - | | | - | | (3) ...to here - | | (4) following 'false' branch (when 'y == 0')... - | NN | free (ptr); - | NN | } - | | ~ - | | | - | | (5) ...to here - | | (6) 'ptr' leaks here; was allocated at (1) - | + NN | void *ptr = malloc (1024); + | ~~~~~~~^~~~~~ + | | + | (1) allocated here + NN | if (x) + | ~~ + | | + | (2) following 'false' branch (when 'x == 0')... + NN | free (ptr); + NN | if (y) + | ~~ + | | + | (3) ...to here + | (4) following 'false' branch (when 'y == 0')... + NN | free (ptr); + NN | } + | ~ + | | + | (5) ...to here + | (6) 'ptr' leaks here; was allocated at (1) { dg-end-multiline-output "" { target c++ } } */ int test_3 (int x, int y) @@ -195,31 +183,27 @@ int test_3 (int x, int y) NN | *ptr = 42; | ~~~~~^~~~ 'test_3': events 1-2 - | - | NN | int *ptr = (int *)malloc (sizeof (int)); - | | ^~~~~~~~~~~~~~~~~~~~~ - | | | - | | (1) this call could return NULL - | NN | *ptr = 42; - | | ~~~~~~~~~ - | | | - | | (2) 'ptr' could be NULL: unchecked value from (1) - | + NN | int *ptr = (int *)malloc (sizeof (int)); + | ^~~~~~~~~~~~~~~~~~~~~ + | | + | (1) this call could return NULL + NN | *ptr = 42; + | ~~~~~~~~~ + | | + | (2) 'ptr' could be NULL: unchecked value from (1) { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } NN | *ptr = 42; | ~~~~~^~~~ 'int test_3(int, int)': events 1-2 - | - | NN | int *ptr = (int *)malloc (sizeof (int)); - | | ~~~~~~~^~~~~~~~~~~~~~ - | | | - | | (1) this call could return NULL - | NN | *ptr = 42; - | | ~~~~~~~~~ - | | | - | | (2) 'ptr' could be NULL: unchecked value from (1) - | + NN | int *ptr = (int *)malloc (sizeof (int)); + | ~~~~~~~^~~~~~~~~~~~~~ + | | + | (1) this call could return NULL + NN | *ptr = 42; + | ~~~~~~~~~ + | | + | (2) 'ptr' could be NULL: unchecked value from (1) { dg-end-multiline-output "" { target c++ } } */ /* "use after 'free' of 'ptr'". */ @@ -227,59 +211,55 @@ int test_3 (int x, int y) NN | *ptr = 19; | ~~~~~^~~~ 'test_3': events 1-6 - | - | NN | int *ptr = (int *)malloc (sizeof (int)); - | | ^~~~~~~~~~~~~~~~~~~~~ - | | | - | | (1) allocated here - | NN | *ptr = 42; - | | ~~~~~~~~~ - | | | - | | (2) assuming 'ptr' is non-NULL - | NN | if (x) - | | ~ - | | | - | | (3) following 'true' branch (when 'x != 0')... - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (4) ...to here - | | (5) freed here - | NN | - | NN | *ptr = 19; - | | ~~~~~~~~~ - | | | - | | (6) use after 'free' of 'ptr'; freed at (5) - | + NN | int *ptr = (int *)malloc (sizeof (int)); + | ^~~~~~~~~~~~~~~~~~~~~ + | | + | (1) allocated here + NN | *ptr = 42; + | ~~~~~~~~~ + | | + | (2) assuming 'ptr' is non-NULL + NN | if (x) + | ~ + | | + | (3) following 'true' branch (when 'x != 0')... + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (4) ...to here + | (5) freed here + NN | + NN | *ptr = 19; + | ~~~~~~~~~ + | | + | (6) use after 'free' of 'ptr'; freed at (5) { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } NN | *ptr = 19; | ~~~~~^~~~ 'int test_3(int, int)': events 1-6 - | - | NN | int *ptr = (int *)malloc (sizeof (int)); - | | ~~~~~~~^~~~~~~~~~~~~~ - | | | - | | (1) allocated here - | NN | *ptr = 42; - | | ~~~~~~~~~ - | | | - | | (2) assuming 'ptr' is non-NULL - | NN | if (x) - | | ~~ - | | | - | | (3) following 'true' branch (when 'x != 0')... - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (4) ...to here - | | (5) freed here - | NN | - | NN | *ptr = 19; - | | ~~~~~~~~~ - | | | - | | (6) use after 'free' of 'ptr'; freed at (5) - | + NN | int *ptr = (int *)malloc (sizeof (int)); + | ~~~~~~~^~~~~~~~~~~~~~ + | | + | (1) allocated here + NN | *ptr = 42; + | ~~~~~~~~~ + | | + | (2) assuming 'ptr' is non-NULL + NN | if (x) + | ~~ + | | + | (3) following 'true' branch (when 'x != 0')... + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (4) ...to here + | (5) freed here + NN | + NN | *ptr = 19; + | ~~~~~~~~~ + | | + | (6) use after 'free' of 'ptr'; freed at (5) { dg-end-multiline-output "" { target c++ } } */ /* "use after 'free' of 'ptr'". */ @@ -287,79 +267,75 @@ int test_3 (int x, int y) NN | return *ptr; | ^~~~ 'test_3': events 1-8 - | - | NN | int *ptr = (int *)malloc (sizeof (int)); - | | ^~~~~~~~~~~~~~~~~~~~~ - | | | - | | (1) allocated here - | NN | *ptr = 42; - | | ~~~~~~~~~ - | | | - | | (2) assuming 'ptr' is non-NULL - | NN | if (x) - | | ~ - | | | - | | (3) following 'false' branch (when 'x == 0')... - |...... - | NN | *ptr = 19; - | | ~~~~~~~~~ - | | | - | | (4) ...to here - |...... - | NN | if (y) - | | ~ - | | | - | | (5) following 'true' branch (when 'y != 0')... - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (6) ...to here - | | (7) freed here - | NN | - | NN | return *ptr; - | | ~~~~ - | | | - | | (8) use after 'free' of 'ptr'; freed at (7) - | + NN | int *ptr = (int *)malloc (sizeof (int)); + | ^~~~~~~~~~~~~~~~~~~~~ + | | + | (1) allocated here + NN | *ptr = 42; + | ~~~~~~~~~ + | | + | (2) assuming 'ptr' is non-NULL + NN | if (x) + | ~ + | | + | (3) following 'false' branch (when 'x == 0')... +...... + NN | *ptr = 19; + | ~~~~~~~~~ + | | + | (4) ...to here +...... + NN | if (y) + | ~ + | | + | (5) following 'true' branch (when 'y != 0')... + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (6) ...to here + | (7) freed here + NN | + NN | return *ptr; + | ~~~~ + | | + | (8) use after 'free' of 'ptr'; freed at (7) { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } NN | return *ptr; | ^~~ 'int test_3(int, int)': events 1-8 - | - | NN | int *ptr = (int *)malloc (sizeof (int)); - | | ~~~~~~~^~~~~~~~~~~~~~ - | | | - | | (1) allocated here - | NN | *ptr = 42; - | | ~~~~~~~~~ - | | | - | | (2) assuming 'ptr' is non-NULL - | NN | if (x) - | | ~~ - | | | - | | (3) following 'false' branch (when 'x == 0')... - |...... - | NN | *ptr = 19; - | | ~~~~~~~~~ - | | | - | | (4) ...to here - |...... - | NN | if (y) - | | ~~ - | | | - | | (5) following 'true' branch (when 'y != 0')... - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (6) ...to here - | | (7) freed here - | NN | - | NN | return *ptr; - | | ~~~ - | | | - | | (8) use after 'free' of 'ptr'; freed at (7) - | + NN | int *ptr = (int *)malloc (sizeof (int)); + | ~~~~~~~^~~~~~~~~~~~~~ + | | + | (1) allocated here + NN | *ptr = 42; + | ~~~~~~~~~ + | | + | (2) assuming 'ptr' is non-NULL + NN | if (x) + | ~~ + | | + | (3) following 'false' branch (when 'x == 0')... +...... + NN | *ptr = 19; + | ~~~~~~~~~ + | | + | (4) ...to here +...... + NN | if (y) + | ~~ + | | + | (5) following 'true' branch (when 'y != 0')... + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (6) ...to here + | (7) freed here + NN | + NN | return *ptr; + | ~~~ + | | + | (8) use after 'free' of 'ptr'; freed at (7) { dg-end-multiline-output "" { target c++ } } */ /* "leak of 'ptr'". */ @@ -367,69 +343,65 @@ int test_3 (int x, int y) NN | return *ptr; | ^~~~ 'test_3': events 1-7 - | - | NN | int *ptr = (int *)malloc (sizeof (int)); - | | ^~~~~~~~~~~~~~~~~~~~~ - | | | - | | (1) allocated here - | NN | *ptr = 42; - | | ~~~~~~~~~ - | | | - | | (2) assuming 'ptr' is non-NULL - | NN | if (x) - | | ~ - | | | - | | (3) following 'false' branch (when 'x == 0')... - |...... - | NN | *ptr = 19; - | | ~~~~~~~~~ - | | | - | | (4) ...to here - |...... - | NN | if (y) - | | ~ - | | | - | | (5) following 'false' branch (when 'y == 0')... - |...... - | NN | return *ptr; - | | ~~~~ - | | | - | | (6) ...to here - | | (7) 'ptr' leaks here; was allocated at (1) - | + NN | int *ptr = (int *)malloc (sizeof (int)); + | ^~~~~~~~~~~~~~~~~~~~~ + | | + | (1) allocated here + NN | *ptr = 42; + | ~~~~~~~~~ + | | + | (2) assuming 'ptr' is non-NULL + NN | if (x) + | ~ + | | + | (3) following 'false' branch (when 'x == 0')... +...... + NN | *ptr = 19; + | ~~~~~~~~~ + | | + | (4) ...to here +...... + NN | if (y) + | ~ + | | + | (5) following 'false' branch (when 'y == 0')... +...... + NN | return *ptr; + | ~~~~ + | | + | (6) ...to here + | (7) 'ptr' leaks here; was allocated at (1) { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } NN | return *ptr; | ^~~ 'int test_3(int, int)': events 1-7 - | - | NN | int *ptr = (int *)malloc (sizeof (int)); - | | ~~~~~~~^~~~~~~~~~~~~~ - | | | - | | (1) allocated here - | NN | *ptr = 42; - | | ~~~~~~~~~ - | | | - | | (2) assuming 'ptr' is non-NULL - | NN | if (x) - | | ~~ - | | | - | | (3) following 'false' branch (when 'x == 0')... - |...... - | NN | *ptr = 19; - | | ~~~~~~~~~ - | | | - | | (4) ...to here - |...... - | NN | if (y) - | | ~~ - | | | - | | (5) following 'false' branch (when 'y == 0')... - |...... - | NN | return *ptr; - | | ~~~ - | | | - | | (6) ...to here - | | (7) 'ptr' leaks here; was allocated at (1) - | + NN | int *ptr = (int *)malloc (sizeof (int)); + | ~~~~~~~^~~~~~~~~~~~~~ + | | + | (1) allocated here + NN | *ptr = 42; + | ~~~~~~~~~ + | | + | (2) assuming 'ptr' is non-NULL + NN | if (x) + | ~~ + | | + | (3) following 'false' branch (when 'x == 0')... +...... + NN | *ptr = 19; + | ~~~~~~~~~ + | | + | (4) ...to here +...... + NN | if (y) + | ~~ + | | + | (5) following 'false' branch (when 'y == 0')... +...... + NN | return *ptr; + | ~~~ + | | + | (6) ...to here + | (7) 'ptr' leaks here; was allocated at (1) { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/c-c++-common/analyzer/setjmp-2.c b/gcc/testsuite/c-c++-common/analyzer/setjmp-2.c index 731a17293fc7..264764551d2a 100644 --- a/gcc/testsuite/c-c++-common/analyzer/setjmp-2.c +++ b/gcc/testsuite/c-c++-common/analyzer/setjmp-2.c @@ -39,95 +39,79 @@ void test_2 (void) NN | __analyzer_dump_path (); | ^~~~~~~~~~~~~~~~~~~~~~~ 'test_2': event 1 - | - | NN | i = SETJMP(env); - | | ^~~~~~ - | | | - | | (1) 'setjmp' called here - | + NN | i = SETJMP(env); + | ^~~~~~ + | | + | (1) 'setjmp' called here 'test_2': events 2-4 - | - | NN | if (i != 0) - | | ^ - | | | - | | (2) following 'false' branch (when 'i == 0')... - |...... - | NN | longjmp (env, 1); - | | ~~~~~~~~~~~~~~~~ - | | | - | | (3) ...to here - | | (4) rewinding within 'test_2' from 'longjmp'... - | + NN | if (i != 0) + | ^ + | | + | (2) following 'false' branch (when 'i == 0')... +...... + NN | longjmp (env, 1); + | ~~~~~~~~~~~~~~~~ + | | + | (3) ...to here + | (4) rewinding within 'test_2' from 'longjmp'... 'test_2': event 5 - | - | NN | i = SETJMP(env); - | | ^~~~~~ - | | | - | | (5) ...to 'setjmp' (saved at (1)) - | + NN | i = SETJMP(env); + | ^~~~~~ + | | + | (5) ...to 'setjmp' (saved at (1)) 'test_2': events 6-8 - | - | NN | if (i != 0) - | | ^ - | | | - | | (6) following 'true' branch (when 'i != 0')... - | NN | { - | NN | foo (2); - | | ~~~~~~~ - | | | - | | (7) ...to here - | NN | __analyzer_dump_path (); - | | ~~~~~~~~~~~~~~~~~~~~~~~ - | | | - | | (8) here - | + NN | if (i != 0) + | ^ + | | + | (6) following 'true' branch (when 'i != 0')... + NN | { + NN | foo (2); + | ~~~~~~~ + | | + | (7) ...to here + NN | __analyzer_dump_path (); + | ~~~~~~~~~~~~~~~~~~~~~~~ + | | + | (8) here { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } NN | __analyzer_dump_path (); | ~~~~~~~~~~~~~~~~~~~~~^~ 'void test_2()': event 1 - | - | NN | i = SETJMP(env); - | | ^~~~~~ - | | | - | | (1) 'setjmp' called here - | + NN | i = SETJMP(env); + | ^~~~~~ + | | + | (1) 'setjmp' called here 'void test_2()': events 2-4 - | - | NN | if (i != 0) - | | ^~ - | | | - | | (2) following 'false' branch (when 'i == 0')... - |...... - | NN | longjmp (env, 1); - | | ~~~~~~~~~~~~~~~~ - | | | - | | (3) ...to here - | | (4) rewinding within 'test_2' from 'longjmp'... - | + NN | if (i != 0) + | ^~ + | | + | (2) following 'false' branch (when 'i == 0')... +...... + NN | longjmp (env, 1); + | ~~~~~~~~~~~~~~~~ + | | + | (3) ...to here + | (4) rewinding within 'test_2' from 'longjmp'... 'void test_2()': event 5 - | - | NN | i = SETJMP(env); - | | ^~~~~~ - | | | - | | (5) ...to 'setjmp' (saved at (1)) - | + NN | i = SETJMP(env); + | ^~~~~~ + | | + | (5) ...to 'setjmp' (saved at (1)) 'void test_2()': events 6-8 - | - | NN | if (i != 0) - | | ^~ - | | | - | | (6) following 'true' branch (when 'i != 0')... - | NN | { - | NN | foo (2); - | | ~~~~~~~ - | | | - | | (7) ...to here - | NN | __analyzer_dump_path (); - | | ~~~~~~~~~~~~~~~~~~~~~~~ - | | | - | | (8) here - | + NN | if (i != 0) + | ^~ + | | + | (6) following 'true' branch (when 'i != 0')... + NN | { + NN | foo (2); + | ~~~~~~~ + | | + | (7) ...to here + NN | __analyzer_dump_path (); + | ~~~~~~~~~~~~~~~~~~~~~~~ + | | + | (8) here { dg-end-multiline-output "" { target c++ } } */ void test_3 (void) diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-paths-9.c b/gcc/testsuite/gcc.dg/analyzer/malloc-paths-9.c index 83eec292e85d..a832b084738e 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-paths-9.c +++ b/gcc/testsuite/gcc.dg/analyzer/malloc-paths-9.c @@ -15,20 +15,18 @@ void test_1 (void) NN | free (ptr); | ^~~~~~~~~~ 'test_1': events 1-3 - | - | NN | void *ptr = malloc (1024); - | | ^~~~~~~~~~~~~ - | | | - | | (1) allocated here - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (2) first 'free' here - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (3) second 'free' here; first 'free' was at (2) - | + NN | void *ptr = malloc (1024); + | ^~~~~~~~~~~~~ + | | + | (1) allocated here + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (2) first 'free' here + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (3) second 'free' here; first 'free' was at (2) { dg-end-multiline-output "" } */ void test_2 (int x, int y) @@ -45,30 +43,28 @@ void test_2 (int x, int y) NN | free (ptr); | ^~~~~~~~~~ 'test_2': events 1-7 - | - | NN | void *ptr = malloc (1024); - | | ^~~~~~~~~~~~~ - | | | - | | (1) allocated here - | NN | if (x) - | | ~ - | | | - | | (2) following 'true' branch (when 'x != 0')... - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (3) ...to here - | | (4) first 'free' here - | NN | if (y) - | | ~ - | | | - | | (5) following 'true' branch (when 'y != 0')... - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (6) ...to here - | | (7) second 'free' here; first 'free' was at (4) - | + NN | void *ptr = malloc (1024); + | ^~~~~~~~~~~~~ + | | + | (1) allocated here + NN | if (x) + | ~ + | | + | (2) following 'true' branch (when 'x != 0')... + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (3) ...to here + | (4) first 'free' here + NN | if (y) + | ~ + | | + | (5) following 'true' branch (when 'y != 0')... + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (6) ...to here + | (7) second 'free' here; first 'free' was at (4) { dg-end-multiline-output "" } */ /* "leak of 'ptr'. */ @@ -76,28 +72,26 @@ void test_2 (int x, int y) NN | } | ^ 'test_2': events 1-6 - | - | NN | void *ptr = malloc (1024); - | | ^~~~~~~~~~~~~ - | | | - | | (1) allocated here - | NN | if (x) - | | ~ - | | | - | | (2) following 'false' branch (when 'x == 0')... - | NN | free (ptr); - | NN | if (y) - | | ~ - | | | - | | (3) ...to here - | | (4) following 'false' branch (when 'y == 0')... - | NN | free (ptr); - | NN | } - | | ~ - | | | - | | (5) ...to here - | | (6) 'ptr' leaks here; was allocated at (1) - | + NN | void *ptr = malloc (1024); + | ^~~~~~~~~~~~~ + | | + | (1) allocated here + NN | if (x) + | ~ + | | + | (2) following 'false' branch (when 'x == 0')... + NN | free (ptr); + NN | if (y) + | ~ + | | + | (3) ...to here + | (4) following 'false' branch (when 'y == 0')... + NN | free (ptr); + NN | } + | ~ + | | + | (5) ...to here + | (6) 'ptr' leaks here; was allocated at (1) { dg-end-multiline-output "" } */ int test_3 (int x, int y) @@ -122,16 +116,14 @@ int test_3 (int x, int y) NN | *ptr = 42; | ~~~~~^~~~ 'test_3': events 1-2 - | - | NN | int *ptr = (int *)malloc (sizeof (int)); - | | ^~~~~~~~~~~~~~~~~~~~~ - | | | - | | (1) this call could return NULL - | NN | *ptr = 42; - | | ~~~~~~~~~ - | | | - | | (2) 'ptr' could be NULL: unchecked value from (1) - | + NN | int *ptr = (int *)malloc (sizeof (int)); + | ^~~~~~~~~~~~~~~~~~~~~ + | | + | (1) this call could return NULL + NN | *ptr = 42; + | ~~~~~~~~~ + | | + | (2) 'ptr' could be NULL: unchecked value from (1) { dg-end-multiline-output "" } */ /* "use after 'free' of 'ptr'". */ @@ -139,30 +131,28 @@ int test_3 (int x, int y) NN | *ptr = 19; | ~~~~~^~~~ 'test_3': events 1-6 - | - | NN | int *ptr = (int *)malloc (sizeof (int)); - | | ^~~~~~~~~~~~~~~~~~~~~ - | | | - | | (1) allocated here - | NN | *ptr = 42; - | | ~~~~~~~~~ - | | | - | | (2) assuming 'ptr' is non-NULL - | NN | if (x) - | | ~ - | | | - | | (3) following 'true' branch (when 'x != 0')... - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (4) ...to here - | | (5) freed here - | NN | - | NN | *ptr = 19; - | | ~~~~~~~~~ - | | | - | | (6) use after 'free' of 'ptr'; freed at (5) - | + NN | int *ptr = (int *)malloc (sizeof (int)); + | ^~~~~~~~~~~~~~~~~~~~~ + | | + | (1) allocated here + NN | *ptr = 42; + | ~~~~~~~~~ + | | + | (2) assuming 'ptr' is non-NULL + NN | if (x) + | ~ + | | + | (3) following 'true' branch (when 'x != 0')... + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (4) ...to here + | (5) freed here + NN | + NN | *ptr = 19; + | ~~~~~~~~~ + | | + | (6) use after 'free' of 'ptr'; freed at (5) { dg-end-multiline-output "" } */ /* "use after 'free' of 'ptr'". */ @@ -170,40 +160,38 @@ int test_3 (int x, int y) NN | return *ptr; | ^~~~ 'test_3': events 1-8 - | - | NN | int *ptr = (int *)malloc (sizeof (int)); - | | ^~~~~~~~~~~~~~~~~~~~~ - | | | - | | (1) allocated here - | NN | *ptr = 42; - | | ~~~~~~~~~ - | | | - | | (2) assuming 'ptr' is non-NULL - | NN | if (x) - | | ~ - | | | - | | (3) following 'false' branch (when 'x == 0')... - |...... - | NN | *ptr = 19; - | | ~~~~~~~~~ - | | | - | | (4) ...to here - |...... - | NN | if (y) - | | ~ - | | | - | | (5) following 'true' branch (when 'y != 0')... - | NN | free (ptr); - | | ~~~~~~~~~~ - | | | - | | (6) ...to here - | | (7) freed here - | NN | - | NN | return *ptr; - | | ~~~~ - | | | - | | (8) use after 'free' of 'ptr'; freed at (7) - | + NN | int *ptr = (int *)malloc (sizeof (int)); + | ^~~~~~~~~~~~~~~~~~~~~ + | | + | (1) allocated here + NN | *ptr = 42; + | ~~~~~~~~~ + | | + | (2) assuming 'ptr' is non-NULL + NN | if (x) + | ~ + | | + | (3) following 'false' branch (when 'x == 0')... +...... + NN | *ptr = 19; + | ~~~~~~~~~ + | | + | (4) ...to here +...... + NN | if (y) + | ~ + | | + | (5) following 'true' branch (when 'y != 0')... + NN | free (ptr); + | ~~~~~~~~~~ + | | + | (6) ...to here + | (7) freed here + NN | + NN | return *ptr; + | ~~~~ + | | + | (8) use after 'free' of 'ptr'; freed at (7) { dg-end-multiline-output "" } */ /* "leak of 'ptr'". */ @@ -211,34 +199,32 @@ int test_3 (int x, int y) NN | return *ptr; | ^~~~ 'test_3': events 1-7 - | - | NN | int *ptr = (int *)malloc (sizeof (int)); - | | ^~~~~~~~~~~~~~~~~~~~~ - | | | - | | (1) allocated here - | NN | *ptr = 42; - | | ~~~~~~~~~ - | | | - | | (2) assuming 'ptr' is non-NULL - | NN | if (x) - | | ~ - | | | - | | (3) following 'false' branch (when 'x == 0')... - |...... - | NN | *ptr = 19; - | | ~~~~~~~~~ - | | | - | | (4) ...to here - |...... - | NN | if (y) - | | ~ - | | | - | | (5) following 'false' branch (when 'y == 0')... - |...... - | NN | return *ptr; - | | ~~~~ - | | | - | | (6) ...to here - | | (7) 'ptr' leaks here; was allocated at (1) - | + NN | int *ptr = (int *)malloc (sizeof (int)); + | ^~~~~~~~~~~~~~~~~~~~~ + | | + | (1) allocated here + NN | *ptr = 42; + | ~~~~~~~~~ + | | + | (2) assuming 'ptr' is non-NULL + NN | if (x) + | ~ + | | + | (3) following 'false' branch (when 'x == 0')... +...... + NN | *ptr = 19; + | ~~~~~~~~~ + | | + | (4) ...to here +...... + NN | if (y) + | ~ + | | + | (5) following 'false' branch (when 'y == 0')... +...... + NN | return *ptr; + | ~~~~ + | | + | (6) ...to here + | (7) 'ptr' leaks here; was allocated at (1) { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-multiline-2.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-multiline-2.c index 660901ab782d..47f3bcb524fc 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-multiline-2.c +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-multiline-2.c @@ -18,15 +18,14 @@ void int_vla_write_element_after_end_off_by_one(int32_t x, size_t n) arr[n] = x; ~~~~~~~^~~ 'int_vla_write_element_after_end_off_by_one': events 1-2 (depth 1) - | - | int32_t arr[n]; - | ^~~ - | | - | (1) capacity: 'n * 4' bytes - | - | arr[n] = x; - | ~~~~~~~~~~ - | | - | (2) write of 4 bytes at offset 'n * 4' exceeds the buffer - | + int32_t arr[n]; + ^~~ + | + (1) capacity: 'n * 4' bytes + { dg-end-multiline-output "" } */ +/* { dg-begin-multiline-output "" } + arr[n] = x; + ~~~~~~~~~~ + | + (2) write of 4 bytes at offset 'n * 4' exceeds the buffer { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.c index b2b269a12b51..b8134aebfda4 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.c @@ -36,21 +36,19 @@ make_a_list_of_random_ints_badly(PyObject *self, 29 | PyList_Append(list, item); | ^~~~~~~~~~~~~~~~~~~~~~~~~ 'make_a_list_of_random_ints_badly': events 1-3 - | - | 25 | list = PyList_New(0); - | | ^~~~~~~~~~~~~ - | | | - | | (1) when 'PyList_New' fails, returning NULL - | 26 | - | 27 | for (i = 0; i < count; i++) { - | | ~~~~~~~~~ - | | | - | | (2) when 'i < count' - | 28 | item = PyLong_FromLong(random()); - | 29 | PyList_Append(list, item); - | | ~~~~~~~~~~~~~~~~~~~~~~~~~ - | | | - | | (3) when calling 'PyList_Append', passing NULL from (1) as argument 1 - | + 25 | list = PyList_New(0); + | ^~~~~~~~~~~~~ + | | + | (1) when 'PyList_New' fails, returning NULL + 26 | + 27 | for (i = 0; i < count; i++) { + | ~~~~~~~~~ + | | + | (2) when 'i < count' + 28 | item = PyLong_FromLong(random()); + 29 | PyList_Append(list, item); + | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | | + | (3) when calling 'PyList_Append', passing NULL from (1) as argument 1 { dg-end-multiline-output "" } */ } diff --git a/gcc/tree-diagnostic-path.cc b/gcc/tree-diagnostic-path.cc index 8247192a2504..33389ef5d33e 100644 --- a/gcc/tree-diagnostic-path.cc +++ b/gcc/tree-diagnostic-path.cc @@ -141,6 +141,8 @@ public: const char *get_name () const { return m_name.get (); } unsigned get_swimlane_index () const { return m_swimlane_idx; } + bool interprocedural_p () const; + private: friend struct path_summary; friend class thread_event_printer; @@ -293,6 +295,26 @@ private: } }; +/* Return true iff there is more than one stack frame used by the events + of this thread. */ + +bool +per_thread_summary::interprocedural_p () const +{ + if (m_event_ranges.is_empty ()) + return false; + tree first_fndecl = m_event_ranges[0]->m_fndecl; + int first_stack_depth = m_event_ranges[0]->m_stack_depth; + for (auto range : m_event_ranges) + { + if (range->m_fndecl != first_fndecl) + return true; + if (range->m_stack_depth != first_stack_depth) + return true; + } + return false; +} + /* path_summary's ctor. */ path_summary::path_summary (const diagnostic_path &path, @@ -391,11 +413,14 @@ public: = colorize_start (pp_show_color (pp), line_color); const char *end_line_color = colorize_stop (pp_show_color (pp)); + const bool interprocedural_p = m_per_thread_summary.interprocedural_p (); + write_indent (pp, m_cur_indent); if (const event_range *prev_range = get_any_prev_range ()) { if (range->m_stack_depth > prev_range->m_stack_depth) { + gcc_assert (interprocedural_p); /* Show pushed stack frame(s). */ const char *push_prefix = "+--> "; pp_string (pp, start_line_color); @@ -420,34 +445,37 @@ public: pp_newline (pp); /* Print a run of events. */ - { - write_indent (pp, m_cur_indent + per_frame_indent); - pp_string (pp, start_line_color); - pp_string (pp, "|"); - pp_string (pp, end_line_color); - pp_newline (pp); - - char *saved_prefix = pp_take_prefix (pp); - char *prefix; + if (interprocedural_p) { - pretty_printer tmp_pp; - write_indent (&tmp_pp, m_cur_indent + per_frame_indent); - pp_string (&tmp_pp, start_line_color); - pp_string (&tmp_pp, "|"); - pp_string (&tmp_pp, end_line_color); - prefix = xstrdup (pp_formatted_text (&tmp_pp)); + write_indent (pp, m_cur_indent + per_frame_indent); + pp_string (pp, start_line_color); + pp_string (pp, "|"); + pp_string (pp, end_line_color); + pp_newline (pp); + + char *saved_prefix = pp_take_prefix (pp); + char *prefix; + { + pretty_printer tmp_pp; + write_indent (&tmp_pp, m_cur_indent + per_frame_indent); + pp_string (&tmp_pp, start_line_color); + pp_string (&tmp_pp, "|"); + pp_string (&tmp_pp, end_line_color); + prefix = xstrdup (pp_formatted_text (&tmp_pp)); + } + pp_set_prefix (pp, prefix); + pp_prefixing_rule (pp) = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE; + range->print (dc, pp); + pp_set_prefix (pp, saved_prefix); + + write_indent (pp, m_cur_indent + per_frame_indent); + pp_string (pp, start_line_color); + pp_string (pp, "|"); + pp_string (pp, end_line_color); + pp_newline (pp); } - pp_set_prefix (pp, prefix); - pp_prefixing_rule (pp) = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE; + else range->print (dc, pp); - pp_set_prefix (pp, saved_prefix); - - write_indent (pp, m_cur_indent + per_frame_indent); - pp_string (pp, start_line_color); - pp_string (pp, "|"); - pp_string (pp, end_line_color); - pp_newline (pp); - } if (const event_range *next_range = get_any_next_range ()) { @@ -460,6 +488,7 @@ public: " |\n" " <------------ +\n" " |\n". */ + gcc_assert (interprocedural_p); int vbar_for_next_frame = *m_vbar_column_for_depth.get (next_range->m_stack_depth); @@ -492,6 +521,7 @@ public: else if (range->m_stack_depth < next_range->m_stack_depth) { /* Prepare to show pushed stack frame. */ + gcc_assert (interprocedural_p); gcc_assert (range->m_stack_depth != EMPTY); gcc_assert (range->m_stack_depth != DELETED); m_vbar_column_for_depth.put (range->m_stack_depth, @@ -766,10 +796,8 @@ test_intraprocedural_path (pretty_printer *event_pp) test_diagnostic_context dc; print_path_summary_as_text (&summary, &dc, true); ASSERT_STREQ (" `foo': events 1-2 (depth 0)\n" - " |\n" - " | (1): first `free'\n" - " | (2): double `free'\n" - " |\n", + " (1): first `free'\n" + " (2): double `free'\n", pp_formatted_text (dc.printer)); }