diff options
author | Ian Lance Taylor <iant@golang.org> | 2023-06-26 09:57:21 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2023-06-26 09:57:21 -0700 |
commit | aa1e672b5d99102b03eb5fb9c51609c45f62bff7 (patch) | |
tree | 886212591b1c9d127eaaf234a4a2e22452ea384a /gcc/testsuite/gcc.dg | |
parent | 97e31a0a2a2d2273687fcdb4e5416aab1a2186e1 (diff) | |
parent | 3a39a31b8ae9c6465434aefa657f7fcc86f905c0 (diff) | |
download | gcc-devel/gccgo.zip gcc-devel/gccgo.tar.gz gcc-devel/gccgo.tar.bz2 |
Merge from trunk revision 3a39a31b8ae9c6465434aefa657f7fcc86f905c0.devel/gccgo
Diffstat (limited to 'gcc/testsuite/gcc.dg')
37 files changed, 1620 insertions, 15 deletions
diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c index 86d1ccf..3c4a45f 100644 --- a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c @@ -240,8 +240,8 @@ void test_16 (void) __analyzer_eval (strlen (msg) == 11); /* { dg-warning "TRUE" } */ /* Out-of-bounds. */ - __analyzer_eval (msg[100] == 'e'); /* { dg-warning "UNKNOWN" } */ - // TODO: some kind of warning for the out-of-bounds access + __analyzer_eval (msg[100] == 'e'); /* { dg-warning "UNKNOWN" "eval result" } */ + /* { dg-warning "buffer over-read" "out-of-bounds" { target *-*-* } .-1 } */ } static const char *__attribute__((noinline)) diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-macro-inline-events.c b/gcc/testsuite/gcc.dg/analyzer/malloc-macro-inline-events.c index f08aee6..9134bb4 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-macro-inline-events.c +++ b/gcc/testsuite/gcc.dg/analyzer/malloc-macro-inline-events.c @@ -12,11 +12,6 @@ int test (void *ptr) WRAPPED_FREE (ptr); /* { dg-message "in expansion of macro 'WRAPPED_FREE'" } */ WRAPPED_FREE (ptr); /* { dg-message "in expansion of macro 'WRAPPED_FREE'" } */ - /* Erase the spans indicating the header file - (to avoid embedding path assumptions). */ - /* { dg-regexp "\[^|\]+/malloc-macro.h:\[0-9\]+:\[0-9\]+:" } */ - /* { dg-regexp "\[^|\]+/malloc-macro.h:\[0-9\]+:\[0-9\]+:" } */ - /* { dg-begin-multiline-output "" } NN | #define WRAPPED_FREE(PTR) free(PTR) | ^~~~~~~~~ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-ascii.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-ascii.c new file mode 100644 index 0000000..5e6eadc --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-ascii.c @@ -0,0 +1,55 @@ +/* { dg-additional-options "-fdiagnostics-show-path-depths" } */ +/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */ +/* { dg-additional-options "-fdiagnostics-text-art-charset=ascii" } */ + +#include <stdint.h> + +int32_t arr[10]; + +void int_arr_write_element_after_end_off_by_one(int32_t x) +{ + arr[10] = x; /* { dg-line line } */ +} +/* { dg-warning "buffer overflow" "warning" { target *-*-* } line } */ +/* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } line } */ + + +/* { dg-begin-multiline-output "" } + arr[10] = x; + ~~~~~~~~^~~ + event 1 (depth 0) + | + | int32_t arr[10]; + | ^~~ + | | + | (1) capacity: 40 bytes + | + +--> 'int_arr_write_element_after_end_off_by_one': event 2 (depth 1) + | + | arr[10] = x; + | ~~~~~~~~^~~ + | | + | (2) out-of-bounds write from byte 40 till byte 43 but 'arr' ends at byte 40 + | + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + + +--------------------------------+ + |write from 'x' (type: 'int32_t')| + +--------------------------------+ + | + | + v + +--------+-----------------+---------++--------------------------------+ + | [0] | ... | [9] || | + +--------+-----------------+---------+| after valid range | + | 'arr' (type: 'int32_t[10]') || | + +------------------------------------++--------------------------------+ + |~~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~~~||~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~| + | | + +---------+--------+ +---------+---------+ + |capacity: 40 bytes| |overflow of 4 bytes| + +------------------+ +-------------------+ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-debug.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-debug.c new file mode 100644 index 0000000..4c4d9d1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-debug.c @@ -0,0 +1,40 @@ +/* Test of -fanalyzer-debug-text-art. */ + +/* { dg-additional-options "-fdiagnostics-text-art-charset=ascii -fanalyzer-debug-text-art" } */ + +#include <stdint.h> + +int32_t arr[10]; + +void int_arr_write_element_after_end_off_by_one(int32_t x) +{ + arr[10] = x; /* { dg-line line } */ +} +/* { dg-warning "buffer overflow" "warning" { target *-*-* } line } */ +/* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } line } */ + +/* { dg-begin-multiline-output "" } + + +---------+-----------+-----------+---+--------------------------------+ + | tc0 | tc1 | tc2 |tc3| tc4 | + +---------+-----------+-----------+---+--------------------------------+ + |bytes 0-3|bytes 4-35 |bytes 36-39| | bytes 40-43 | + +---------+-----------+-----------+ +--------------------------------+ + +--------------------------------+ + |write from 'x' (type: 'int32_t')| + +--------------------------------+ + | + | + v + +---------+-----------+-----------+ +--------------------------------+ + | [0] | ... | [9] | | | + +---------+-----------+-----------+ | after valid range | + | 'arr' (type: 'int32_t[10]') | | | + +---------------------------------+ +--------------------------------+ + |~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~| |~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~| + | | + +---------+--------+ +---------+---------+ + |capacity: 40 bytes| |overflow of 4 bytes| + +------------------+ +-------------------+ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-emoji.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-emoji.c new file mode 100644 index 0000000..1c61252 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-emoji.c @@ -0,0 +1,55 @@ +/* { dg-additional-options "-fdiagnostics-show-path-depths" } */ +/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */ +/* { dg-additional-options "-fdiagnostics-text-art-charset=emoji" } */ + +#include <stdint.h> + +int32_t arr[10]; + +void int_arr_write_element_after_end_off_by_one(int32_t x) +{ + arr[10] = x; /* { dg-line line } */ +} +/* { dg-warning "buffer overflow" "warning" { target *-*-* } line } */ +/* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } line } */ + + +/* { dg-begin-multiline-output "" } + arr[10] = x; + ~~~~~~~~^~~ + event 1 (depth 0) + | + | int32_t arr[10]; + | ^~~ + | | + | (1) capacity: 40 bytes + | + +--> 'int_arr_write_element_after_end_off_by_one': event 2 (depth 1) + | + | arr[10] = x; + | ~~~~~~~~^~~ + | | + | (2) out-of-bounds write from byte 40 till byte 43 but 'arr' ends at byte 40 + | + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + + ┌────────────────────────────────┐ + │write from 'x' (type: 'int32_t')│ + └────────────────────────────────┘ + │ + │ + v + ┌────────┬─────────────────┬─────────┐┌────────────────────────────────┐ + │ [0] │ ... │ [9] ││ │ + ├────────┴─────────────────┴─────────┤│ after valid range │ + │ 'arr' (type: 'int32_t[10]') ││ │ + └────────────────────────────────────┘└────────────────────────────────┘ + ├─────────────────┬──────────────────┤├───────────────┬────────────────┤ + │ │ + ╭─────────┴────────╮ ╭───────────┴──────────╮ + │capacity: 40 bytes│ │⚠️ overflow of 4 bytes│ + ╰──────────────────╯ ╰──────────────────────╯ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-json.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-json.c new file mode 100644 index 0000000..0a2cc34 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-json.c @@ -0,0 +1,13 @@ +/* { dg-additional-options "-fdiagnostics-format=json-file" } */ + +/* The custom JSON format doesn't support text art, so this is just a simple + smoketext. */ + +#include <stdint.h> + +int32_t arr[10]; + +void int_arr_write_element_after_end_off_by_one(int32_t x) +{ + arr[10] = x; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-sarif.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-sarif.c new file mode 100644 index 0000000..051a1ce --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-sarif.c @@ -0,0 +1,24 @@ +/* We require -fdiagnostics-text-art-charset= to get any text art here + because of the test suite using -fdiagnostics-plain-output. */ + +/* { dg-additional-options "-fdiagnostics-format=sarif-file -fdiagnostics-text-art-charset=ascii" } */ + +#include <stdint.h> + +int32_t arr[10]; + +void int_arr_write_element_after_end_off_by_one(int32_t x) +{ + arr[10] = x; +} + +/* Verify that some JSON was written to a file with the expected name. + + { dg-final { verify-sarif-file } } + + Expect the "alt-text" to be captured. + { dg-final { scan-sarif-file "\"text\": \"Diagram visualizing the predicted out-of-bounds access\"," } } + + Expect the diagram to have 4 leading spaces (to indicate a code block), + and that at least part of the diagram was written out. + { dg-final { scan-sarif-file "\"markdown\": \" .*capacity: 40 bytes.*\"" } } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-unicode.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-unicode.c new file mode 100644 index 0000000..71f66ff --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-unicode.c @@ -0,0 +1,55 @@ +/* { dg-additional-options "-fdiagnostics-show-path-depths" } */ +/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */ +/* { dg-additional-options "-fdiagnostics-text-art-charset=unicode" } */ + +#include <stdint.h> + +int32_t arr[10]; + +void int_arr_write_element_after_end_off_by_one(int32_t x) +{ + arr[10] = x; /* { dg-line line } */ +} +/* { dg-warning "buffer overflow" "warning" { target *-*-* } line } */ +/* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } line } */ + + +/* { dg-begin-multiline-output "" } + arr[10] = x; + ~~~~~~~~^~~ + event 1 (depth 0) + | + | int32_t arr[10]; + | ^~~ + | | + | (1) capacity: 40 bytes + | + +--> 'int_arr_write_element_after_end_off_by_one': event 2 (depth 1) + | + | arr[10] = x; + | ~~~~~~~~^~~ + | | + | (2) out-of-bounds write from byte 40 till byte 43 but 'arr' ends at byte 40 + | + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + + ┌────────────────────────────────┐ + │write from 'x' (type: 'int32_t')│ + └────────────────────────────────┘ + │ + │ + v + ┌────────┬─────────────────┬─────────┐┌────────────────────────────────┐ + │ [0] │ ... │ [9] ││ │ + ├────────┴─────────────────┴─────────┤│ after valid range │ + │ 'arr' (type: 'int32_t[10]') ││ │ + └────────────────────────────────────┘└────────────────────────────────┘ + ├─────────────────┬──────────────────┤├───────────────┬────────────────┤ + │ │ + ╭─────────┴────────╮ ╭─────────┴─────────╮ + │capacity: 40 bytes│ │overflow of 4 bytes│ + ╰──────────────────╯ ╰───────────────────╯ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-10.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-10.c new file mode 100644 index 0000000..4a7b8e3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-10.c @@ -0,0 +1,29 @@ +/* { dg-additional-options "-fdiagnostics-text-art-charset=unicode" } */ + +#include <stdint.h> +#include <stdlib.h> + +int32_t int_vla_write_element_symbolic_before_start (int32_t x, size_t n) +{ + int32_t arr[n]; /* { dg-message "\\(1\\) capacity: 'n \\* 4' bytes" } */ + arr[-2] = 42; /* { dg-warning "stack-based buffer underwrite" } */ +} + +/* { dg-begin-multiline-output "" } + + ┌───────────────────┐ + │write of '(int) 42'│ + └───────────────────┘ + │ + │ + v + ┌───────────────────┐ ┌────────────────────────────────┐ + │before valid range │ │buffer allocated on stack at (1)│ + └───────────────────┘ └────────────────────────────────┘ + ├─────────┬─────────┤├───────┬───────┤├───────────────┬────────────────┤ + │ │ │ + ╭─────────┴───────────╮ ╭───┴───╮ ╭───────────┴───────────╮ + │underwrite of 4 bytes│ │4 bytes│ │capacity: 'n * 4' bytes│ + ╰─────────────────────╯ ╰───────╯ ╰───────────────────────╯ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-11.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-11.c new file mode 100644 index 0000000..f8eb158 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-11.c @@ -0,0 +1,82 @@ +/* { dg-additional-options "-fdiagnostics-text-art-charset=unicode" } */ +/* { dg-require-effective-target alloca } */ + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> + +void test6 (size_t size) +{ + int32_t *buf = __builtin_alloca (4 * size); + memset (buf, 0, 4 * size); + int32_t last = *(buf + 4 * size); /* { dg-warning "stack-based buffer over-read" } */ +} + +/* (size * 16) - (size * 4) leads to a gap of (size * 12). */ + +/* { dg-begin-multiline-output "" } + + ┌─────────────────┐ + │ read of 4 bytes │ + └─────────────────┘ + ^ + │ + │ + ┌────────────────────────────────┐ ┌─────────────────┐ + │buffer allocated on stack at (1)│ │after valid range│ + └────────────────────────────────┘ └─────────────────┘ + ├───────────────┬────────────────┤├────────┬────────┤├────────┬────────┤ + │ │ │ + │ │ ╭──────────┴─────────╮ + │ │ │over-read of 4 bytes│ + │ │ ╰────────────────────╯ + ╭───────────┴──────────╮ ╭────────┴────────╮ + │size: 'size * 4' bytes│ │'size * 12' bytes│ + ╰──────────────────────╯ ╰─────────────────╯ + + { dg-end-multiline-output "" } */ + +void test7 (size_t size) +{ + int32_t *buf = __builtin_alloca (4 * size + 3); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ + buf[size] = 42; /* { dg-warning "stack-based buffer overflow" } */ +} + +/* { dg-begin-multiline-output "" } + + ┌───────────────────────────────────────┐ + │ write of '(int) 42' │ + └───────────────────────────────────────┘ + │ │ + │ │ + v v + ┌──────────────────────────────────────────────────┐┌──────────────────┐ + │ buffer allocated on stack at (1) ││after valid range │ + └──────────────────────────────────────────────────┘└──────────────────┘ + ├────────────────────────┬─────────────────────────┤├────────┬─────────┤ + │ │ + ╭───────────────┴──────────────╮ ╭─────────┴────────╮ + │capacity: 'size * 4 + 3' bytes│ │overflow of 1 byte│ + ╰──────────────────────────────╯ ╰──────────────────╯ + + { dg-end-multiline-output "" } */ + + +/* We're currently not able to generate a diagram for this case; + make sure we handle this case gracefully. */ + +char *test99 (const char *x, const char *y) +{ + size_t len_x = __builtin_strlen (x); + size_t len_y = __builtin_strlen (y); + /* BUG (root cause): forgot to add 1 for terminator. */ + size_t sz = len_x + len_y; + char *result = __builtin_malloc (sz); + if (!result) + return NULL; + __builtin_memcpy (result, x, len_x); + __builtin_memcpy (result + len_x, y, len_y); + /* BUG (symptom): off-by-one out-of-bounds write to heap. */ + result[len_x + len_y] = '\0'; /* { dg-warning "heap-based buffer overflow" } */ + return result; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-12.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-12.c new file mode 100644 index 0000000..3573750 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-12.c @@ -0,0 +1,53 @@ +/* { dg-additional-options "-fdiagnostics-text-art-charset=unicode" } */ +/* { dg-require-effective-target alloca } */ + +#include <string.h> +#include <stdlib.h> +#include <stdint.h> + +void test8 (size_t size, size_t offset) +{ + char src[size]; + char dst[size]; + memcpy (dst, src, size + offset); /* { dg-line test8 } */ + /* { dg-warning "over-read" "warning" { target *-*-* } test8 } */ + /* { dg-warning "overflow" "warning" { target *-*-* } test8 } */ +} + +/* { dg-begin-multiline-output "" } + + ┌──────────────────────────────────────────────────────────────────────┐ + │ read of 'size + offset' bytes │ + └──────────────────────────────────────────────────────────────────────┘ + ^ ^ + │ │ + │ │ + ┌──────────────────────────────────┐┌──────────────────────────────────┐ + │ buffer allocated on stack at (1) ││ after valid range │ + └──────────────────────────────────┘└──────────────────────────────────┘ + ├────────────────┬─────────────────┤├────────────────┬─────────────────┤ + │ │ + ╭─────────┴────────╮ ╭─────────────┴─────────────╮ + │size: 'size' bytes│ │over-read of 'offset' bytes│ + ╰──────────────────╯ ╰───────────────────────────╯ + + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + + ┌──────────────────────────────────────────────────────────────────────┐ + │ write of 'size + offset' bytes │ + └──────────────────────────────────────────────────────────────────────┘ + │ │ + │ │ + v v + ┌──────────────────────────────────┐┌──────────────────────────────────┐ + │ buffer allocated on stack at (1) ││ after valid range │ + └──────────────────────────────────┘└──────────────────────────────────┘ + ├────────────────┬─────────────────┤├────────────────┬─────────────────┤ + │ │ + ╭───────────┴──────────╮ ╭─────────────┴────────────╮ + │capacity: 'size' bytes│ │overflow of 'offset' bytes│ + ╰──────────────────────╯ ╰──────────────────────────╯ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-13.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-13.c new file mode 100644 index 0000000..dcd1263 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-13.c @@ -0,0 +1,43 @@ +/* { dg-additional-options "-fdiagnostics-text-art-charset=unicode" } */ + +#include <string.h> + +void +test_non_ascii () +{ + char buf[9]; + strcpy (buf, "Liberté\n"); /* { dg-warning "stack-based buffer overflow" } */ + /* { dg-warning "'__builtin_memcpy' writing 10 bytes into a region of size 9 overflows the destination" "" { target *-*-* } .-1 } */ +} + +/* Example of non-ASCII UTF-8 that's short enough to fully quote, whilst + containing control characters. */ + +/* { dg-begin-multiline-output "" } + + ┌──────┬──────┬──────┬──────┬──────┬──────┬────┬────┬──────┐┌─────────────────┐ + │ [0] │ [1] │ [2] │ [3] │ [4] │ [5] │[6] │[7] │ [8] ││ [9] │ + ├──────┼──────┼──────┼──────┼──────┼──────┼────┼────┼──────┤├─────────────────┤ + │ 0x4c │ 0x69 │ 0x62 │ 0x65 │ 0x72 │ 0x74 │0xc3│0xa9│ 0x0a ││ 0x00 │ + ├──────┼──────┼──────┼──────┼──────┼──────┼────┴────┼──────┤├─────────────────┤ + │U+004c│U+0069│U+0062│U+0065│U+0072│U+0074│ U+00e9 │U+000a││ U+0000 │ + ├──────┼──────┼──────┼──────┼──────┼──────┼─────────┼──────┤├─────────────────┤ + │ L │ i │ b │ e │ r │ t │ é │ ││ NUL │ + ├──────┴──────┴──────┴──────┴──────┴──────┴─────────┴──────┴┴─────────────────┤ + │ string literal (type: 'char[10]') │ + └─────────────────────────────────────────────────────────────────────────────┘ + │ │ │ │ │ │ │ │ │ │ + │ │ │ │ │ │ │ │ │ │ + v v v v v v v v v v + ┌──────┬────────────────────────────────────────────┬──────┐┌─────────────────┐ + │ [0] │ ... │ [8] ││ │ + ├──────┴────────────────────────────────────────────┴──────┤│after valid range│ + │ 'buf' (type: 'char[9]') ││ │ + └──────────────────────────────────────────────────────────┘└─────────────────┘ + ├────────────────────────────┬─────────────────────────────┤├────────┬────────┤ + │ │ + ╭────────┴────────╮ ╭─────────┴────────╮ + │capacity: 9 bytes│ │overflow of 1 byte│ + ╰─────────────────╯ ╰──────────────────╯ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-14.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-14.c new file mode 100644 index 0000000..3cedf06 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-14.c @@ -0,0 +1,110 @@ +/* { dg-additional-options "-fdiagnostics-text-art-charset=unicode" } */ + +#include <stdint.h> + +extern int32_t arr_0[0]; /* { dg-message "capacity: 0 bytes" } */ +extern int32_t arr_1[1]; /* { dg-message "capacity: 4 bytes" } */ +extern int32_t arr_2[2]; /* { dg-message "capacity: 8 bytes" } */ +extern int32_t arr_3[3]; /* { dg-message "capacity: 12 bytes" } */ +extern int32_t arr_4[4]; /* { dg-message "capacity: 16 bytes" } */ + +void test_immediately_after (int x) +{ + arr_0[0] = x; /* { dg-warning "buffer overflow" } */ + arr_1[1] = x; /* { dg-warning "buffer overflow" } */ + arr_2[2] = x; /* { dg-warning "buffer overflow" } */ + arr_3[3] = x; /* { dg-warning "buffer overflow" } */ + arr_4[4] = x; /* { dg-warning "buffer overflow" } */ +} + +/* Expect no diagram for the arr_0 case: there's no valid region +to write to. */ + +/* The arr_1 case. */ +/* { dg-begin-multiline-output "" } + + ┌──────────────────────────────────┐ + │ write from 'x' (type: 'int') │ + └──────────────────────────────────┘ + │ + │ + v + ┌──────────────────────────────────┐┌──────────────────────────────────┐ + │ [0] ││ │ + ├──────────────────────────────────┤│ after valid range │ + │ 'arr_1' (type: 'int32_t[1]') ││ │ + └──────────────────────────────────┘└──────────────────────────────────┘ + ├────────────────┬─────────────────┤├────────────────┬─────────────────┤ + │ │ + ╭────────┴────────╮ ╭─────────┴─────────╮ + │capacity: 4 bytes│ │overflow of 4 bytes│ + ╰─────────────────╯ ╰───────────────────╯ + + { dg-end-multiline-output "" } */ + +/* The arr_2 case. */ +/* { dg-begin-multiline-output "" } + + ┌────────────────────────────┐ + │write from 'x' (type: 'int')│ + └────────────────────────────┘ + │ + │ + v + ┌────────────────────┬───────────────────┐┌────────────────────────────┐ + │ [0] │ [1] ││ │ + ├────────────────────┴───────────────────┤│ after valid range │ + │ 'arr_2' (type: 'int32_t[2]') ││ │ + └────────────────────────────────────────┘└────────────────────────────┘ + ├───────────────────┬────────────────────┤├─────────────┬──────────────┤ + │ │ + ╭────────┴────────╮ ╭─────────┴─────────╮ + │capacity: 8 bytes│ │overflow of 4 bytes│ + ╰─────────────────╯ ╰───────────────────╯ + + { dg-end-multiline-output "" } */ + +/* The arr_3 case. */ +// Perhaps we should show [1] rather than ellipsize here. +/* { dg-begin-multiline-output "" } + + ┌────────────────────────────┐ + │write from 'x' (type: 'int')│ + └────────────────────────────┘ + │ + │ + v + ┌─────────────┬─────────────┬────────────┐┌────────────────────────────┐ + │ [0] │ ... │ [2] ││ │ + ├─────────────┴─────────────┴────────────┤│ after valid range │ + │ 'arr_3' (type: 'int32_t[3]') ││ │ + └────────────────────────────────────────┘└────────────────────────────┘ + ├───────────────────┬────────────────────┤├─────────────┬──────────────┤ + │ │ + ╭─────────┴────────╮ ╭─────────┴─────────╮ + │capacity: 12 bytes│ │overflow of 4 bytes│ + ╰──────────────────╯ ╰───────────────────╯ + + { dg-end-multiline-output "" } */ + +/* The arr_4 case. */ +/* { dg-begin-multiline-output "" } + + ┌────────────────────────────┐ + │write from 'x' (type: 'int')│ + └────────────────────────────┘ + │ + │ + v + ┌──────────┬──────────────────┬──────────┐┌────────────────────────────┐ + │ [0] │ ... │ [3] ││ │ + ├──────────┴──────────────────┴──────────┤│ after valid range │ + │ 'arr_4' (type: 'int32_t[4]') ││ │ + └────────────────────────────────────────┘└────────────────────────────┘ + ├───────────────────┬────────────────────┤├─────────────┬──────────────┤ + │ │ + ╭─────────┴────────╮ ╭─────────┴─────────╮ + │capacity: 16 bytes│ │overflow of 4 bytes│ + ╰──────────────────╯ ╰───────────────────╯ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-15.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-15.c new file mode 100644 index 0000000..e2a6381 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-15.c @@ -0,0 +1,42 @@ +/* Regression test for ICE with short values of + --param=analyzer-text-art-string-ellipsis-threshold=. */ +/* { dg-additional-options "-fdiagnostics-text-art-charset=unicode --param=analyzer-text-art-string-ellipsis-threshold=0" } */ + +#include <string.h> + +void +test_non_ascii () +{ + char buf[9]; + strcpy (buf, "Liberté\n"); /* { dg-warning "stack-based buffer overflow" } */ + /* { dg-warning "'__builtin_memcpy' writing 10 bytes into a region of size 9 overflows the destination" "" { target *-*-* } .-1 } */ +} + +/* { dg-begin-multiline-output "" } + + ┌──────┬──────┬──────┬──────┬──────┬──────┬────┬────┬──────┐┌─────────────────┐ + │ [0] │ [1] │ [2] │ [3] │ [4] │ [5] │[6] │[7] │ [8] ││ [9] │ + ├──────┼──────┼──────┼──────┼──────┼──────┼────┼────┼──────┤├─────────────────┤ + │ 0x4c │ 0x69 │ 0x62 │ 0x65 │ 0x72 │ 0x74 │0xc3│0xa9│ 0x0a ││ 0x00 │ + ├──────┼──────┼──────┼──────┼──────┼──────┼────┴────┼──────┤├─────────────────┤ + │U+004c│U+0069│U+0062│U+0065│U+0072│U+0074│ U+00e9 │U+000a││ U+0000 │ + ├──────┼──────┼──────┼──────┼──────┼──────┼─────────┼──────┤├─────────────────┤ + │ L │ i │ b │ e │ r │ t │ é │ ││ NUL │ + ├──────┴──────┴──────┴──────┴──────┴──────┴─────────┴──────┴┴─────────────────┤ + │ string literal (type: 'char[10]') │ + └─────────────────────────────────────────────────────────────────────────────┘ + │ │ │ │ │ │ │ │ │ │ + │ │ │ │ │ │ │ │ │ │ + v v v v v v v v v v + ┌──────┬────────────────────────────────────────────┬──────┐┌─────────────────┐ + │ [0] │ ... │ [8] ││ │ + ├──────┴────────────────────────────────────────────┴──────┤│after valid range│ + │ 'buf' (type: 'char[9]') ││ │ + └──────────────────────────────────────────────────────────┘└─────────────────┘ + ├────────────────────────────┬─────────────────────────────┤├────────┬────────┤ + │ │ + ╭────────┴────────╮ ╭─────────┴────────╮ + │capacity: 9 bytes│ │overflow of 1 byte│ + ╰─────────────────╯ ╰──────────────────╯ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-2.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-2.c new file mode 100644 index 0000000..535dab1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-2.c @@ -0,0 +1,30 @@ +/* { dg-additional-options "-fdiagnostics-text-art-charset=unicode" } */ + +#include <stdint.h> +#include <stdlib.h> + +void int_vla_write_element_after_end_off_by_one(int32_t x, size_t n) +{ + int32_t arr[n]; /* { dg-message "\\(1\\) capacity: 'n \\* 4' bytes" } */ + + arr[n] = x; /* { dg-warning "stack-based buffer overflow" } */ +} + +/* { dg-begin-multiline-output "" } + + ┌──────────────────────────────────┐ + │ write from 'x' (type: 'int32_t') │ + └──────────────────────────────────┘ + │ + │ + v + ┌──────────────────────────────────┐┌──────────────────────────────────┐ + │ buffer allocated on stack at (1) ││ after valid range │ + └──────────────────────────────────┘└──────────────────────────────────┘ + ├────────────────┬─────────────────┤├────────────────┬─────────────────┤ + │ │ + ╭───────────┴───────────╮ ╭─────────┴─────────╮ + │capacity: 'n * 4' bytes│ │overflow of 4 bytes│ + ╰───────────────────────╯ ╰───────────────────╯ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-3.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-3.c new file mode 100644 index 0000000..064f3fa --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-3.c @@ -0,0 +1,45 @@ +/* The multiline output assumes sizeof(size_t) == 8. + { dg-require-effective-target lp64 } */ + +/* { dg-additional-options "-fdiagnostics-text-art-charset=unicode" } */ + +#include <stdlib.h> +#include <string.h> +#include <stdint.h> + +struct str { + size_t len; + char data[]; +}; + +struct str * +make_str_badly (const char *src) +{ + size_t len = strlen(src); + struct str *str = malloc(sizeof(str) + len); /* { dg-message "\\(1\\) capacity: 'len \\+ 8' bytes" } */ + if (!str) + return NULL; + str->len = len; + memcpy(str->data, src, len); + str->data[len] = '\0'; /* { dg-warning "heap-based buffer overflow" } */ + return str; +} + +/* { dg-begin-multiline-output "" } + + ┌──────────────────────────────────┐ + │ write of '(char) 0' │ + └──────────────────────────────────┘ + │ + │ + v + ┌──────────────────────────────────┐┌──────────────────────────────────┐ + │ buffer allocated on heap at (1) ││ after valid range │ + └──────────────────────────────────┘└──────────────────────────────────┘ + ├────────────────┬─────────────────┤├────────────────┬─────────────────┤ + │ │ + ╭────────────┴────────────╮ ╭─────────┴────────╮ + │capacity: 'len + 8' bytes│ │overflow of 1 byte│ + ╰─────────────────────────╯ ╰──────────────────╯ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-4.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-4.c new file mode 100644 index 0000000..ec8e4ab --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-4.c @@ -0,0 +1,45 @@ +/* { dg-additional-options "-fdiagnostics-text-art-charset=unicode" } */ + +#include <string.h> + +#define LOREM_IPSUM \ + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod" \ + " tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim" \ + " veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea" \ + " commodo consequat. Duis aute irure dolor in reprehenderit in voluptate" \ + " velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint" \ + " occaecat cupidatat non proident, sunt in culpa qui officia deserunt" \ + " mollit anim id est laborum." + +void +test_long_string () +{ + char buf[100]; + strcpy (buf, LOREM_IPSUM); /* { dg-warning "stack-based buffer overflow" } */ + /* { dg-warning "'__builtin_memcpy' writing 446 bytes into a region of size 100 overflows the destination" "" { target *-*-* } .-1 } */ +} + +/* { dg-begin-multiline-output "" } + + ┌───┬───┬───┬───┬───┬───┬──────────┬─────┬─────┬─────┬─────┬─────┬─────┐ + │[0]│[1]│[2]│[3]│[4]│[5]│ │[440]│[441]│[442]│[443]│[444]│[445]│ + ├───┼───┼───┼───┼───┼───┤ ... ├─────┼─────┼─────┼─────┼─────┼─────┤ + │'L'│'o'│'r'│'e'│'m'│' '│ │ 'o' │ 'r' │ 'u' │ 'm' │ '.' │ NUL │ + ├───┴───┴───┴───┴───┴───┴──────────┴─────┴─────┴─────┴─────┴─────┴─────┤ + │ string literal (type: 'char[446]') │ + └──────────────────────────────────────────────────────────────────────┘ + │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ + │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ + v v v v v v v v v v v v v v v + ┌───┬─────────────────────┬────┐┌──────────────────────────────────────┐ + │[0]│ ... │[99]││ │ + ├───┴─────────────────────┴────┤│ after valid range │ + │ 'buf' (type: 'char[100]') ││ │ + └──────────────────────────────┘└──────────────────────────────────────┘ + ├──────────────┬───────────────┤├──────────────────┬───────────────────┤ + │ │ + ╭─────────┴─────────╮ ╭──────────┴──────────╮ + │capacity: 100 bytes│ │overflow of 346 bytes│ + ╰───────────────────╯ ╰─────────────────────╯ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-5-ascii.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-5-ascii.c new file mode 100644 index 0000000..e82bce9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-5-ascii.c @@ -0,0 +1,40 @@ +/* { dg-additional-options "-fdiagnostics-text-art-charset=ascii" } */ + +#include <string.h> + +void +test_non_ascii () +{ + char buf[5]; + strcpy (buf, "文字化け"); /* { dg-warning "stack-based buffer overflow" } */ + /* { dg-warning "'__builtin_memcpy' writing 13 bytes into a region of size 5 overflows the destination" "" { target *-*-* } .-1 } */ +} + +/* Without unicode support, we shouldn't show the printable unicode chars. */ + +/* { dg-begin-multiline-output "" } + + +-----+-----+-----+----+----++----+----+----+----+----+----+----+------+ + | [0] | [1] | [2] |[3] |[4] ||[5] |[6] |[7] |[8] |[9] |[10]|[11]| [12] | + +-----+-----+-----+----+----++----+----+----+----+----+----+----+------+ + |0xe6 |0x96 |0x87 |0xe5|0xad||0x97|0xe5|0x8c|0x96|0xe3|0x81|0x91| 0x00 | + +-----+-----+-----+----+----++----+----+----+----+----+----+----+------+ + | U+6587 | U+5b57 | U+5316 | U+3051 |U+0000| + +-----------------+---------------+--------------+--------------+------+ + | string literal (type: 'char[13]') | + +----------------------------------------------------------------------+ + | | | | | | | | | | | | | + | | | | | | | | | | | | | + v v v v v v v v v v v v v + +-----+----------------+----++-----------------------------------------+ + | [0] | ... |[4] || | + +-----+----------------+----+| after valid range | + | 'buf' (type: 'char[5]') || | + +---------------------------++-----------------------------------------+ + |~~~~~~~~~~~~~+~~~~~~~~~~~~~||~~~~~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~~~~~| + | | + +--------+--------+ +---------+---------+ + |capacity: 5 bytes| |overflow of 8 bytes| + +-----------------+ +-------------------+ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-5-unicode.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-5-unicode.c new file mode 100644 index 0000000..48fa12f --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-5-unicode.c @@ -0,0 +1,42 @@ +/* { dg-additional-options "-fdiagnostics-text-art-charset=unicode" } */ + +#include <string.h> + +void +test_non_ascii () +{ + char buf[5]; + strcpy (buf, "文字化け"); /* { dg-warning "stack-based buffer overflow" } */ + /* { dg-warning "'__builtin_memcpy' writing 13 bytes into a region of size 5 overflows the destination" "" { target *-*-* } .-1 } */ +} + +/* With unicode support, we should show the printable unicode chars. */ + +/* { dg-begin-multiline-output "" } + + ┌─────┬─────┬─────┬────┬────┐┌────┬────┬────┬────┬────┬────┬────┬──────┐ + │ [0] │ [1] │ [2] │[3] │[4] ││[5] │[6] │[7] │[8] │[9] │[10]│[11]│ [12] │ + ├─────┼─────┼─────┼────┼────┤├────┼────┼────┼────┼────┼────┼────┼──────┤ + │0xe6 │0x96 │0x87 │0xe5│0xad││0x97│0xe5│0x8c│0x96│0xe3│0x81│0x91│ 0x00 │ + ├─────┴─────┴─────┼────┴────┴┴────┼────┴────┴────┼────┴────┴────┼──────┤ + │ U+6587 │ U+5b57 │ U+5316 │ U+3051 │U+0000│ + ├─────────────────┼───────────────┼──────────────┼──────────────┼──────┤ + │ 文 │ 字 │ 化 │ け │ NUL │ + ├─────────────────┴───────────────┴──────────────┴──────────────┴──────┤ + │ string literal (type: 'char[13]') │ + └──────────────────────────────────────────────────────────────────────┘ + │ │ │ │ │ │ │ │ │ │ │ │ │ + │ │ │ │ │ │ │ │ │ │ │ │ │ + v v v v v v v v v v v v v + ┌─────┬────────────────┬────┐┌─────────────────────────────────────────┐ + │ [0] │ ... │[4] ││ │ + ├─────┴────────────────┴────┤│ after valid range │ + │ 'buf' (type: 'char[5]') ││ │ + └───────────────────────────┘└─────────────────────────────────────────┘ + ├─────────────┬─────────────┤├────────────────────┬────────────────────┤ + │ │ + ╭────────┴────────╮ ╭─────────┴─────────╮ + │capacity: 5 bytes│ │overflow of 8 bytes│ + ╰─────────────────╯ ╰───────────────────╯ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-6.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-6.c new file mode 100644 index 0000000..25bf9d5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-6.c @@ -0,0 +1,125 @@ +/* { dg-require-effective-target lp64 } + Misbehaves with -m32 due to optimization turning the pointer arithmetic into: + _2 = &buf + 4294967246; + memcpy (_2, _1, 4096); +*/ + +/* { dg-additional-options "-fdiagnostics-text-art-charset=unicode" } */ + +#include <string.h> + +#define LOREM_IPSUM \ + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod" \ + " tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim" \ + " veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea" \ + " commodo consequat. Duis aute irure dolor in reprehenderit in voluptate" \ + " velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint" \ + " occaecat cupidatat non proident, sunt in culpa qui officia deserunt" \ + " mollit anim id est laborum." + +/* This memcpy reads from both before and after the bounds of the + string literal, and writes to both before and after the bounds of "buf". */ + +void +test_bad_memcpy () +{ + char buf[100]; + memcpy (buf - 50, LOREM_IPSUM - 100, 4096); /* { dg-warning "stack-based buffer overflow" } */ + /* { dg-warning "stack-based buffer underwrite" "" { target *-*-* } .-1 } */ + /* { dg-warning "buffer under-read" "" { target *-*-* } .-2 } */ + /* { dg-warning "buffer over-read" "" { target *-*-* } .-3 } */ + /* { dg-warning "'memcpy' writing 4096 bytes into a region of size 0 overflows the destination" "" { target *-*-* } .-4 } */ +} + +/* { dg-begin-multiline-output "" } + + ┌─────────────────────────────────────────────────────────────────────────┐ + │ read of 4096 bytes │ + └─────────────────────────────────────────────────────────────────────────┘ + ^ ^ ^ ^ ^ + │ │ │ │ │ + │ │ │ │ │ + ┌──────────────────┐┌──────────┬──────────┬────────────┐┌─────────────────┐ + │ ││ [0] │ ... │ [445] ││ │ + │before valid range│├──────────┴──────────┴────────────┤│after valid range│ + │ ││string literal (type: 'char[446]')││ │ + └──────────────────┘└──────────────────────────────────┘└─────────────────┘ + ├────────┬─────────┤├────────────────┬─────────────────┤├────────┬────────┤ + │ │ │ + ╭────────┴──────────────╮ ╭───────┴───────╮ ╭───────────┴───────────╮ + │under-read of 100 bytes│ │size: 446 bytes│ │over-read of 3550 bytes│ + ╰───────────────────────╯ ╰───────────────╯ ╰───────────────────────╯ + + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + + ┌──────────────────────────────────────────────────────────────────────┐ + │ write of 4096 bytes │ + └──────────────────────────────────────────────────────────────────────┘ + │ │ │ │ │ + │ │ │ │ │ + v v v v v + ┌──────────────────┐┌───────┬───────┬─────────┐┌───────────────────────┐ + │ ││ [0] │ ... │ [99] ││ │ + │before valid range│├───────┴───────┴─────────┤│ after valid range │ + │ ││'buf' (type: 'char[100]')││ │ + └──────────────────┘└─────────────────────────┘└───────────────────────┘ + ├────────┬─────────┤├────────────┬────────────┤├───────────┬───────────┤ + │ │ │ + │ ╭─────────┴─────────╮ ╭───────────┴──────────╮ + │ │capacity: 100 bytes│ │overflow of 3946 bytes│ + │ ╰───────────────────╯ ╰──────────────────────╯ + ╭────────┴─────────────╮ + │underwrite of 50 bytes│ + ╰──────────────────────╯ + + { dg-end-multiline-output "" } */ + +/* The read and write diagrams are each emitted twice: once for the "before" + and once for the "after" diagnostic. */ + +/* { dg-begin-multiline-output "" } + + ┌─────────────────────────────────────────────────────────────────────────┐ + │ read of 4096 bytes │ + └─────────────────────────────────────────────────────────────────────────┘ + ^ ^ ^ ^ ^ + │ │ │ │ │ + │ │ │ │ │ + ┌──────────────────┐┌──────────┬──────────┬────────────┐┌─────────────────┐ + │ ││ [0] │ ... │ [445] ││ │ + │before valid range│├──────────┴──────────┴────────────┤│after valid range│ + │ ││string literal (type: 'char[446]')││ │ + └──────────────────┘└──────────────────────────────────┘└─────────────────┘ + ├────────┬─────────┤├────────────────┬─────────────────┤├────────┬────────┤ + │ │ │ + ╭────────┴──────────────╮ ╭───────┴───────╮ ╭───────────┴───────────╮ + │under-read of 100 bytes│ │size: 446 bytes│ │over-read of 3550 bytes│ + ╰───────────────────────╯ ╰───────────────╯ ╰───────────────────────╯ + + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + + ┌──────────────────────────────────────────────────────────────────────┐ + │ write of 4096 bytes │ + └──────────────────────────────────────────────────────────────────────┘ + │ │ │ │ │ + │ │ │ │ │ + v v v v v + ┌──────────────────┐┌───────┬───────┬─────────┐┌───────────────────────┐ + │ ││ [0] │ ... │ [99] ││ │ + │before valid range│├───────┴───────┴─────────┤│ after valid range │ + │ ││'buf' (type: 'char[100]')││ │ + └──────────────────┘└─────────────────────────┘└───────────────────────┘ + ├────────┬─────────┤├────────────┬────────────┤├───────────┬───────────┤ + │ │ │ + │ ╭─────────┴─────────╮ ╭───────────┴──────────╮ + │ │capacity: 100 bytes│ │overflow of 3946 bytes│ + │ ╰───────────────────╯ ╰──────────────────────╯ + ╭────────┴─────────────╮ + │underwrite of 50 bytes│ + ╰──────────────────────╯ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-7.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-7.c new file mode 100644 index 0000000..25a9acc --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-7.c @@ -0,0 +1,36 @@ +/* { dg-additional-options "-fdiagnostics-text-art-charset=unicode" } */ + +#include <string.h> + +void +test_string_with_control_chars () +{ + char buf[8]; + strcpy (buf, "\tone\n\ttwo\n"); /* { dg-warning "stack-based buffer overflow" } */ + /* { dg-warning "'__builtin_memcpy' writing 11 bytes into a region of size 8 overflows the destination" "" { target *-*-* } .-1 } */ +} + +/* { dg-begin-multiline-output "" } + + ┌──────┬──────┬──────┬─────┬─────┬─────┬─────┬─────┐┌─────┬─────┬──────┐ + │ [0] │ [1] │ [2] │ [3] │ [4] │ [5] │ [6] │ [7] ││ [8] │ [9] │ [10] │ + ├──────┼──────┼──────┼─────┼─────┼─────┼─────┼─────┤├─────┼─────┼──────┤ + │ 0x09 │ 'o' │ 'n' │ 'e' │0x0a │0x09 │ 't' │ 'w' ││ 'o' │0x0a │ NUL │ + ├──────┴──────┴──────┴─────┴─────┴─────┴─────┴─────┴┴─────┴─────┴──────┤ + │ string literal (type: 'char[11]') │ + └──────────────────────────────────────────────────────────────────────┘ + │ │ │ │ │ │ │ │ │ │ │ + │ │ │ │ │ │ │ │ │ │ │ + v v v v v v v v v v v + ┌──────┬─────────────────────────────────────┬─────┐┌──────────────────┐ + │ [0] │ ... │ [7] ││ │ + ├──────┴─────────────────────────────────────┴─────┤│after valid range │ + │ 'buf' (type: 'char[8]') ││ │ + └──────────────────────────────────────────────────┘└──────────────────┘ + ├────────────────────────┬─────────────────────────┤├────────┬─────────┤ + │ │ + ╭────────┴────────╮ ╭─────────┴─────────╮ + │capacity: 8 bytes│ │overflow of 3 bytes│ + ╰─────────────────╯ ╰───────────────────╯ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-8.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-8.c new file mode 100644 index 0000000..24d8735 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-8.c @@ -0,0 +1,34 @@ +/* { dg-additional-options "-fdiagnostics-text-art-charset=unicode" } */ + +#include <stdlib.h> +#include <stdint.h> + +/* Gap of 4, then an overflow of 4. */ + +void test2 (size_t size) +{ + int32_t *buf = __builtin_malloc (size * sizeof(int32_t)); /* { dg-message "\\(1\\) capacity: 'size \\* 4' bytes" } */ + if (!buf) return; + + buf[size + 1] = 42; /* { dg-warning "heap-based buffer overflow" } */ + __builtin_free (buf); +} + +/* { dg-begin-multiline-output "" } + + ┌───────────────────┐ + │write of '(int) 42'│ + └───────────────────┘ + │ + │ + v + ┌───────────────────────────────┐ ┌───────────────────┐ + │buffer allocated on heap at (1)│ │ after valid range │ + └───────────────────────────────┘ └───────────────────┘ + ├───────────────┬───────────────┤├───────┬────────┤├─────────┬─────────┤ + │ │ │ + ╭─────────────┴────────────╮ ╭───┴───╮ ╭─────────┴─────────╮ + │capacity: 'size * 4' bytes│ │4 bytes│ │overflow of 4 bytes│ + ╰──────────────────────────╯ ╰───────╯ ╰───────────────────╯ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-9.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-9.c new file mode 100644 index 0000000..bb9ad66 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-9.c @@ -0,0 +1,42 @@ +/* { dg-additional-options "-fdiagnostics-text-art-charset=unicode" } */ + +#include <stdint.h> + +struct st +{ + char buf[16]; + int32_t x; + int32_t y; +}; + +struct st arr[10]; + +int32_t struct_arr_read_x_element_before_start_far(void) +{ + return arr[-100].x; /* { dg-warning "buffer under-read" "warning" } */ + /* { dg-message "out-of-bounds read from byte -2384 till byte -2381 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */ +} + +// TODO: show index of accessed element +// TODO: show field of accessed element +/* { dg-begin-multiline-output "" } + + ┌───────────────────────────┐ + │read of 'int32_t' (4 bytes)│ + └───────────────────────────┘ + ^ + │ + │ + ┌───────────────────────────┐ ┌─────────┬─────────┬─────────┐ + │ │ │ [0] │ ... │ [9] │ + │ before valid range │ ├─────────┴─────────┴─────────┤ + │ │ │'arr' (type: 'struct st[10]')│ + └───────────────────────────┘ └─────────────────────────────┘ + ├─────────────┬─────────────┤├────┬─────┤├──────────────┬──────────────┤ + │ │ │ + ╭──────────┴──────────╮ ╭─────┴────╮ ╭───────┴───────╮ + │under-read of 4 bytes│ │2380 bytes│ │size: 240 bytes│ + ╰─────────────────────╯ ╰──────────╯ ╰───────────────╯ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/pattern-test-2.c b/gcc/testsuite/gcc.dg/analyzer/pattern-test-2.c index 7c8d1b3..5b8ff7b 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pattern-test-2.c +++ b/gcc/testsuite/gcc.dg/analyzer/pattern-test-2.c @@ -26,7 +26,7 @@ void test_2 (void *p, void *q) foo(p); /* { dg-warning "pattern match on 'p != 0'" "p != 0" { target *-*-* } cond_2 } */ - /* { dg-warning "pattern match on 'tmp1 | tmp2 != 0'" "tmp1 | tmp2 != 0" { target *-*-* } cond_2 } */ + /* { dg-warning "pattern match on 'p == 0 | q == 0 != 0'" "tmp1 | tmp2 != 0" { target *-*-* } cond_2 } */ /* { dg-warning "pattern match on 'q != 0'" "q != 0" { target *-*-* } cond_2 } */ } @@ -42,6 +42,6 @@ void test_3 (void *p, void *q) foo(p); /* { dg-warning "pattern match on 'p == 0'" "p == 0" { target *-*-* } cond_3 } */ - /* { dg-warning "pattern match on 'tmp1 & tmp2 == 0'" "tmp1 & tmp2 == 0" { target *-*-* } cond_3 } */ + /* { dg-warning "pattern match on 'p == 0 & q == 0 == 0'" "tmp1 & tmp2 == 0" { target *-*-* } cond_3 } */ /* { dg-warning "pattern match on 'q == 0'" "q == 0" { target *-*-* } cond_3 } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/pr101962.c b/gcc/testsuite/gcc.dg/analyzer/pr101962.c index b878aad..5eb7cf0 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr101962.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr101962.c @@ -16,7 +16,7 @@ maybe_inc_int_ptr (int *ptr) int test_1 (void) { - int stack; /* { dg-message "region created on stack here" } */ + int stack; int *a = &stack; a = maybe_inc_int_ptr (a); a = maybe_inc_int_ptr (a); diff --git a/gcc/testsuite/gcc.dg/missing-header-fixit-5.c b/gcc/testsuite/gcc.dg/missing-header-fixit-5.c index 916033c..bf44feb 100644 --- a/gcc/testsuite/gcc.dg/missing-header-fixit-5.c +++ b/gcc/testsuite/gcc.dg/missing-header-fixit-5.c @@ -12,14 +12,18 @@ foo (char *m, int i) /* { dg-begin-multiline-output "" } 11 | if (isdigit (m[0])) | ^~~~~~~ + { dg-end-multiline-output "" } */ + /* { dg-begin-multiline-output "" } +++ |+#include <ctype.h> 1 | { dg-end-multiline-output "" } */ { return abs (i); /* { dg-warning "implicit declaration of function" } */ /* { dg-begin-multiline-output "" } - 19 | return abs (i); + 21 | return abs (i); | ^~~ + { dg-end-multiline-output "" } */ + /* { dg-begin-multiline-output "" } +++ |+#include <stdlib.h> 1 | { dg-end-multiline-output "" } */ @@ -27,8 +31,10 @@ foo (char *m, int i) else putchar (m[0]); /* { dg-warning "implicit declaration of function" } */ /* { dg-begin-multiline-output "" } - 28 | putchar (m[0]); + 32 | putchar (m[0]); | ^~~~~~~ + { dg-end-multiline-output "" } */ + /* { dg-begin-multiline-output "" } +++ |+#include <stdio.h> 1 | { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c index e494315..e0fc9cd 100644 --- a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c +++ b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c @@ -155,7 +155,7 @@ class double_save_thread : public gil_diagnostic return m_call == sub_other.m_call; } - bool emit (rich_location *rich_loc) final override + bool emit (rich_location *rich_loc, logger *) final override { return warning_at (rich_loc, get_controlling_option (), "nested usage of %qs", "Py_BEGIN_ALLOW_THREADS"); @@ -194,7 +194,7 @@ class fncall_without_gil : public gil_diagnostic && m_arg_idx == sub_other.m_arg_idx); } - bool emit (rich_location *rich_loc) final override + bool emit (rich_location *rich_loc, logger *) final override { auto_diagnostic_group d; if (m_callee_fndecl) @@ -245,7 +245,7 @@ class pyobject_usage_without_gil : public gil_diagnostic ((const pyobject_usage_without_gil&)base_other).m_expr); } - bool emit (rich_location *rich_loc) final override + bool emit (rich_location *rich_loc, logger *) final override { auto_diagnostic_group d; return warning_at (rich_loc, get_controlling_option (), diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-text-art-ascii-bw.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-text-art-ascii-bw.c new file mode 100644 index 0000000..e4239aa --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-text-art-ascii-bw.c @@ -0,0 +1,57 @@ +/* { dg-additional-options "-fdiagnostics-text-art-charset=ascii -fdiagnostics-color=never" } */ + +int non_empty; + +/* { dg-begin-multiline-output "" } + + A + B + C + + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + + ♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜ + ♟ ♟ ♟ ♟ ♟ ♟ ♟ ♟ + + + + + ♙ ♙ ♙ ♙ ♙ ♙ ♙ ♙ + ♖ ♘ ♗ ♕ ♔ ♗ ♘ ♖ + + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + + +--+ + |🙂| + +--+ + + { dg-end-multiline-output "" } */ +/* { dg-begin-multiline-output "" } + + +-------+-----+---------------+---------------------+-----------------------+-----------------------+ + |Offsets|Octet| 0 | 1 | 2 | 3 | + +-------+-----+-+-+-+-+-+-+-+-+-+-+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + | Octet | Bit |0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31| + +-------+-----+-+-+-+-+-+-+-+-+-+-+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + | 0 | 0 |Version| IHL | DSCP | ECN | Total Length | + +-------+-----+-------+-------+---------------+-----+--------+--------------------------------------+ + | 4 | 32 | Identification | Flags | Fragment Offset | + +-------+-----+---------------+---------------------+--------+--------------------------------------+ + | 8 | 64 | Time To Live | Protocol | Header Checksum | + +-------+-----+---------------+---------------------+-----------------------------------------------+ + | 12 | 96 | Source IP Address | + +-------+-----+-------------------------------------------------------------------------------------+ + | 16 | 128 | Destination IP Address | + +-------+-----+-------------------------------------------------------------------------------------+ + | 20 | 160 | | + +-------+-----+ | + | ... | ... | Options | + +-------+-----+ | + | 56 | 448 | | + +-------+-----+-------------------------------------------------------------------------------------+ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-text-art-ascii-color.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-text-art-ascii-color.c new file mode 100644 index 0000000..0650428 --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-text-art-ascii-color.c @@ -0,0 +1,58 @@ +/* { dg-additional-options "-fdiagnostics-text-art-charset=ascii -fdiagnostics-color=always" } */ + +int non_empty; + +/* { dg-begin-multiline-output "" } + + A + B + C + + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + + [38;2;0;0;0;48;2;240;217;181m[K♜ [38;2;0;0;0;48;2;181;136;99m[K♞ [38;2;0;0;0;48;2;240;217;181m[K♝ [38;2;0;0;0;48;2;181;136;99m[K♛ [38;2;0;0;0;48;2;240;217;181m[K♚ [38;2;0;0;0;48;2;181;136;99m[K♝ [38;2;0;0;0;48;2;240;217;181m[K♞ [38;2;0;0;0;48;2;181;136;99m[K♜ [m[K + [38;2;0;0;0;48;2;181;136;99m[K♟ [38;2;0;0;0;48;2;240;217;181m[K♟ [38;2;0;0;0;48;2;181;136;99m[K♟ [38;2;0;0;0;48;2;240;217;181m[K♟ [38;2;0;0;0;48;2;181;136;99m[K♟ [38;2;0;0;0;48;2;240;217;181m[K♟ [38;2;0;0;0;48;2;181;136;99m[K♟ [38;2;0;0;0;48;2;240;217;181m[K♟ [m[K + [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [m[K + [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [m[K + [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [m[K + [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [m[K + [38;2;255;255;255;48;2;240;217;181m[K♙ [38;2;255;255;255;48;2;181;136;99m[K♙ [38;2;255;255;255;48;2;240;217;181m[K♙ [38;2;255;255;255;48;2;181;136;99m[K♙ [38;2;255;255;255;48;2;240;217;181m[K♙ [38;2;255;255;255;48;2;181;136;99m[K♙ [38;2;255;255;255;48;2;240;217;181m[K♙ [38;2;255;255;255;48;2;181;136;99m[K♙ [m[K + [38;2;255;255;255;48;2;181;136;99m[K♖ [38;2;255;255;255;48;2;240;217;181m[K♘ [38;2;255;255;255;48;2;181;136;99m[K♗ [38;2;255;255;255;48;2;240;217;181m[K♕ [38;2;255;255;255;48;2;181;136;99m[K♔ [38;2;255;255;255;48;2;240;217;181m[K♗ [38;2;255;255;255;48;2;181;136;99m[K♘ [38;2;255;255;255;48;2;240;217;181m[K♖ [m[K + + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + + +--+ + |🙂| + +--+ + + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + + +-------+-----+---------------+---------------------+-----------------------+-----------------------+ + |Offsets|Octet| 0 | 1 | 2 | 3 | + +-------+-----+-+-+-+-+-+-+-+-+-+-+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + | Octet | Bit |0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31| + +-------+-----+-+-+-+-+-+-+-+-+-+-+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + | 0 | 0 |Version| IHL | DSCP | ECN | Total Length | + +-------+-----+-------+-------+---------------+-----+--------+--------------------------------------+ + | 4 | 32 | Identification | Flags | Fragment Offset | + +-------+-----+---------------+---------------------+--------+--------------------------------------+ + | 8 | 64 | Time To Live | Protocol | Header Checksum | + +-------+-----+---------------+---------------------+-----------------------------------------------+ + | 12 | 96 | Source IP Address | + +-------+-----+-------------------------------------------------------------------------------------+ + | 16 | 128 | Destination IP Address | + +-------+-----+-------------------------------------------------------------------------------------+ + | 20 | 160 | | + +-------+-----+ | + | ... | ... | Options | + +-------+-----+ | + | 56 | 448 | | + +-------+-----+-------------------------------------------------------------------------------------+ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-text-art-none.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-text-art-none.c new file mode 100644 index 0000000..c8118b4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-text-art-none.c @@ -0,0 +1,5 @@ +/* { dg-additional-options "-fdiagnostics-text-art-charset=none" } */ + +int non_empty; + +/* We expect no output. */ diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-text-art-unicode-bw.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-text-art-unicode-bw.c new file mode 100644 index 0000000..c9f5b36 --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-text-art-unicode-bw.c @@ -0,0 +1,58 @@ +/* { dg-additional-options "-fdiagnostics-text-art-charset=unicode -fdiagnostics-color=never" } */ + +int non_empty; + +/* { dg-begin-multiline-output "" } + + A + B + C + + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + + ♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜ + ♟ ♟ ♟ ♟ ♟ ♟ ♟ ♟ + + + + + ♙ ♙ ♙ ♙ ♙ ♙ ♙ ♙ + ♖ ♘ ♗ ♕ ♔ ♗ ♘ ♖ + + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + + ┌──┐ + │🙂│ + └──┘ + + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + + ┌───────┬─────┬───────────────┬─────────────────────┬───────────────────────┬───────────────────────┐ + │Offsets│Octet│ 0 │ 1 │ 2 │ 3 │ + ├───────┼─────┼─┬─┬─┬─┬─┬─┬─┬─┼─┬─┬──┬──┬──┬──┬──┬──┼──┬──┬──┬──┬──┬──┬──┬──┼──┬──┬──┬──┬──┬──┬──┬──┤ + │ Octet │ Bit │0│1│2│3│4│5│6│7│8│9│10│11│12│13│14│15│16│17│18│19│20│21│22│23│24│25│26│27│28│29│30│31│ + ├───────┼─────┼─┴─┴─┴─┼─┴─┴─┴─┼─┴─┴──┴──┴──┴──┼──┴──┼──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┤ + │ 0 │ 0 │Version│ IHL │ DSCP │ ECN │ Total Length │ + ├───────┼─────┼───────┴───────┴───────────────┴─────┼────────┬──────────────────────────────────────┤ + │ 4 │ 32 │ Identification │ Flags │ Fragment Offset │ + ├───────┼─────┼───────────────┬─────────────────────┼────────┴──────────────────────────────────────┤ + │ 8 │ 64 │ Time To Live │ Protocol │ Header Checksum │ + ├───────┼─────┼───────────────┴─────────────────────┴───────────────────────────────────────────────┤ + │ 12 │ 96 │ Source IP Address │ + ├───────┼─────┼─────────────────────────────────────────────────────────────────────────────────────┤ + │ 16 │ 128 │ Destination IP Address │ + ├───────┼─────┼─────────────────────────────────────────────────────────────────────────────────────┤ + │ 20 │ 160 │ │ + ├───────┼─────┤ │ + │ ... │ ... │ Options │ + ├───────┼─────┤ │ + │ 56 │ 448 │ │ + └───────┴─────┴─────────────────────────────────────────────────────────────────────────────────────┘ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-text-art-unicode-color.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-text-art-unicode-color.c new file mode 100644 index 0000000..f402836 --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-text-art-unicode-color.c @@ -0,0 +1,59 @@ +/* { dg-additional-options "-fdiagnostics-text-art-charset=unicode -fdiagnostics-color=always" } */ + +int non_empty; + + +/* { dg-begin-multiline-output "" } + + A + B + C + + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + + [38;2;0;0;0;48;2;240;217;181m[K♜ [38;2;0;0;0;48;2;181;136;99m[K♞ [38;2;0;0;0;48;2;240;217;181m[K♝ [38;2;0;0;0;48;2;181;136;99m[K♛ [38;2;0;0;0;48;2;240;217;181m[K♚ [38;2;0;0;0;48;2;181;136;99m[K♝ [38;2;0;0;0;48;2;240;217;181m[K♞ [38;2;0;0;0;48;2;181;136;99m[K♜ [m[K + [38;2;0;0;0;48;2;181;136;99m[K♟ [38;2;0;0;0;48;2;240;217;181m[K♟ [38;2;0;0;0;48;2;181;136;99m[K♟ [38;2;0;0;0;48;2;240;217;181m[K♟ [38;2;0;0;0;48;2;181;136;99m[K♟ [38;2;0;0;0;48;2;240;217;181m[K♟ [38;2;0;0;0;48;2;181;136;99m[K♟ [38;2;0;0;0;48;2;240;217;181m[K♟ [m[K + [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [m[K + [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [m[K + [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [m[K + [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [48;2;181;136;99m[K [48;2;240;217;181m[K [m[K + [38;2;255;255;255;48;2;240;217;181m[K♙ [38;2;255;255;255;48;2;181;136;99m[K♙ [38;2;255;255;255;48;2;240;217;181m[K♙ [38;2;255;255;255;48;2;181;136;99m[K♙ [38;2;255;255;255;48;2;240;217;181m[K♙ [38;2;255;255;255;48;2;181;136;99m[K♙ [38;2;255;255;255;48;2;240;217;181m[K♙ [38;2;255;255;255;48;2;181;136;99m[K♙ [m[K + [38;2;255;255;255;48;2;181;136;99m[K♖ [38;2;255;255;255;48;2;240;217;181m[K♘ [38;2;255;255;255;48;2;181;136;99m[K♗ [38;2;255;255;255;48;2;240;217;181m[K♕ [38;2;255;255;255;48;2;181;136;99m[K♔ [38;2;255;255;255;48;2;240;217;181m[K♗ [38;2;255;255;255;48;2;181;136;99m[K♘ [38;2;255;255;255;48;2;240;217;181m[K♖ [m[K + + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + + ┌──┐ + │🙂│ + └──┘ + + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + + ┌───────┬─────┬───────────────┬─────────────────────┬───────────────────────┬───────────────────────┐ + │Offsets│Octet│ 0 │ 1 │ 2 │ 3 │ + ├───────┼─────┼─┬─┬─┬─┬─┬─┬─┬─┼─┬─┬──┬──┬──┬──┬──┬──┼──┬──┬──┬──┬──┬──┬──┬──┼──┬──┬──┬──┬──┬──┬──┬──┤ + │ Octet │ Bit │0│1│2│3│4│5│6│7│8│9│10│11│12│13│14│15│16│17│18│19│20│21│22│23│24│25│26│27│28│29│30│31│ + ├───────┼─────┼─┴─┴─┴─┼─┴─┴─┴─┼─┴─┴──┴──┴──┴──┼──┴──┼──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┤ + │ 0 │ 0 │Version│ IHL │ DSCP │ ECN │ Total Length │ + ├───────┼─────┼───────┴───────┴───────────────┴─────┼────────┬──────────────────────────────────────┤ + │ 4 │ 32 │ Identification │ Flags │ Fragment Offset │ + ├───────┼─────┼───────────────┬─────────────────────┼────────┴──────────────────────────────────────┤ + │ 8 │ 64 │ Time To Live │ Protocol │ Header Checksum │ + ├───────┼─────┼───────────────┴─────────────────────┴───────────────────────────────────────────────┤ + │ 12 │ 96 │ Source IP Address │ + ├───────┼─────┼─────────────────────────────────────────────────────────────────────────────────────┤ + │ 16 │ 128 │ Destination IP Address │ + ├───────┼─────┼─────────────────────────────────────────────────────────────────────────────────────┤ + │ 20 │ 160 │ │ + ├───────┼─────┤ │ + │ ... │ ... │ Options │ + ├───────┼─────┤ │ + │ 56 │ 448 │ │ + └───────┴─────┴─────────────────────────────────────────────────────────────────────────────────────┘ + + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_text_art.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_text_art.c new file mode 100644 index 0000000..58b219b --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_text_art.c @@ -0,0 +1,258 @@ +/* { dg-options "-O" } */ + +/* This plugin exercises the text_art code. */ + +#define INCLUDE_VECTOR +#include "gcc-plugin.h" +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "plugin-version.h" +#include "diagnostic.h" +#include "diagnostic-diagram.h" +#include "text-art/canvas.h" +#include "text-art/table.h" + +int plugin_is_GPL_compatible; + +using namespace text_art; + +/* Canvas tests. */ + +static void +emit_canvas (const canvas &c, const char *alt_text) +{ + diagnostic_diagram diagram (c, alt_text); + diagnostic_emit_diagram (global_dc, diagram); +} + +static void +test_abc () +{ + style_manager sm; + canvas c (canvas::size_t (3, 3), sm); + c.paint (canvas::coord_t (0, 0), styled_unichar ('A')); + c.paint (canvas::coord_t (1, 1), styled_unichar ('B')); + c.paint (canvas::coord_t (2, 2), styled_unichar ('C')); + emit_canvas (c, "test_abc"); +} + +/* Test of procedural art using 24-bit color: chess starting position. */ + +static void +test_chessboard () +{ + /* With the exception of NONE, these are in order of the chess symbols + in the Unicode Miscellaneous Symbols block. */ + enum class piece { KING, QUEEN, ROOK, BISHOP, KNIGHT, PAWN, NONE }; + enum class color { BLACK, WHITE, NONE }; + + style_manager sm; + + /* We assume double-column chars for the pieces, so allow two canvas + columns per square. */ + canvas canvas (canvas::size_t (16, 8), sm); + + for (int x = 0; x < 8; x++) + for (int y = 0; y < 8; y++) + { + enum piece piece_kind; + enum color piece_color; + switch (y) + { + case 0: + case 7: + switch (x) + { + default: + gcc_unreachable (); + case 0: + piece_kind = piece::ROOK; + break; + case 1: + piece_kind = piece::KNIGHT; + break; + case 2: + piece_kind = piece::BISHOP; + break; + case 3: + piece_kind = piece::QUEEN; + break; + case 4: + piece_kind = piece::KING; + break; + case 5: + piece_kind = piece::BISHOP; + break; + case 6: + piece_kind = piece::KNIGHT; + break; + case 7: + piece_kind = piece::ROOK; + break; + } + piece_color = (y == 0) ? color::BLACK : color::WHITE; + break; + case 1: + case 6: + piece_kind = piece::PAWN; + piece_color = (y == 1) ? color::BLACK : color::WHITE; + break; + default: + piece_kind = piece::NONE; + piece_color = color::NONE; + break; + } + + style s; + const bool white_square = (x + y) % 2 == 0; + if (white_square) + s.m_bg_color = style::color (0xf0, 0xd9, 0xb5); + else + s.m_bg_color = style::color (0xb5, 0x88, 0x63); + switch (piece_color) + { + default: + gcc_unreachable (); + case color::WHITE: + s.m_fg_color = style::color (0xff, 0xff, 0xff); + break; + case color::BLACK: + s.m_fg_color = style::color (0x00, 0x00, 0x00); + break; + case color::NONE: + break; + } + style::id_t style_id = sm.get_or_create_id (s); + + cppchar_t ch; + if (piece_kind == piece::NONE) + ch = ' '; + else + { + const cppchar_t WHITE_KING = 0x2654; + const cppchar_t BLACK_KING = 0x265A; + cppchar_t base ((piece_color == color::WHITE) + ? WHITE_KING : BLACK_KING); + ch = base + ((int)piece_kind - (int)piece::KING); + } + canvas.paint (canvas::coord_t (x * 2, y), + canvas::cell_t (ch, false, style_id)); + canvas.paint (canvas::coord_t (x * 2 + 1, y), + canvas::cell_t (' ', false, style_id)); + } + emit_canvas (canvas, "test_chessboard"); +} + +/* Table tests. */ + +static void +emit_table (const table &table, const style_manager &sm, const char *alt_text) +{ + const text_art::theme *theme = global_dc->m_diagrams.m_theme; + if (!theme) + return; + canvas c (table.to_canvas (*theme, sm)); + emit_canvas (c, alt_text); +} + +static void +test_double_width_chars () +{ + style_manager sm; + table table (table::size_t (1, 1)); + table.set_cell (table::coord_t (0,0), + styled_string ((cppchar_t)0x1f642)); + + emit_table (table, sm, "test_double_width_chars"); +} + +static void +test_ipv4_header () +{ + style_manager sm; + table table (table::size_t (34, 10)); + table.set_cell (table::coord_t (0, 0), styled_string (sm, "Offsets")); + table.set_cell (table::coord_t (1, 0), styled_string (sm, "Octet")); + table.set_cell (table::coord_t (0, 1), styled_string (sm, "Octet")); + for (int octet = 0; octet < 4; octet++) + table.set_cell_span (table::rect_t (table::coord_t (2 + (octet * 8), 0), + table::size_t (8, 1)), + styled_string::from_fmt (sm, nullptr, "%i", octet)); + table.set_cell (table::coord_t (1, 1), styled_string (sm, "Bit")); + for (int bit = 0; bit < 32; bit++) + table.set_cell (table::coord_t (bit + 2, 1), + styled_string::from_fmt (sm, nullptr, "%i", bit)); + for (int word = 0; word < 6; word++) + { + table.set_cell (table::coord_t (0, word + 2), + styled_string::from_fmt (sm, nullptr, "%i", word * 4)); + table.set_cell (table::coord_t (1, word + 2), + styled_string::from_fmt (sm, nullptr, "%i", word * 32)); + } + + table.set_cell (table::coord_t (0, 8), styled_string (sm, "...")); + table.set_cell (table::coord_t (1, 8), styled_string (sm, "...")); + table.set_cell (table::coord_t (0, 9), styled_string (sm, "56")); + table.set_cell (table::coord_t (1, 9), styled_string (sm, "448")); + +#define SET_BITS(FIRST, LAST, NAME) \ + do { \ + const int first = (FIRST); \ + const int last = (LAST); \ + const char *name = (NAME); \ + const int row = first / 32; \ + gcc_assert (last / 32 == row); \ + table::rect_t rect (table::coord_t ((first % 32) + 2, row + 2), \ + table::size_t (last + 1 - first , 1)); \ + table.set_cell_span (rect, styled_string (sm, name)); \ + } while (0) + + SET_BITS (0, 3, "Version"); + SET_BITS (4, 7, "IHL"); + SET_BITS (8, 13, "DSCP"); + SET_BITS (14, 15, "ECN"); + SET_BITS (16, 31, "Total Length"); + + SET_BITS (32 + 0, 32 + 15, "Identification"); + SET_BITS (32 + 16, 32 + 18, "Flags"); + SET_BITS (32 + 19, 32 + 31, "Fragment Offset"); + + SET_BITS (64 + 0, 64 + 7, "Time To Live"); + SET_BITS (64 + 8, 64 + 15, "Protocol"); + SET_BITS (64 + 16, 64 + 31, "Header Checksum"); + + SET_BITS (96 + 0, 96 + 31, "Source IP Address"); + SET_BITS (128 + 0, 128 + 31, "Destination IP Address"); + + table.set_cell_span(table::rect_t (table::coord_t (2, 7), + table::size_t (32, 3)), + styled_string (sm, "Options")); + + emit_table (table, sm, "test_ipv4_header"); +} + +static void +show_diagrams () +{ + test_abc (); + test_chessboard (); + test_double_width_chars (); + test_ipv4_header (); +} + +int +plugin_init (struct plugin_name_args *plugin_info, + struct plugin_gcc_version *version) +{ + const char *plugin_name = plugin_info->base_name; + int argc = plugin_info->argc; + struct plugin_argument *argv = plugin_info->argv; + + if (!plugin_default_version_check (version, &gcc_version)) + return 1; + + show_diagrams (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp index 4d6304c..60723a2 100644 --- a/gcc/testsuite/gcc.dg/plugin/plugin.exp +++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp @@ -114,6 +114,12 @@ set plugin_test_list [list \ diagnostic-path-format-inline-events-1.c \ diagnostic-path-format-inline-events-2.c \ diagnostic-path-format-inline-events-3.c } \ + { diagnostic_plugin_test_text_art.c \ + diagnostic-test-text-art-none.c \ + diagnostic-test-text-art-ascii-bw.c \ + diagnostic-test-text-art-ascii-color.c \ + diagnostic-test-text-art-unicode-bw.c \ + diagnostic-test-text-art-unicode-color.c } \ { location_overflow_plugin.c \ location-overflow-test-1.c \ location-overflow-test-2.c \ diff --git a/gcc/testsuite/gcc.dg/torture/pr110332-1.c b/gcc/testsuite/gcc.dg/torture/pr110332-1.c new file mode 100644 index 0000000..438993e --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr110332-1.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +struct s { int lie; }; +struct s si7, si8; +unsigned u9, u6; +_Bool b3, b4; +unsigned transferValues(struct s *End) { + unsigned RegIdx; + unsigned *t = b4 ? &u6 : &u9; + RegIdx = *t; + *End = *(b3 ? &si7 : &si8); + return RegIdx; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr110332-2.c b/gcc/testsuite/gcc.dg/torture/pr110332-2.c new file mode 100644 index 0000000..18b656f --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr110332-2.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ + +_Bool a; +struct s { int t; } c, d; +unsigned e, f; +unsigned transferValues(struct s *End) { + unsigned RegIdx = *(a ? &e : &f); + *End = *(a ? &c : &d); + return RegIdx; +} diff --git a/gcc/testsuite/gcc.dg/vect/pr110381.c b/gcc/testsuite/gcc.dg/vect/pr110381.c new file mode 100644 index 0000000..2313dbf --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr110381.c @@ -0,0 +1,40 @@ +/* { dg-do run } */ + +struct FOO { + double a; + double b; + double c; +}; + +double __attribute__((noipa)) +sum_8_foos(const struct FOO* foos) +{ + double sum = 0; + + for (int i = 0; i < 8; ++i) + { + struct FOO foo = foos[i]; + + /* Need to use an in-order reduction here, preserving + the load permutation. */ + sum += foo.a; + sum += foo.c; + sum += foo.b; + } + + return sum; +} + +int main() +{ + struct FOO foos[8]; + + __builtin_memset (foos, 0, sizeof (foos)); + foos[0].a = __DBL_MAX__; + foos[0].b = 5; + foos[0].c = -__DBL_MAX__; + + if (sum_8_foos (foos) != 5) + __builtin_abort (); + return 0; +} |