Resolves:
PR tree-optimization/102759 - ICE: Segmentation fault in maybe_check_access_sizes since
r12-2976-gb48d4e6818674898
gcc/ChangeLog:
PR tree-optimization/102759
* gimple-array-bounds.cc (build_printable_array_type): Move...
* gimple-ssa-warn-access.cc (build_printable_array_type): Avoid
pathological function redeclarations that remove a previously
declared prototype.
Improve formatting of function arguments in informational notes.
* pointer-query.cc (build_printable_array_type): ...to here.
* pointer-query.h (build_printable_array_type): Declared.
gcc/testsuite/ChangeLog:
PR tree-optimization/102759
* gcc.dg/Warray-parameter-10.c: New test.
* gcc.dg/Wstringop-overflow-82.c: New test.
return warned;
}
-/* Wrapper around build_array_type_nelts that makes sure the array
- can be created at all and handles zero sized arrays specially. */
-
-static tree
-build_printable_array_type (tree eltype, unsigned HOST_WIDE_INT nelts)
-{
- if (TYPE_SIZE_UNIT (eltype)
- && TREE_CODE (TYPE_SIZE_UNIT (eltype)) == INTEGER_CST
- && !integer_zerop (TYPE_SIZE_UNIT (eltype))
- && TYPE_ALIGN_UNIT (eltype) > 1
- && wi::zext (wi::to_wide (TYPE_SIZE_UNIT (eltype)),
- ffs_hwi (TYPE_ALIGN_UNIT (eltype)) - 1) != 0)
- eltype = TYPE_MAIN_VARIANT (eltype);
-
- if (nelts)
- return build_array_type_nelts (eltype, nelts);
-
- tree idxtype = build_range_type (sizetype, size_zero_node, NULL_TREE);
- tree arrtype = build_array_type (eltype, idxtype);
- arrtype = build_distinct_type_copy (TYPE_MAIN_VARIANT (arrtype));
- TYPE_SIZE (arrtype) = bitsize_zero_node;
- TYPE_SIZE_UNIT (arrtype) = size_zero_node;
- return arrtype;
-}
-
/* Checks one MEM_REF in REF, located at LOCATION, for out-of-bounds
references to string constants. If VRP can determine that the array
subscript is a constant, check if it is outside valid range.
continue;
tree ptrtype = fntype_argno_type (fntype, ptridx);
+ if (!ptrtype)
+ /* A function with a prototype was redeclared without one and
+ the protype has been lost. See pr102759. Avoid dealing
+ with this pathological case. */
+ return;
+
tree argtype = TREE_TYPE (ptrtype);
- /* The size of the access by the call. */
- tree access_size;
+ /* The size of the access by the call in elements. */
+ tree access_nelts;
if (sizidx == -1)
{
/* If only the pointer attribute operand was specified and
if the pointer is also declared with attribute nonnull. */
if (access.second.minsize
&& access.second.minsize != HOST_WIDE_INT_M1U)
- access_size = build_int_cstu (sizetype, access.second.minsize);
+ access_nelts = build_int_cstu (sizetype, access.second.minsize);
else
- access_size = size_one_node;
+ access_nelts = size_one_node;
}
else
- access_size = rwm->get (sizidx)->size;
+ access_nelts = rwm->get (sizidx)->size;
/* Format the value or range to avoid an explosion of messages. */
char sizstr[80];
tree sizrng[2] = { size_zero_node, build_all_ones_cst (sizetype) };
- if (get_size_range (m_ptr_qry.rvals, access_size, stmt, sizrng, 1))
+ if (get_size_range (m_ptr_qry.rvals, access_nelts, stmt, sizrng, 1))
{
char *s0 = print_generic_expr_to_str (sizrng[0]);
if (tree_int_cst_equal (sizrng[0], sizrng[1]))
}
}
+ /* The size of the access by the call in bytes. */
+ tree access_size = NULL_TREE;
if (tree_int_cst_sgn (sizrng[0]) >= 0)
{
if (COMPLETE_TYPE_P (argtype))
access_size = wide_int_to_tree (sizetype, minsize);
}
}
+ else
+ access_size = access_nelts;
}
- else
- access_size = NULL_TREE;
if (integer_zerop (ptr))
{
if (opt_warned != no_warning)
{
if (access.second.internal_p)
- inform (loc, "referencing argument %u of type %qT",
- ptridx + 1, ptrtype);
+ {
+ unsigned HOST_WIDE_INT nelts =
+ access_nelts ? access.second.minsize : HOST_WIDE_INT_M1U;
+ tree arrtype = build_printable_array_type (argtype, nelts);
+ inform (loc, "referencing argument %u of type %qT",
+ ptridx + 1, arrtype);
+ }
else
/* If check_access issued a warning above, append the relevant
attribute to the string. */
return NULL_TREE;
}
+
+/* Wrapper around build_array_type_nelts that makes sure the array
+ can be created at all and handles zero sized arrays specially. */
+
+tree
+build_printable_array_type (tree eltype, unsigned HOST_WIDE_INT nelts)
+{
+ if (TYPE_SIZE_UNIT (eltype)
+ && TREE_CODE (TYPE_SIZE_UNIT (eltype)) == INTEGER_CST
+ && !integer_zerop (TYPE_SIZE_UNIT (eltype))
+ && TYPE_ALIGN_UNIT (eltype) > 1
+ && wi::zext (wi::to_wide (TYPE_SIZE_UNIT (eltype)),
+ ffs_hwi (TYPE_ALIGN_UNIT (eltype)) - 1) != 0)
+ eltype = TYPE_MAIN_VARIANT (eltype);
+
+ /* Consider excessive NELTS an array of unknown bound. */
+ tree idxtype = NULL_TREE;
+ if (nelts < HOST_WIDE_INT_MAX)
+ {
+ if (nelts)
+ return build_array_type_nelts (eltype, nelts);
+ idxtype = build_range_type (sizetype, size_zero_node, NULL_TREE);
+ }
+
+ tree arrtype = build_array_type (eltype, idxtype);
+ arrtype = build_distinct_type_copy (TYPE_MAIN_VARIANT (arrtype));
+ TYPE_SIZE (arrtype) = bitsize_zero_node;
+ TYPE_SIZE_UNIT (arrtype) = size_zero_node;
+ return arrtype;
+}
HOST_WIDE_INT * = nullptr,
HOST_WIDE_INT * = nullptr);
+/* Helper to build an array type that can be printed. */
+extern tree build_printable_array_type (tree, unsigned HOST_WIDE_INT);
+
#endif // GCC_POINTER_QUERY_H
--- /dev/null
+/* PR c/102759 - ICE calling a function taking an argument redeclared
+ without a prototype.
+ { dg-do compile }
+ { dg-options "-Wall" } */
+
+void f (void)
+{
+ void gia (int[2]);
+ void g ();
+}
+
+/* Redeclaring the g(int[]) above without a prototype loses it. */
+void gia ();
+void g (int[2]);
+
+void h (void )
+{
+ gia (gia);
+ gia (g);
+}
--- /dev/null
+/* Verify that notes after warnings for array and VLA parameters show
+ the array form.
+ { dg-do compile }
+ { dg-options "-Wall" } */
+
+void fia5 (int[5]);
+
+void gia3_fia5 (void)
+{
+ int a[3];
+ fia5 (a); // { dg-warning "-Wstringop-overflow" }
+ // { dg-message "argument 1 of type 'int\\\[5]'" "note" { target *-*-* } .-1 }
+}
+
+
+/* The type of the argument would ideall be 'int[n]' but the variable
+ bound is lost/cleared by free-lang-data and never makes it into
+ the middle end. An (inferior) alternative would be 'int[*]' but
+ the pretty printer doesn't know how to format the star. A better
+ solution might be to introduce a new notation, like 'int[$1]',
+ where the $1 refers to the VLA argument bound. */
+void fvla (int n, int[n]);
+
+void gia3_fvla (void)
+{
+ int a[3];
+ fvla (sizeof a, a); // { dg-warning "-Wstringop-overflow" }
+ // { dg-message "argument 2 of type 'int\\\[]'" "note" { target *-*-* } .-1 }
+}