PR middle-end/91490 - bogus argument missing terminating nul warning on strlen of a flexible array member
gcc/c-family/ChangeLog: PR middle-end/91490 * c-common.c (braced_list_to_string): Add argument and overload. Handle flexible length arrays and unions. gcc/testsuite/ChangeLog: PR middle-end/91490 * c-c++-common/Warray-bounds-7.c: New test. * gcc.dg/Warray-bounds-39.c: Expect either -Warray-bounds or -Wstringop-overflow. * gcc.dg/strlenopt-78.c: New test. gcc/ChangeLog: PR middle-end/91490 * builtins.c (c_strlen): Rename argument and introduce new local. Set no-warning bit on original argument. * expr.c (string_constant): Pass argument type to fold_ctor_reference. Fold empty and zero constructors into empty strings. * gimple-fold.c (fold_nonarray_ctor_reference): Return a STRING_CST for missing initializers. * tree.c (build_string_literal): Handle optional argument. * tree.h (build_string_literal): Add defaulted argument. * gimple-ssa-warn-restrict.c (maybe_diag_access_bounds): Check no-warning bit on original expression. From-SVN: r274837
This commit is contained in:
parent
1b1e13dbde
commit
14b7950f12
@ -1,3 +1,17 @@
|
||||
2019-08-22 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR middle-end/91490
|
||||
* builtins.c (c_strlen): Rename argument and introduce new local.
|
||||
Set no-warning bit on original argument.
|
||||
* expr.c (string_constant): Pass argument type to fold_ctor_reference.
|
||||
Fold empty and zero constructors into empty strings.
|
||||
* gimple-fold.c (fold_nonarray_ctor_reference): Return a STRING_CST
|
||||
for missing initializers.
|
||||
* tree.c (build_string_literal): Handle optional argument.
|
||||
* tree.h (build_string_literal): Add defaulted argument.
|
||||
* gimple-ssa-warn-restrict.c (maybe_diag_access_bounds): Check
|
||||
no-warning bit on original expression.
|
||||
|
||||
2019-08-22 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
|
||||
PR target/91481
|
||||
|
@ -620,7 +620,7 @@ unterminated_array (tree exp, tree *size /* = NULL */, bool *exact /* = NULL */)
|
||||
into the instruction stream and zero if it is going to be expanded.
|
||||
E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
|
||||
is returned, otherwise NULL, since
|
||||
len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
|
||||
len = c_strlen (ARG, 1); if (len) expand_expr (len, ...); would not
|
||||
evaluate the side-effects.
|
||||
|
||||
If ONLY_VALUE is two then we do not emit warnings about out-of-bound
|
||||
@ -628,7 +628,7 @@ unterminated_array (tree exp, tree *size /* = NULL */, bool *exact /* = NULL */)
|
||||
into the instruction stream.
|
||||
|
||||
Additional information about the string accessed may be recorded
|
||||
in DATA. For example, if SRC references an unterminated string,
|
||||
in DATA. For example, if ARG references an unterminated string,
|
||||
then the declaration will be stored in the DECL field. If the
|
||||
length of the unterminated string can be determined, it'll be
|
||||
stored in the LEN field. Note this length could well be different
|
||||
@ -640,7 +640,7 @@ unterminated_array (tree exp, tree *size /* = NULL */, bool *exact /* = NULL */)
|
||||
The value returned is of type `ssizetype'. */
|
||||
|
||||
tree
|
||||
c_strlen (tree src, int only_value, c_strlen_data *data, unsigned eltsize)
|
||||
c_strlen (tree arg, int only_value, c_strlen_data *data, unsigned eltsize)
|
||||
{
|
||||
/* If we were not passed a DATA pointer, then get one to a local
|
||||
structure. That avoids having to check DATA for NULL before
|
||||
@ -650,7 +650,8 @@ c_strlen (tree src, int only_value, c_strlen_data *data, unsigned eltsize)
|
||||
data = &local_strlen_data;
|
||||
|
||||
gcc_checking_assert (eltsize == 1 || eltsize == 2 || eltsize == 4);
|
||||
STRIP_NOPS (src);
|
||||
|
||||
tree src = STRIP_NOPS (arg);
|
||||
if (TREE_CODE (src) == COND_EXPR
|
||||
&& (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
|
||||
{
|
||||
@ -762,11 +763,15 @@ c_strlen (tree src, int only_value, c_strlen_data *data, unsigned eltsize)
|
||||
{
|
||||
/* Suppress multiple warnings for propagated constant strings. */
|
||||
if (only_value != 2
|
||||
&& !TREE_NO_WARNING (src)
|
||||
&& !TREE_NO_WARNING (arg)
|
||||
&& warning_at (loc, OPT_Warray_bounds,
|
||||
"offset %qwi outside bounds of constant string",
|
||||
eltoff))
|
||||
TREE_NO_WARNING (src) = 1;
|
||||
{
|
||||
if (decl)
|
||||
inform (DECL_SOURCE_LOCATION (decl), "%qE declared here", decl);
|
||||
TREE_NO_WARNING (arg) = 1;
|
||||
}
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
2019-08-22 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR middle-end/91490
|
||||
* c-common.c (braced_list_to_string): Add argument and overload.
|
||||
Handle flexible length arrays and unions.
|
||||
|
||||
2019-08-21 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* c-ada-spec.c (dump_ada_function_declaration): Be prepared for broken
|
||||
|
@ -8747,9 +8747,12 @@ maybe_add_include_fixit (rich_location *richloc, const char *header,
|
||||
the converted string on success or the original ctor on failure. */
|
||||
|
||||
static tree
|
||||
braced_list_to_string (tree type, tree ctor)
|
||||
braced_list_to_string (tree type, tree ctor, bool member)
|
||||
{
|
||||
if (!tree_fits_uhwi_p (TYPE_SIZE_UNIT (type)))
|
||||
/* Ignore non-members with unknown size like arrays with unspecified
|
||||
bound. */
|
||||
tree typesize = TYPE_SIZE_UNIT (type);
|
||||
if (!member && !tree_fits_uhwi_p (typesize))
|
||||
return ctor;
|
||||
|
||||
/* If the array has an explicit bound, use it to constrain the size
|
||||
@ -8757,10 +8760,17 @@ braced_list_to_string (tree type, tree ctor)
|
||||
as long as implied by the index of the last zero specified via
|
||||
a designator, as in:
|
||||
const char a[] = { [7] = 0 }; */
|
||||
unsigned HOST_WIDE_INT maxelts = tree_to_uhwi (TYPE_SIZE_UNIT (type));
|
||||
unsigned HOST_WIDE_INT maxelts;
|
||||
if (typesize)
|
||||
{
|
||||
maxelts = tree_to_uhwi (typesize);
|
||||
maxelts /= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type)));
|
||||
}
|
||||
else
|
||||
maxelts = HOST_WIDE_INT_M1U;
|
||||
|
||||
/* Avoid converting initializers for zero-length arrays. */
|
||||
/* Avoid converting initializers for zero-length arrays (but do
|
||||
create them for flexible array members). */
|
||||
if (!maxelts)
|
||||
return ctor;
|
||||
|
||||
@ -8818,7 +8828,7 @@ braced_list_to_string (tree type, tree ctor)
|
||||
}
|
||||
|
||||
/* Append a nul string termination. */
|
||||
if (str.length () < maxelts)
|
||||
if (maxelts != HOST_WIDE_INT_M1U && str.length () < maxelts)
|
||||
str.safe_push (0);
|
||||
|
||||
/* Build a STRING_CST with the same type as the array. */
|
||||
@ -8827,14 +8837,12 @@ braced_list_to_string (tree type, tree ctor)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Attempt to convert a CTOR containing braced array initializer lists
|
||||
for array TYPE into one containing STRING_CSTs, for convenience and
|
||||
efficiency. Recurse for arrays of arrays and member initializers.
|
||||
Return the converted CTOR or STRING_CST on success or the original
|
||||
CTOR otherwise. */
|
||||
/* Implementation of the two-argument braced_lists_to_string withe
|
||||
the same arguments plus MEMBER which is set for struct members
|
||||
to allow initializers for flexible member arrays. */
|
||||
|
||||
tree
|
||||
braced_lists_to_strings (tree type, tree ctor)
|
||||
static tree
|
||||
braced_lists_to_strings (tree type, tree ctor, bool member)
|
||||
{
|
||||
if (TREE_CODE (ctor) != CONSTRUCTOR)
|
||||
return ctor;
|
||||
@ -8858,17 +8866,19 @@ braced_lists_to_strings (tree type, tree ctor)
|
||||
|
||||
if ((TREE_CODE (ttp) == ARRAY_TYPE || TREE_CODE (ttp) == INTEGER_TYPE)
|
||||
&& TYPE_STRING_FLAG (ttp))
|
||||
return braced_list_to_string (type, ctor);
|
||||
return braced_list_to_string (type, ctor, member);
|
||||
|
||||
code = TREE_CODE (ttp);
|
||||
if (code == ARRAY_TYPE || code == RECORD_TYPE)
|
||||
if (code == ARRAY_TYPE || RECORD_OR_UNION_TYPE_P (ttp))
|
||||
{
|
||||
bool rec = RECORD_OR_UNION_TYPE_P (ttp);
|
||||
|
||||
/* Handle array of arrays or struct member initializers. */
|
||||
tree val;
|
||||
unsigned HOST_WIDE_INT idx;
|
||||
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), idx, val)
|
||||
{
|
||||
val = braced_lists_to_strings (ttp, val);
|
||||
val = braced_lists_to_strings (ttp, val, rec);
|
||||
CONSTRUCTOR_ELT (ctor, idx)->value = val;
|
||||
}
|
||||
}
|
||||
@ -8876,4 +8886,16 @@ braced_lists_to_strings (tree type, tree ctor)
|
||||
return ctor;
|
||||
}
|
||||
|
||||
/* Attempt to convert a CTOR containing braced array initializer lists
|
||||
for array TYPE into one containing STRING_CSTs, for convenience and
|
||||
efficiency. Recurse for arrays of arrays and member initializers.
|
||||
Return the converted CTOR or STRING_CST on success or the original
|
||||
CTOR otherwise. */
|
||||
|
||||
tree
|
||||
braced_lists_to_strings (tree type, tree ctor)
|
||||
{
|
||||
return braced_lists_to_strings (type, ctor, false);
|
||||
}
|
||||
|
||||
#include "gt-c-family-c-common.h"
|
||||
|
62
gcc/expr.c
62
gcc/expr.c
@ -11402,6 +11402,15 @@ is_aligning_offset (const_tree offset, const_tree exp)
|
||||
tree
|
||||
string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
|
||||
{
|
||||
tree dummy = NULL_TREE;;
|
||||
if (!mem_size)
|
||||
mem_size = &dummy;
|
||||
|
||||
/* Store the type of the original expression before conversions
|
||||
via NOP_EXPR or POINTER_PLUS_EXPR to other types have been
|
||||
removed. */
|
||||
tree argtype = TREE_TYPE (arg);
|
||||
|
||||
tree array;
|
||||
STRIP_NOPS (arg);
|
||||
|
||||
@ -11464,7 +11473,7 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
|
||||
&& TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == ARRAY_TYPE
|
||||
&& !(decl && !*decl)
|
||||
&& !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl))
|
||||
&& mem_size && tree_fits_uhwi_p (*mem_size)
|
||||
&& tree_fits_uhwi_p (*mem_size)
|
||||
&& tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl))))
|
||||
return NULL_TREE;
|
||||
|
||||
@ -11496,7 +11505,7 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
|
||||
&& TREE_CODE (TREE_TYPE (TREE_TYPE (rhs1))) == ARRAY_TYPE
|
||||
&& !(decl && !*decl)
|
||||
&& !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl))
|
||||
&& mem_size && tree_fits_uhwi_p (*mem_size)
|
||||
&& tree_fits_uhwi_p (*mem_size)
|
||||
&& tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl))))
|
||||
return NULL_TREE;
|
||||
|
||||
@ -11530,7 +11539,6 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
|
||||
if (TREE_CODE (array) == STRING_CST)
|
||||
{
|
||||
*ptr_offset = fold_convert (sizetype, offset);
|
||||
if (mem_size)
|
||||
*mem_size = TYPE_SIZE_UNIT (TREE_TYPE (array));
|
||||
if (decl)
|
||||
*decl = NULL_TREE;
|
||||
@ -11561,7 +11569,7 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
|
||||
|
||||
base_off = wioff.to_uhwi ();
|
||||
unsigned HOST_WIDE_INT fieldoff = 0;
|
||||
init = fold_ctor_reference (NULL_TREE, init, base_off, 0, array,
|
||||
init = fold_ctor_reference (TREE_TYPE (arg), init, base_off, 0, array,
|
||||
&fieldoff);
|
||||
HOST_WIDE_INT cstoff;
|
||||
if (!base_off.is_constant (&cstoff))
|
||||
@ -11580,17 +11588,11 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
|
||||
|
||||
*ptr_offset = offset;
|
||||
|
||||
tree eltype = TREE_TYPE (init);
|
||||
tree initsize = TYPE_SIZE_UNIT (eltype);
|
||||
if (mem_size)
|
||||
*mem_size = initsize;
|
||||
|
||||
if (decl)
|
||||
*decl = array;
|
||||
tree inittype = TREE_TYPE (init);
|
||||
|
||||
if (TREE_CODE (init) == INTEGER_CST
|
||||
&& (TREE_CODE (TREE_TYPE (array)) == INTEGER_TYPE
|
||||
|| TYPE_MAIN_VARIANT (eltype) == char_type_node))
|
||||
|| TYPE_MAIN_VARIANT (inittype) == char_type_node))
|
||||
{
|
||||
/* For a reference to (address of) a single constant character,
|
||||
store the native representation of the character in CHARBUF.
|
||||
@ -11602,17 +11604,49 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
|
||||
int len = native_encode_expr (init, charbuf, sizeof charbuf, 0);
|
||||
if (len > 0)
|
||||
{
|
||||
/* Construct a string literal with elements of ELTYPE and
|
||||
/* Construct a string literal with elements of INITTYPE and
|
||||
the representation above. Then strip
|
||||
the ADDR_EXPR (ARRAY_REF (...)) around the STRING_CST. */
|
||||
init = build_string_literal (len, (char *)charbuf, eltype);
|
||||
init = build_string_literal (len, (char *)charbuf, inittype);
|
||||
init = TREE_OPERAND (TREE_OPERAND (init, 0), 0);
|
||||
}
|
||||
}
|
||||
|
||||
tree initsize = TYPE_SIZE_UNIT (inittype);
|
||||
|
||||
if (TREE_CODE (init) == CONSTRUCTOR && initializer_zerop (init))
|
||||
{
|
||||
/* Fold an empty/zero constructor for an implicitly initialized
|
||||
object or subobject into the empty string. */
|
||||
|
||||
/* Determine the character type from that of the original
|
||||
expression. */
|
||||
tree chartype = argtype;
|
||||
if (POINTER_TYPE_P (chartype))
|
||||
chartype = TREE_TYPE (chartype);
|
||||
while (TREE_CODE (chartype) == ARRAY_TYPE)
|
||||
chartype = TREE_TYPE (chartype);
|
||||
/* Convert a char array to an empty STRING_CST having an array
|
||||
of the expected type. */
|
||||
if (!initsize)
|
||||
initsize = integer_zero_node;
|
||||
|
||||
unsigned HOST_WIDE_INT size = tree_to_uhwi (initsize);
|
||||
init = build_string_literal (size ? 1 : 0, "", chartype, size);
|
||||
init = TREE_OPERAND (init, 0);
|
||||
init = TREE_OPERAND (init, 0);
|
||||
|
||||
*ptr_offset = integer_zero_node;
|
||||
}
|
||||
|
||||
if (decl)
|
||||
*decl = array;
|
||||
|
||||
if (TREE_CODE (init) != STRING_CST)
|
||||
return NULL_TREE;
|
||||
|
||||
*mem_size = initsize;
|
||||
|
||||
gcc_checking_assert (tree_to_shwi (initsize) >= TREE_STRING_LENGTH (init));
|
||||
|
||||
return init;
|
||||
|
@ -759,11 +759,13 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi,
|
||||
dest_align = get_pointer_alignment (dest);
|
||||
if (tree_fits_uhwi_p (len)
|
||||
&& compare_tree_int (len, MOVE_MAX) <= 0
|
||||
/* ??? Don't transform copies from strings with known length this
|
||||
confuses the tree-ssa-strlen.c. This doesn't handle
|
||||
the case in gcc.dg/strlenopt-8.c which is XFAILed for that
|
||||
reason. */
|
||||
&& !c_strlen (src, 2)
|
||||
/* FIXME: Don't transform copies from strings with known length.
|
||||
Until GCC 9 this prevented a case in gcc.dg/strlenopt-8.c
|
||||
from being handled, and the case was XFAILed for that reason.
|
||||
Now that it is handled and the XFAIL removed, as soon as other
|
||||
strlenopt tests that rely on it for passing are adjusted, this
|
||||
hack can be removed. */
|
||||
&& !c_strlen (src, 1)
|
||||
&& !((tmp_str = c_getstr (src, &tmp_len)) != NULL
|
||||
&& memchr (tmp_str, 0, tmp_len) == NULL))
|
||||
{
|
||||
@ -6969,12 +6971,15 @@ fold_nonarray_ctor_reference (tree type, tree ctor,
|
||||
from_decl, suboff);
|
||||
}
|
||||
}
|
||||
/* Memory not explicitly mentioned in constructor is 0. */
|
||||
return type ? build_zero_cst (type) : NULL_TREE;
|
||||
|
||||
if (!type)
|
||||
return NULL_TREE;
|
||||
|
||||
return build_zero_cst (type);
|
||||
}
|
||||
|
||||
/* CTOR is value initializing memory. Fold a reference of TYPE and
|
||||
bit size POLY_SIZE to the memory at bit POLY_OFFSET. When SIZE
|
||||
bit size POLY_SIZE to the memory at bit POLY_OFFSET. When POLY_SIZE
|
||||
is zero, attempt to fold a reference to the entire subobject
|
||||
which OFFSET refers to. This is used when folding accesses to
|
||||
string members of aggregates. When non-null, set *SUBOFF to
|
||||
|
@ -1678,7 +1678,8 @@ maybe_diag_access_bounds (location_t loc, gimple *call, tree func, int strict,
|
||||
if (!warn_array_bounds)
|
||||
return false;
|
||||
|
||||
if (ref.ref && TREE_NO_WARNING (ref.ref))
|
||||
if (TREE_NO_WARNING (ref.ptr)
|
||||
|| (ref.ref && TREE_NO_WARNING (ref.ref)))
|
||||
return false;
|
||||
|
||||
if (EXPR_HAS_LOCATION (ref.ptr))
|
||||
|
@ -1,3 +1,11 @@
|
||||
2019-08-22 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR middle-end/91490
|
||||
* c-c++-common/Warray-bounds-7.c: New test.
|
||||
* gcc.dg/Warray-bounds-39.c: Expect either -Warray-bounds or
|
||||
-Wstringop-overflow.
|
||||
* gcc.dg/strlenopt-78.c: New test.
|
||||
|
||||
2019-08-22 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
* gcc.target/i386/minmax-4.c: Add -mno-stackrealign to dg-options.
|
||||
|
107
gcc/testsuite/c-c++-common/Warray-bounds-7.c
Normal file
107
gcc/testsuite/c-c++-common/Warray-bounds-7.c
Normal file
@ -0,0 +1,107 @@
|
||||
/* PR middle-end/91490 - bogus argument missing terminating nul warning
|
||||
on strlen of a flexible array member
|
||||
{ dg-do compile }
|
||||
{ dg-options "-Wall -ftrack-macro-expansion=0" } */
|
||||
|
||||
#define INT_MAX __INT_MAX__
|
||||
#define PTRDIFF_MAX __PTRDIFF_MAX__
|
||||
#define SIZE_MAX __SIZE_MAX__
|
||||
|
||||
struct A0 { char n, a[0]; };
|
||||
struct A1 { char n, a[1]; };
|
||||
struct Ax { char n, a[]; };
|
||||
|
||||
const struct A0 a0 = { };
|
||||
const struct A0 a0_0 = { 0 };
|
||||
const struct A0 a0_0_ = { 0, { } };
|
||||
|
||||
const struct A0 a1 = { };
|
||||
const struct A0 a1_0 = { 0 };
|
||||
const struct A0 a1_0_ = { 0, { } };
|
||||
|
||||
const struct Ax ax= { };
|
||||
const struct Ax ax_0 = { 0 };
|
||||
const struct Ax ax_0_ = { 0, { } };
|
||||
|
||||
void sink (unsigned);
|
||||
|
||||
#define T(x) sink (__builtin_strlen (x))
|
||||
|
||||
void test_zero_length_array (void)
|
||||
{
|
||||
T (a0.a); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a0.a - 1); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a0.a + 1); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a0.a + 9); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a0.a + INT_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a0.a + PTRDIFF_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a0.a + SIZE_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
|
||||
T (a0_0.a); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a0_0.a - 1); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a0_0.a + 1); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a0_0.a + 9); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a0_0.a + INT_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a0_0.a + PTRDIFF_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a0_0.a + SIZE_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
|
||||
T (a0_0_.a); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a0_0_.a - 1); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a0_0_.a + 1); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a0_0_.a + 9); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a0_0_.a + INT_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a0_0_.a + PTRDIFF_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a0_0_.a + SIZE_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
void test_one_element_array (void)
|
||||
{
|
||||
T (a1.a - 1); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a1.a + 1); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a1.a + 9); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a1.a + INT_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a1.a + PTRDIFF_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a1.a + SIZE_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
|
||||
T (a1_0.a - 1); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a1_0.a + 1); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a1_0.a + 9); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a1_0.a + INT_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a1_0.a + PTRDIFF_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a1_0.a + SIZE_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
|
||||
T (a1_0_.a - 1); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a1_0_.a + 1); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a1_0_.a + 9); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a1_0_.a + INT_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a1_0_.a + PTRDIFF_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a1_0_.a + SIZE_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
void test_flexible_array_member (void)
|
||||
{
|
||||
T (ax.a); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (ax.a - 1); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (ax.a + 1); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (ax.a + 9); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (ax.a + INT_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (ax.a + PTRDIFF_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (ax.a + SIZE_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
|
||||
T (ax_0.a); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (ax_0.a - 1); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (ax_0.a + 1); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (ax_0.a + 9); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (ax_0.a + INT_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (ax_0.a + PTRDIFF_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (ax_0.a + SIZE_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
|
||||
T (ax_0_.a); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (ax_0_.a - 1); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (ax_0_.a + 1); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (ax_0_.a + 9); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (ax_0_.a + INT_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (ax_0_.a + PTRDIFF_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (ax_0_.a + SIZE_MAX); // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
@ -21,65 +21,65 @@ char d[4];
|
||||
|
||||
void* test_memcpy_s0_1 (void *d)
|
||||
{
|
||||
return memcpy (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds" } */
|
||||
return memcpy (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
void* test_memcpy_s0_2 (void *d)
|
||||
{
|
||||
return memcpy (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds" } */
|
||||
return memcpy (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
void* test_memcpy_s0_0_1 (void *d)
|
||||
{
|
||||
return memcpy (d, s0_0, 1); /* { dg-warning "\\\[-Warray-bounds" } */
|
||||
return memcpy (d, s0_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
void* test_memcpy_s0_0_2 (void *d)
|
||||
{
|
||||
return memcpy (d, s0_0, 2); /* { dg-warning "\\\[-Warray-bounds" } */
|
||||
return memcpy (d, s0_0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
|
||||
void* test_memcpy_s0_1_1 (void *d)
|
||||
{
|
||||
return memcpy (d, s0_1, 1); /* { dg-warning "\\\[-Warray-bounds" } */
|
||||
return memcpy (d, s0_1, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
void* test_memcpy_s0_1_2 (void *d)
|
||||
{
|
||||
return memcpy (d, s0_1, 2); /* { dg-warning "\\\[-Warray-bounds" } */
|
||||
return memcpy (d, s0_1, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
|
||||
void* test_memcpy_s1_0_1 (void *d)
|
||||
{
|
||||
return memcpy (d, s1_0, 1); /* { dg-warning "\\\[-Warray-bounds" } */
|
||||
return memcpy (d, s1_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
void* test_memcpy_s1_0_2 (void *d)
|
||||
{
|
||||
return memcpy (d, s1_0, 2); /* { dg-warning "\\\[-Warray-bounds" } */
|
||||
return memcpy (d, s1_0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
|
||||
void* test_memmove_s0_1 (void *d)
|
||||
{
|
||||
return memmove (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds" } */
|
||||
return memmove (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
void* test_memmove_s0_2 (void *d)
|
||||
{
|
||||
return memmove (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds" } */
|
||||
return memmove (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
void* test_memmove_s0_0_1 (void *d)
|
||||
{
|
||||
return memmove (d, s0_0, 1); /* { dg-warning "\\\[-Warray-bounds" } */
|
||||
return memmove (d, s0_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
void* test_memmove_s0_0_2 (void *d)
|
||||
{
|
||||
return memmove (d, s0_0, 2); /* { dg-warning "\\\[-Warray-bounds" } */
|
||||
return memmove (d, s0_0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
|
||||
@ -92,57 +92,57 @@ const struct Empty e1_0[1][0] = { };
|
||||
|
||||
void* test_memcpy_e_1 (void *d)
|
||||
{
|
||||
return memcpy (d, &e, 1); /* { dg-warning "\\\[-Warray-bounds" } */
|
||||
return memcpy (d, &e, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
void* test_memcpy_e0_1 (void *d)
|
||||
{
|
||||
return memcpy (d, e0, 1); /* { dg-warning "\\\[-Warray-bounds" } */
|
||||
return memcpy (d, e0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
void* test_memcpy_e0_0_1 (void *d)
|
||||
{
|
||||
return memcpy (d, e0_0, 1); /* { dg-warning "\\\[-Warray-bounds" } */
|
||||
return memcpy (d, e0_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
void* test_memcpy_e0_1_1 (void *d)
|
||||
{
|
||||
return memcpy (d, e0_1, 1); /* { dg-warning "\\\[-Warray-bounds" } */
|
||||
return memcpy (d, e0_1, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
void* test_memcpy_e1_0_1 (void *d)
|
||||
{
|
||||
return memcpy (d, e1_0, 1); /* { dg-warning "\\\[-Warray-bounds" } */
|
||||
return memcpy (d, e1_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
|
||||
char* test_strcpy_s0 (char *d)
|
||||
{
|
||||
return strcpy (d, s0); /* { dg-warning "\\\[-Warray-bounds" "pr88991" { xfail *-*-* } } */
|
||||
return strcpy (d, s0); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
char* test_strcpy_s0_0 (char *d)
|
||||
{
|
||||
return strcpy (d, s0_0[0]); /* { dg-warning "\\\[-Warray-bounds" "pr88991" { xfail *-*-* } } */
|
||||
return strcpy (d, s0_0[0]); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr88991" { xfail *-*-* } } */
|
||||
}
|
||||
|
||||
|
||||
char* test_strncpy_s0_1 (char *d)
|
||||
{
|
||||
return strncpy (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds" "pr88991" { xfail *-*-* } } */
|
||||
return strncpy (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
char* test_strncpy_s0_2 (char *d)
|
||||
{
|
||||
return strncpy (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds" "pr88991" { xfail *-*-* } } */
|
||||
return strncpy (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
char* test_strncpy_s0_0_1 (char *d)
|
||||
{
|
||||
return strncpy (d, s0_0[0], 1); /* { dg-warning "\\\[-Warray-bounds" "pr88991" { xfail *-*-* } } */
|
||||
return strncpy (d, s0_0[0], 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr88991" { xfail *-*-* } } */
|
||||
}
|
||||
|
||||
char* test_strncpy_s0_0_2 (char *d)
|
||||
{
|
||||
return strncpy (d, s0_0[0], 2); /* { dg-warning "\\\[-Warray-bounds" "pr88991" { xfail *-*-* } } */
|
||||
return strncpy (d, s0_0[0], 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr88991" { xfail *-*-* } } */
|
||||
}
|
||||
|
166
gcc/testsuite/gcc.dg/strlenopt-78.c
Normal file
166
gcc/testsuite/gcc.dg/strlenopt-78.c
Normal file
@ -0,0 +1,166 @@
|
||||
/* PR middle-end/91490 - bogus argument missing terminating nul warning
|
||||
on strlen of a flexible array member
|
||||
Verify that strlen calls with a flexible array member (and its common
|
||||
forms) of declaraed objects are folded.
|
||||
{ dg-do compile }
|
||||
{ dg-options "-Wall -fdump-tree-gimple" } */
|
||||
|
||||
#include "strlenopt.h"
|
||||
|
||||
extern void* memchr (const void*, int, size_t);
|
||||
|
||||
struct A1 { char n, a[1]; };
|
||||
struct A2 { char n, a[2]; };
|
||||
struct A3 { char n, a[3]; };
|
||||
struct Ax { char n, a[]; };
|
||||
|
||||
const struct A1 a1_0 = { 0 };
|
||||
const struct A1 a1_0_ = { 0, { } };
|
||||
const struct A1 a1_0_0 = { 0, { 0 } };
|
||||
|
||||
const struct A2 a2_1_ = { 1, { } };
|
||||
const struct A2 a2_1_1 = { 1, { 1 } };
|
||||
const struct A2 a2_1_1_0 = { 1, { 1, 0 } };
|
||||
|
||||
const struct A3 aa3_1_[2] = { { 1 } };
|
||||
|
||||
const struct Ax ax = { 3, { 3, 2, 1, 0 } };
|
||||
|
||||
struct BxA1 { int n; struct A1 a[]; };
|
||||
struct BxA2 { int n; struct A2 a[]; };
|
||||
|
||||
const struct BxA2 bx = { 2, { { 2, { 2, 1 } }, { 2, { 1, 0 } } } };
|
||||
|
||||
#if 0
|
||||
|
||||
// Not implemented yet.
|
||||
|
||||
int mchr1, mchr1__, mchr1_0, mchr2_1, mchr2, mchr2_1_0, mchrax, mchrbx;
|
||||
|
||||
void test_memchr_flexarray (void)
|
||||
{
|
||||
mchr1 = 0 != memchr (&a1_0, '1', sizeof a1_0);
|
||||
mchr1__ = 0 != memchr (&a1_0_, '2', sizeof a1_0_);
|
||||
mchr1_0 = 0 != memchr (&a1_0_0, '3', sizeof a1_0_0);
|
||||
|
||||
mchr2 = 0 != memchr (&a2_1_, '4', sizeof a2_1_);
|
||||
mchr2_1 = 0 != memchr (&a2_1_1, '\001', sizeof a2_1_1);
|
||||
mchr2_1_0 = 0 != memchr (&a2_1_1_0, '\001', sizeof a2_1_1_0);
|
||||
|
||||
mchrax = (const char*)&ax + sizeof ax - 1 == memchr (&ax, '\001', sizeof ax);
|
||||
mchrbx = (const char*)&bx + sizeof bx - 1 == memchr (&bx, '\001', sizeof bx);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
int schr1, schr1__, schr1_0, schr2_1, schr2, schr2_1_0, schrax, schrbx;
|
||||
|
||||
void test_strchr_flexarray (void)
|
||||
{
|
||||
schr1 = 0 != strchr (a1_0.a, '1');
|
||||
schr1__ = 0 != strchr (a1_0_.a, '2');
|
||||
schr1_0 = 0 != strchr (a1_0_0.a, '3');
|
||||
|
||||
schr2 = 0 != strchr (a2_1_.a, '4');
|
||||
schr2_1 = 0 != strchr (a2_1_1.a, '\001');
|
||||
schr2_1_0 = 0 != strchr (a2_1_1_0.a, '\001');
|
||||
|
||||
schrax = 0 != strchr (ax.a, '\001');
|
||||
schrbx = 0 != strchr (bx.a[1].a, '\0');
|
||||
|
||||
/* { dg-final { scan-tree-dump "schr1 = 0;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "schr1__ = 0;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "schr1_0 = 0;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "schr2 = 0;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "schr2_1 = 1;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "schr2_1_0 = 1;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "schrax = 1;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "schrbx = 1;" "gimple" } } */
|
||||
}
|
||||
|
||||
|
||||
int scmp1, scmp1__, scmp1_0, scmp2_1, scmp2, scmp2_1_0, scmpax, scmpbx;
|
||||
|
||||
void test_strcmp_flexarray (void)
|
||||
{
|
||||
scmp1 = 0 == strcmp (a1_0.a, "1");
|
||||
scmp1__ = 0 == strcmp (a1_0_.a, "2");
|
||||
scmp1_0 = 0 == strcmp (a1_0_0.a, "3");
|
||||
|
||||
scmp2 = 0 == strcmp (a2_1_.a, "4");
|
||||
scmp2_1 = 0 == strcmp (a2_1_1.a, "\001");
|
||||
scmp2_1_0 = 0 == strcmp (a2_1_1_0.a, "\001");
|
||||
|
||||
scmpax = 0 == strcmp (ax.a, "\003\002\001");
|
||||
scmpbx = 0 == strcmp (bx.a[1].a, "\001");
|
||||
|
||||
/* { dg-final { scan-tree-dump "scmp1 = 0;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "scmp1__ = 0;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "scmp1_0 = 0;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "scmp2 = 0;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "scmp2_1 = 1;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "scmp2_1_0 = 1;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "scmpax = 1;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "scmpbx = 1;" "gimple" } } */
|
||||
}
|
||||
|
||||
|
||||
int len1, len1__, len1_0, len2_1, len2, len2_1_0, lenax, lenbx;
|
||||
|
||||
void test_strlen_flexarray (void)
|
||||
{
|
||||
len1 = strlen (a1_0.a);
|
||||
len1__ = strlen (a1_0_.a);
|
||||
len1_0 = strlen (a1_0_0.a);
|
||||
|
||||
len2 = strlen (a2_1_.a);
|
||||
len2_1 = strlen (a2_1_1.a);
|
||||
len2_1_0 = strlen (a2_1_1_0.a);
|
||||
|
||||
lenax = strlen (ax.a);
|
||||
lenbx = strlen (bx.a[1].a);
|
||||
|
||||
/* { dg-final { scan-tree-dump "len1 = 0;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "len1__ = 0;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "len1_0 = 0;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "len2 = 0;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "len2_1 = 1;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "len2_1_0 = 1;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "lenax = 3;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "lenbx = 1;" "gimple" } } */
|
||||
}
|
||||
|
||||
|
||||
int schraa3, scmpaa3, lenaa3;
|
||||
|
||||
void test_trailing_array_empty_init (void)
|
||||
{
|
||||
schraa3 = ((aa3_1_[0].a == strchr (aa3_1_[0].a, 0))
|
||||
+ (aa3_1_[1].a == strchr (aa3_1_[1].a, 0)));
|
||||
|
||||
scmpaa3 = strcmp (aa3_1_[0].a, aa3_1_[1].a);
|
||||
lenaa3 = strlen (aa3_1_[0].a) + strlen (aa3_1_[1].a);
|
||||
|
||||
/* { dg-final { scan-tree-dump "schraa3 = 2;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "scmpaa3 = 0;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "lenaa3 = 0;" "gimple" } } */
|
||||
}
|
||||
|
||||
union U4 { char a[4]; int i; };
|
||||
const union U4 u4[2] = { { "123" } };
|
||||
|
||||
int ulen0, ulen1;
|
||||
|
||||
void test_union_init (void)
|
||||
{
|
||||
ulen0 = strlen (u4[0].a);
|
||||
ulen1 = strlen (u4[1].a);
|
||||
|
||||
/* { dg-final { scan-tree-dump "ulen0 = 3;" "gimple" } }
|
||||
{ dg-final { scan-tree-dump "ulen1 = 0;" "gimple" } } */
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-not "strchr *\\(" "gimple" } }
|
||||
{ dg-final { scan-tree-dump-not "strcmp *\\(" "gimple" } }
|
||||
{ dg-final { scan-tree-dump-not "strlen *\\(" "gimple" } } */
|
17
gcc/tree.c
17
gcc/tree.c
@ -11872,18 +11872,23 @@ build_alloca_call_expr (tree size, unsigned int align, HOST_WIDE_INT max_size)
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a new constant string literal consisting of elements of type
|
||||
ELTYPE and return a tree node representing char* pointer to it as
|
||||
an ADDR_EXPR (ARRAY_REF (ELTYPE, ...)). The STRING_CST value is
|
||||
the LEN bytes at STR (the representation of the string, which may
|
||||
/* Create a new constant string literal of type ELTYPE[SIZE] (or LEN
|
||||
if SIZE == -1) and return a tree node representing char* pointer to
|
||||
it as an ADDR_EXPR (ARRAY_REF (ELTYPE, ...)). The STRING_CST value
|
||||
is the LEN bytes at STR (the representation of the string, which may
|
||||
be wide). */
|
||||
|
||||
tree
|
||||
build_string_literal (int len, const char *str,
|
||||
tree eltype /* = char_type_node */)
|
||||
tree eltype /* = char_type_node */,
|
||||
unsigned HOST_WIDE_INT size /* = -1 */)
|
||||
{
|
||||
tree t = build_string (len, str);
|
||||
tree index = build_index_type (size_int (len - 1));
|
||||
/* Set the maximum valid index based on the string length or SIZE. */
|
||||
unsigned HOST_WIDE_INT maxidx
|
||||
= (size == HOST_WIDE_INT_M1U ? len : size) - 1;
|
||||
|
||||
tree index = build_index_type (size_int (maxidx));
|
||||
eltype = build_type_variant (eltype, 1, 0);
|
||||
tree type = build_array_type (eltype, index);
|
||||
TREE_TYPE (t) = type;
|
||||
|
@ -4418,7 +4418,8 @@ extern tree build_call_expr_internal_loc_array (location_t, enum internal_fn,
|
||||
extern tree maybe_build_call_expr_loc (location_t, combined_fn, tree,
|
||||
int, ...);
|
||||
extern tree build_alloca_call_expr (tree, unsigned int, HOST_WIDE_INT);
|
||||
extern tree build_string_literal (int, const char *, tree = char_type_node);
|
||||
extern tree build_string_literal (int, const char *, tree = char_type_node,
|
||||
unsigned HOST_WIDE_INT = HOST_WIDE_INT_M1U);
|
||||
|
||||
/* Construct various nodes representing data types. */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user