diff options
Diffstat (limited to 'gcc/testsuite/gcc.dg/analyzer')
25 files changed, 1045 insertions, 10 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); |