@@ -362,6 +362,10 @@ ubsan_instrument_bounds (location_t loc, tree array, tree *index,
{
tree type = TREE_TYPE (array);
tree domain = TYPE_DOMAIN (type);
+ /* whether the array ref is a flexible array member with valid element_count
+ attribute. */
+ bool fam_has_count_attr = false;
+ tree element_count = NULL_TREE;
if (domain == NULL_TREE)
return NULL_TREE;
@@ -375,6 +379,17 @@ ubsan_instrument_bounds (location_t loc, tree array, tree *index,
&& COMPLETE_TYPE_P (type)
&& integer_zerop (TYPE_SIZE (type)))
bound = build_int_cst (TREE_TYPE (TYPE_MIN_VALUE (domain)), -1);
+ /* If the array ref is to flexible array member field which has
+ element_count attribute. We can use the information from the
+ attribute as the bound to instrument the reference. */
+ else if ((element_count = component_ref_get_element_count (array))
+ != NULL_TREE)
+ {
+ fam_has_count_attr = true;
+ bound = fold_build2 (MINUS_EXPR, TREE_TYPE (element_count),
+ element_count,
+ build_int_cst (TREE_TYPE (element_count), 1));
+ }
else
return NULL_TREE;
}
@@ -387,6 +402,7 @@ ubsan_instrument_bounds (location_t loc, tree array, tree *index,
-fsanitize=bounds-strict. */
tree base = get_base_address (array);
if (!sanitize_flags_p (SANITIZE_BOUNDS_STRICT)
+ && !fam_has_count_attr
&& TREE_CODE (array) == COMPONENT_REF
&& base && (INDIRECT_REF_P (base) || TREE_CODE (base) == MEM_REF))
{
new file mode 100644
@@ -0,0 +1,46 @@
+/* test the attribute element_count and its usage in
+ bounds sanitizer. */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds" } */
+
+#include <stdlib.h>
+
+struct flex {
+ int b;
+ int c[];
+} *array_flex;
+
+struct annotated {
+ int b;
+ int c[] __attribute__ ((element_count ("b")));
+} *array_annotated;
+
+void __attribute__((__noinline__)) setup (int normal_count, int annotated_count)
+{
+ array_flex
+ = (struct flex *)malloc (sizeof (struct flex)
+ + normal_count * sizeof (int));
+ array_flex->b = normal_count;
+
+ array_annotated
+ = (struct annotated *)malloc (sizeof (struct annotated)
+ + annotated_count * sizeof (int));
+ array_annotated->b = annotated_count;
+
+ return;
+}
+
+void __attribute__((__noinline__)) test (int normal_index, int annotated_index)
+{
+ array_flex->c[normal_index] = 1;
+ array_annotated->c[annotated_index] = 2;
+}
+
+int main(int argc, char *argv[])
+{
+ setup (10,10);
+ test (10,10);
+ return 0;
+}
+
+/* { dg-output "36:21: runtime error: index 10 out of bounds for type" } */