bound = fold_build2 (PLUS_EXPR, TREE_TYPE (bound), bound,
build_int_cst (TREE_TYPE (bound),
- 1 + ignore_off_by_one));
+ 1 + ignore_off_by_one));
/* Detect flexible array members and suchlike, unless
-fsanitize=bounds-strict. */
return NULL_TREE;
*index = save_expr (*index);
- /* Create a "(T *) 0" tree node to describe the array type. */
- tree zero_with_type = build_int_cst (build_pointer_type (type), 0);
+ /* If TYPE is a VLA, use 1 instead of 0 as the first argument and
+ use just the addend to TYPE_MAX_VALUE (domain) as the third argument
+ temporarily, so that gimplification can use TYPE_MAX_VALUE (domain)
+ after gimplify_type_sizes. See PR120052. */
+ bool is_vla = (TYPE_MAX_VALUE (domain)
+ && TREE_CODE (TYPE_MAX_VALUE (domain)) != INTEGER_CST);
+ if (is_vla)
+ bound = build_int_cst (TREE_TYPE (bound), 1 + ignore_off_by_one);
+ /* Create a "(T *) 0" (or 1) tree node to describe the array type. */
+ tree zero_with_type = build_int_cst (build_pointer_type (type), is_vla);
return build_call_expr_internal_loc (loc, IFN_UBSAN_BOUNDS,
void_type_node, 3, zero_with_type,
*index, bound);
*expr_p = NULL_TREE;
return GS_ALL_DONE;
}
+ else if (ifn == IFN_UBSAN_BOUNDS
+ && nargs == 3
+ && integer_onep (CALL_EXPR_ARG (*expr_p, 0)))
+ {
+ /* If first argument is one, add TYPE_MAX_VALUE (TYPE_DOMAIN (t))
+ to 3rd argument and change first argument to 0. This is
+ done by ubsan_instrument_bounds so that we can use the
+ max value from gimplify_type_sizes here instead of original
+ expression for VLAs. */
+ tree type = TREE_TYPE (CALL_EXPR_ARG (*expr_p, 0));
+ CALL_EXPR_ARG (*expr_p, 0) = build_int_cst (type, 0);
+ gcc_assert (TREE_CODE (type) == POINTER_TYPE);
+ type = TREE_TYPE (type);
+ gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
+ tree maxv = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
+ gcc_assert (maxv);
+ tree arg3 = CALL_EXPR_ARG (*expr_p, 2);
+ CALL_EXPR_ARG (*expr_p, 2)
+ = fold_build2 (PLUS_EXPR, TREE_TYPE (arg3), maxv, arg3);
+ }
for (i = 0; i < nargs; i++)
{
--- /dev/null
+/* PR middle-end/120052 */
+/* { dg-do compile } */
+/* { dg-additional-options "-fsanitize=undefined" } */
+
+void
+foo (unsigned long s, long indx)
+{
+ long counts[2][s];
+ #pragma omp parallel
+ #pragma omp masked
+ for (int i = 0; i < 2; i++)
+ counts[2][indx] = 1;
+}
+
+void
+bar (unsigned long s, long indx)
+{
+ long counts[2][s];
+ #pragma omp parallel shared(counts)
+ #pragma omp masked
+ for (int i = 0; i < 2; i++)
+ counts[2][indx] = 1;
+}
+
+void
+baz (unsigned long s, long indx)
+{
+ long counts[2][s];
+ #pragma omp parallel private(counts)
+ for (int i = 0; i < 2; i++)
+ counts[2][indx] = 1;
+}