ELEMENT_SIZE:
(sizetype) SAVE_EXPR <n> * 4
get the index as (long unsigned int) m, and return it.
+ One special case is when the OFFSET is an integer constant, and the
+ element_size is also an integer constant, we should get the index
+ as OFFSET/element_size.
The INDEX_P holds the pointer to the parent tree of the index,
INDEX_N holds the position of the index in its parent. */
get_index_from_offset (tree offset, tree *index_p,
int *index_n, tree element_size)
{
- if (TREE_CODE (offset) != MULT_EXPR)
+ if (TREE_CODE (offset) != MULT_EXPR
+ && TREE_CODE (offset) != INTEGER_CST)
return NULL_TREE;
+ if (TREE_CODE (offset) == INTEGER_CST
+ && TREE_CODE (element_size) != INTEGER_CST)
+ return NULL_TREE;
+
+ if (TREE_CODE (offset) == INTEGER_CST
+ && TREE_CODE (element_size) == INTEGER_CST)
+ return fold_build2 (EXACT_DIV_EXPR, TREE_TYPE (offset),
+ offset, element_size);
+
auto_vec<factor_t> e_factors, o_factors;
get_factors_from_mul_expr (element_size, NULL, -1, &e_factors);
get_factors_from_mul_expr (offset, *index_p, *index_n, &o_factors);
--- /dev/null
+/* Test the attribute counted_by for pointer fields and its usage in
+ bounds sanitizer. */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds" } */
+/* { dg-output "index 10 out of bounds for type 'char \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*index 11 out of bounds for type 'char \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+
+#define PTR_TYPE char
+#include "pointer-counted-by-bounds-124230.c"
--- /dev/null
+/* Test the attribute counted_by for pointer fields and its usage in
+ bounds sanitizer. */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds" } */
+/* { dg-output "index 10 out of bounds for type 'float \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*index 11 out of bounds for type 'float \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+
+#define PTR_TYPE float
+#include "pointer-counted-by-bounds-124230.c"
--- /dev/null
+/* Test the attribute counted_by for pointer fields and its usage in
+ bounds sanitizer. */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds" } */
+/* { dg-output "index 10 out of bounds for type 'A \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*index 11 out of bounds for type 'A \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+
+#include <stdlib.h>
+
+struct A {
+ int a;
+ char *b;
+};
+#define PTR_TYPE struct A
+struct annotated {
+ int b;
+ PTR_TYPE *c __attribute__ ((counted_by (b)));
+} *p_array_annotated;
+
+struct nested_annotated {
+ PTR_TYPE *c __attribute__ ((counted_by (b)));
+ struct {
+ union {
+ int b;
+ float f;
+ };
+ int n;
+ };
+} *p_array_nested_annotated;
+
+void __attribute__((__noinline__)) setup (int annotated_count)
+{
+ p_array_annotated
+ = (struct annotated *) malloc (sizeof (struct annotated));
+ p_array_annotated->c = (PTR_TYPE *) malloc (annotated_count * sizeof (PTR_TYPE));
+ p_array_annotated->b = annotated_count;
+
+ p_array_nested_annotated
+ = (struct nested_annotated *) malloc (sizeof (struct nested_annotated));
+ p_array_nested_annotated->c = (PTR_TYPE *) malloc (sizeof (PTR_TYPE) * annotated_count);
+ p_array_nested_annotated->b = annotated_count;
+
+ return;
+}
+
+void cleanup ()
+{
+ free (p_array_annotated->c);
+ free (p_array_annotated);
+ free (p_array_nested_annotated->c);
+ free (p_array_nested_annotated);
+}
+
+int main(int argc, char *argv[])
+{
+ setup (10);
+ p_array_annotated->c[10].a = 2;
+ p_array_nested_annotated->c[11].a = 3;
+ cleanup ();
+ return 0;
+}
--- /dev/null
+/* Test the attribute counted_by for pointer fields and its usage in
+ bounds sanitizer. */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds" } */
+/* { dg-output "index 10 out of bounds for type 'A \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*index 11 out of bounds for type 'A \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+
+#include <stdlib.h>
+
+union A {
+ int a;
+ float b;
+};
+#define PTR_TYPE union A
+struct annotated {
+ int b;
+ PTR_TYPE *c __attribute__ ((counted_by (b)));
+} *p_array_annotated;
+
+struct nested_annotated {
+ PTR_TYPE *c __attribute__ ((counted_by (b)));
+ struct {
+ union {
+ int b;
+ float f;
+ };
+ int n;
+ };
+} *p_array_nested_annotated;
+
+void __attribute__((__noinline__)) setup (int annotated_count)
+{
+ p_array_annotated
+ = (struct annotated *) malloc (sizeof (struct annotated));
+ p_array_annotated->c = (PTR_TYPE *) malloc (annotated_count * sizeof (PTR_TYPE));
+ p_array_annotated->b = annotated_count;
+
+ p_array_nested_annotated
+ = (struct nested_annotated *) malloc (sizeof (struct nested_annotated));
+ p_array_nested_annotated->c = (PTR_TYPE *) malloc (sizeof (PTR_TYPE) * annotated_count);
+ p_array_nested_annotated->b = annotated_count;
+
+ return;
+}
+
+void cleanup ()
+{
+ free (p_array_annotated->c);
+ free (p_array_annotated);
+ free (p_array_nested_annotated->c);
+ free (p_array_nested_annotated);
+}
+
+int main(int argc, char *argv[])
+{
+ setup (10);
+ p_array_annotated->c[10].a = 2;
+ p_array_nested_annotated->c[11].a = 3;
+ cleanup ();
+ return 0;
+}
--- /dev/null
+/* Test the attribute counted_by for pointer fields and its usage in
+ bounds sanitizer. */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds" } */
+/* { dg-output "index 10 out of bounds for type 'int \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*index 11 out of bounds for type 'int \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+
+#include <stdlib.h>
+
+#ifndef PTR_TYPE
+#define PTR_TYPE int
+#endif
+struct annotated {
+ int b;
+ PTR_TYPE *c __attribute__ ((counted_by (b)));
+} *p_array_annotated;
+
+struct nested_annotated {
+ PTR_TYPE *c __attribute__ ((counted_by (b)));
+ struct {
+ union {
+ int b;
+ float f;
+ };
+ int n;
+ };
+} *p_array_nested_annotated;
+
+void __attribute__((__noinline__)) setup (int annotated_count)
+{
+ p_array_annotated
+ = (struct annotated *) malloc (sizeof (struct annotated));
+ p_array_annotated->c = (PTR_TYPE *) malloc (annotated_count * sizeof (PTR_TYPE));
+ p_array_annotated->b = annotated_count;
+
+ p_array_nested_annotated
+ = (struct nested_annotated *) malloc (sizeof (struct nested_annotated));
+ p_array_nested_annotated->c = (PTR_TYPE *) malloc (sizeof (PTR_TYPE) * annotated_count);
+ p_array_nested_annotated->b = annotated_count;
+
+ return;
+}
+
+void cleanup ()
+{
+ free (p_array_annotated->c);
+ free (p_array_annotated);
+ free (p_array_nested_annotated->c);
+ free (p_array_nested_annotated);
+}
+
+int main(int argc, char *argv[])
+{
+ setup (10);
+ p_array_annotated->c[10] = 2;
+ p_array_nested_annotated->c[11] = 3;
+ cleanup ();
+ return 0;
+}