}
protected:
+ /* Potentially add a note about valid ways to index this array, such
+ as (given "int arr[10];"):
+ note: valid subscripts for 'arr' are '[0]' to '[9]'
+ We print the '[' and ']' characters so as to express the valid
+ subscripts using C syntax, rather than just as byte ranges,
+ which hopefully is more clear to the user. */
+ void
+ maybe_describe_array_bounds (location_t loc) const
+ {
+ if (!m_diag_arg)
+ return;
+ tree t = TREE_TYPE (m_diag_arg);
+ if (!t)
+ return;
+ if (TREE_CODE (t) != ARRAY_TYPE)
+ return;
+ tree domain = TYPE_DOMAIN (t);
+ if (!domain)
+ return;
+ tree max_idx = TYPE_MAX_VALUE (domain);
+ if (!max_idx)
+ return;
+ tree min_idx = TYPE_MIN_VALUE (domain);
+ inform (loc,
+ "valid subscripts for %qE are %<[%E]%> to %<[%E]%>",
+ m_diag_arg, min_idx, max_idx);
+ }
+
const region *m_reg;
tree m_diag_arg;
byte_range m_out_of_bounds_range;
inform (rich_loc->get_loc (),
"write to beyond the end of %qE",
m_diag_arg);
+
+ maybe_describe_array_bounds (rich_loc->get_loc ());
}
return warned;
inform (rich_loc->get_loc (),
"read from after the end of %qE",
m_diag_arg);
+
+ maybe_describe_array_bounds (rich_loc->get_loc ());
}
return warned;
{
diagnostic_metadata m;
m.add_cwe (124);
- return warning_meta (rich_loc, m, get_controlling_option (),
- "buffer underflow");
+ bool warned = warning_meta (rich_loc, m, get_controlling_option (),
+ "buffer underflow");
+ if (warned)
+ maybe_describe_array_bounds (rich_loc->get_loc ());
+ return warned;
}
label_text describe_final_event (const evdesc::final_event &ev)
{
diagnostic_metadata m;
m.add_cwe (127);
- return warning_meta (rich_loc, m, get_controlling_option (),
- "buffer underread");
+ bool warned = warning_meta (rich_loc, m, get_controlling_option (),
+ "buffer underread");
+ if (warned)
+ maybe_describe_array_bounds (rich_loc->get_loc ());
+ return warned;
}
label_text describe_final_event (const evdesc::final_event &ev)
__analyzer_eval (*returns_element_ptr (1) == 8); /* { dg-warning "TRUE" } */
__analyzer_eval (*returns_element_ptr (2) == 9); /* { dg-warning "TRUE" } */
return *returns_element_ptr (3); /* { dg-warning "buffer overread" } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[2\\\]'" "valid subscript note" { target *-*-* } .-1 } */
}
int returns_offset (int arr[3], int i)
id_sequence[2] = 345;
id_sequence[3] = 456; /* { dg-line test1 } */
- /* { dg-warning "overflow" "warning" { target *-*-* } test1 } */
- /* { dg-message "" "note" { target *-*-* } test1 } */
+ /* { dg-warning "stack-based buffer overflow" "warning" { target *-*-* } test1 } */
+ /* { dg-message "write of 4 bytes to beyond the end of 'id_sequence'" "num bad bytes note" { target *-*-* } test1 } */
+ /* { dg-message "valid subscripts for 'id_sequence' are '\\\[0\\\]' to '\\\[2\\\]'" "valid subscript note" { target *-*-* } test1 } */
}
void test2 (void)
for (int i = n; i >= 0; i--)
arr[i] = i; /* { dg-line test3 } */
- /* { dg-warning "overflow" "warning" { target *-*-* } test3 } */
- /* { dg-message "" "note" { target *-*-* } test3 } */
+ /* { dg-warning "stack-based buffer overflow" "warning" { target *-*-* } test3 } */
+ /* { dg-message "write of 4 bytes to beyond the end of 'arr'" "num bad bytes note" { target *-*-* } test3 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[3\\\]'" "valid subscript note" { target *-*-* } test3 } */
}
void test4 (void)
*last_el = 4; /* { dg-line test5 } */
free (arr);
- /* { dg-warning "overflow" "warning" { target *-*-* } test5 } */
+ /* { dg-warning "heap-based buffer overflow" "warning" { target *-*-* } test5 } */
/* { dg-message "" "note" { target *-*-* } test5 } */
}
printf ("x=%d y=%d *p=%d *q=%d\n" , x, y, *p, *q); /* { dg-line test6c } */
}
- /* { dg-warning "overflow" "warning" { target *-*-* } test6b } */
+ /* { dg-warning "buffer overflow" "warning" { target *-*-* } test6b } */
/* { dg-message "" "note" { target *-*-* } test6b } */
- /* { dg-warning "overread" "warning" { target *-*-* } test6c } */
+ /* { dg-warning "buffer overread" "warning" { target *-*-* } test6c } */
/* { dg-message "" "note" { target *-*-* } test6c } */
}
{
arr[-100] = x; /* { dg-warning "buffer underflow" "warning" } */
/* { dg-message "out-of-bounds write at byte -100 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 } */
}
void int_arr_write_element_before_start_near(char x)
{
arr[-2] = x; /* { dg-warning "buffer underflow" "warning" } */
/* { dg-message "out-of-bounds write at byte -2 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 } */
}
void int_arr_write_element_before_start_off_by_one(char x)
{
arr[-1] = x; /* { dg-warning "buffer underflow" "warning" } */
/* { dg-message "out-of-bounds write at byte -1 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 } */
}
void int_arr_write_element_at_start(char x)
arr[10] = x; /* { dg-warning "buffer overflow" "warning" } */
/* { dg-message "out-of-bounds write at byte 10 but 'arr' ends at byte 10" "final event" { target *-*-* } .-1 } */
/* { dg-message "write of 1 byte to beyond the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
}
void int_arr_write_element_after_end_near(char x)
arr[11] = x; /* { dg-warning "buffer overflow" "warning" } */
/* { dg-message "out-of-bounds write at byte 11 but 'arr' ends at byte 10" "final event" { target *-*-* } .-1 } */
/* { dg-message "write of 1 byte to beyond the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
}
void int_arr_write_element_after_end_far(char x)
arr[100] = x; /* { dg-warning "buffer overflow" "warning" } */
/* { dg-message "out-of-bounds write at byte 100 but 'arr' ends at byte 10" "final event" { target *-*-* } .-1 } */
/* { dg-message "write of 1 byte to beyond the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
}
{
arr[-100] = x; /* { dg-warning "buffer underflow" "warning" } */
/* { dg-message "out-of-bounds write from byte -400 till byte -397 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 } */
}
void int_arr_write_element_before_start_near(int32_t x)
{
arr[-2] = x; /* { dg-warning "buffer underflow" "warning" } */
/* { dg-message "out-of-bounds write from byte -8 till byte -5 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 } */
}
void int_arr_write_element_before_start_off_by_one(int32_t x)
{
arr[-1] = x; /* { dg-warning "buffer underflow" "warning" } */
/* { dg-message "out-of-bounds write from byte -4 till byte -1 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 } */
}
void int_arr_write_element_at_start(int32_t x)
arr[10] = x; /* { dg-warning "buffer overflow" "warning" } */
/* { dg-message "out-of-bounds write from byte 40 till byte 43 but 'arr' ends at byte 40" "final event" { target *-*-* } .-1 } */
/* { dg-message "write of 4 bytes to beyond the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
}
void int_arr_write_element_after_end_near(int32_t x)
arr[11] = x; /* { dg-warning "buffer overflow" "warning" } */
/* { dg-message "out-of-bounds write from byte 44 till byte 47 but 'arr' ends at byte 40" "final event" { target *-*-* } .-1 } */
/* { dg-message "write of 4 bytes to beyond the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
}
void int_arr_write_element_after_end_far(int32_t x)
arr[100] = x; /* { dg-warning "buffer overflow" "warning" } */
/* { dg-message "out-of-bounds write from byte 400 till byte 403 but 'arr' ends at byte 40" "final event" { target *-*-* } .-1 } */
/* { dg-message "write of 4 bytes to beyond the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
}