From: David Malcolm Date: Thu, 16 May 2024 01:22:51 +0000 (-0400) Subject: diagnostics: simplify output of purely intraprocedural execution paths X-Git-Tag: basepoints/gcc-16~9020 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3cd267446755ab6b2c59936a718d34c8bc474ca5;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/diagnostic-path.h b/gcc/diagnostic-path.h index fb7abe88ed3..696991c6d73 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 cedc1a28c83..bcf518ac279 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 de1a49c436e..bc831947175 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 a5def2764fe..cfd6b4f6f4f 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 3cf7fb00424..eeb52192fd4 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 24fe84deb14..acc41567f48 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 e1343705258..27b885dc955 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 0fd865485df..d2dc522cc1a 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 ac699ec544e..3661f1fd485 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 d00d076b209..8620bc919a5 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 f914ed6216f..57d25f436a0 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 731a17293fc..264764551d2 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 83eec292e85..a832b084738 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 660901ab782..47f3bcb524f 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 b2b269a12b5..b8134aebfda 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 8247192a250..33389ef5d33 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)); }