mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-22 18:50:55 +08:00
re PR c/20519 (completed type not selected properly with typeof)
PR c/20519 * c-decl.c (c_finish_incomplete_decl): Update complete_array_type call. (build_compound_literal): Likewise. Propagate decl type into the initializer. (finish_decl): Likewise. Use new return value from complete_array_type for zero sized arrays. (complete_array_type): Move ... * c-common.c (complete_array_type): ... here. Change first argument to pointer-to-type-node. Consistently use sizetype for the index except for zero sized arrays. Detect zero sized arrays for pedantic mode diagnostics. Create a new type node instead of modifying the old node in place. * c-tree.h (complete_array_type): Move decl ... * c-common.h (complete_array_type): ... here. cp/ * decl.c (cp_complete_array_type): Rename from complete_array_type. Use the new complete_array_type in c-common.c. Update all callers. * cp-tree.h (cp_complete_array_type): Update to match. From-SVN: r97223
This commit is contained in:
parent
748e31c326
commit
aab038d54a
@ -1,3 +1,20 @@
|
||||
2005-03-29 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR c/20519
|
||||
* c-decl.c (c_finish_incomplete_decl): Update complete_array_type call.
|
||||
(build_compound_literal): Likewise. Propagate decl type into the
|
||||
initializer.
|
||||
(finish_decl): Likewise. Use new return value from complete_array_type
|
||||
for zero sized arrays.
|
||||
(complete_array_type): Move ...
|
||||
* c-common.c (complete_array_type): ... here. Change first argument
|
||||
to pointer-to-type-node. Consistently use sizetype for the index
|
||||
except for zero sized arrays. Detect zero sized arrays for pedantic
|
||||
mode diagnostics. Create a new type node instead of modifying the
|
||||
old node in place.
|
||||
* c-tree.h (complete_array_type): Move decl ...
|
||||
* c-common.h (complete_array_type): ... here.
|
||||
|
||||
2005-03-29 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR tree-opt/19108
|
||||
|
@ -5756,5 +5756,94 @@ lvalue_error (enum lvalue_use use)
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
|
||||
/* *PTYPE is an incomplete array. Complete it with a domain based on
|
||||
INITIAL_VALUE. If INITIAL_VALUE is not present, use 1 if DO_DEFAULT
|
||||
is true. Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered,
|
||||
2 if INITIAL_VALUE was NULL, and 3 if INITIAL_VALUE was empty. */
|
||||
|
||||
int
|
||||
complete_array_type (tree *ptype, tree initial_value, bool do_default)
|
||||
{
|
||||
tree maxindex, type, main_type, elt, unqual_elt;
|
||||
int failure = 0, quals;
|
||||
|
||||
maxindex = size_zero_node;
|
||||
if (initial_value)
|
||||
{
|
||||
if (TREE_CODE (initial_value) == STRING_CST)
|
||||
{
|
||||
int eltsize
|
||||
= int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value)));
|
||||
maxindex = size_int (TREE_STRING_LENGTH (initial_value)/eltsize - 1);
|
||||
}
|
||||
else if (TREE_CODE (initial_value) == CONSTRUCTOR)
|
||||
{
|
||||
tree elts = CONSTRUCTOR_ELTS (initial_value);
|
||||
|
||||
if (elts == NULL)
|
||||
{
|
||||
if (pedantic)
|
||||
failure = 3;
|
||||
maxindex = integer_minus_one_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
tree curindex;
|
||||
|
||||
if (TREE_PURPOSE (elts))
|
||||
maxindex = fold_convert (sizetype, TREE_PURPOSE (elts));
|
||||
curindex = maxindex;
|
||||
|
||||
for (elts = TREE_CHAIN (elts); elts; elts = TREE_CHAIN (elts))
|
||||
{
|
||||
if (TREE_PURPOSE (elts))
|
||||
curindex = fold_convert (sizetype, TREE_PURPOSE (elts));
|
||||
else
|
||||
curindex = size_binop (PLUS_EXPR, curindex, size_one_node);
|
||||
|
||||
if (tree_int_cst_lt (maxindex, curindex))
|
||||
maxindex = curindex;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Make an error message unless that happened already. */
|
||||
if (initial_value != error_mark_node)
|
||||
failure = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
failure = 2;
|
||||
if (!do_default)
|
||||
return failure;
|
||||
}
|
||||
|
||||
type = *ptype;
|
||||
elt = TREE_TYPE (type);
|
||||
quals = TYPE_QUALS (strip_array_types (elt));
|
||||
if (quals == 0)
|
||||
unqual_elt = elt;
|
||||
else
|
||||
unqual_elt = c_build_qualified_type (elt, TYPE_UNQUALIFIED);
|
||||
|
||||
/* Using build_distinct_type_copy and modifying things afterward instead
|
||||
of using build_array_type to create a new type preserves all of the
|
||||
TYPE_LANG_FLAG_? bits that the front end may have set. */
|
||||
main_type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
|
||||
TREE_TYPE (main_type) = unqual_elt;
|
||||
TYPE_DOMAIN (main_type) = build_index_type (maxindex);
|
||||
layout_type (main_type);
|
||||
|
||||
if (quals == 0)
|
||||
type = main_type;
|
||||
else
|
||||
type = c_build_qualified_type (main_type, quals);
|
||||
|
||||
*ptype = type;
|
||||
return failure;
|
||||
}
|
||||
|
||||
#include "gt-c-common.h"
|
||||
|
@ -888,6 +888,8 @@ enum lvalue_use {
|
||||
|
||||
extern void lvalue_error (enum lvalue_use);
|
||||
|
||||
extern int complete_array_type (tree *, tree, bool);
|
||||
|
||||
/* In c-gimplify.c */
|
||||
extern void c_genericize (tree);
|
||||
extern int c_gimplify_expr (tree *, tree *, tree *);
|
||||
|
94
gcc/c-decl.c
94
gcc/c-decl.c
@ -529,7 +529,7 @@ c_finish_incomplete_decl (tree decl)
|
||||
{
|
||||
warning ("%Jarray %qD assumed to have one element", decl, decl);
|
||||
|
||||
complete_array_type (type, NULL_TREE, 1);
|
||||
complete_array_type (&TREE_TYPE (decl), NULL_TREE, true);
|
||||
|
||||
layout_decl (decl, 0);
|
||||
}
|
||||
@ -3168,14 +3168,15 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
|
||||
&& TYPE_DOMAIN (type) == 0
|
||||
&& TREE_CODE (decl) != TYPE_DECL)
|
||||
{
|
||||
int do_default
|
||||
bool do_default
|
||||
= (TREE_STATIC (decl)
|
||||
/* Even if pedantic, an external linkage array
|
||||
may have incomplete type at first. */
|
||||
? pedantic && !TREE_PUBLIC (decl)
|
||||
: !DECL_EXTERNAL (decl));
|
||||
int failure
|
||||
= complete_array_type (type, DECL_INITIAL (decl), do_default);
|
||||
= complete_array_type (&TREE_TYPE (decl), DECL_INITIAL (decl),
|
||||
do_default);
|
||||
|
||||
/* Get the completed type made by complete_array_type. */
|
||||
type = TREE_TYPE (decl);
|
||||
@ -3196,14 +3197,12 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
|
||||
else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl))
|
||||
DECL_EXTERNAL (decl) = 1;
|
||||
}
|
||||
|
||||
/* TYPE_MAX_VALUE is always one less than the number of elements
|
||||
in the array, because we start counting at zero. Therefore,
|
||||
warn only if the value is less than zero. */
|
||||
else if (pedantic && TYPE_DOMAIN (type) != 0
|
||||
&& tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) < 0)
|
||||
else if (failure == 3)
|
||||
error ("%Jzero or negative size array %qD", decl, decl);
|
||||
|
||||
if (DECL_INITIAL (decl))
|
||||
TREE_TYPE (DECL_INITIAL (decl)) = type;
|
||||
|
||||
layout_decl (decl, 0);
|
||||
}
|
||||
|
||||
@ -3491,17 +3490,19 @@ build_compound_literal (tree type, tree init)
|
||||
|
||||
if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
|
||||
{
|
||||
int failure = complete_array_type (type, DECL_INITIAL (decl), 1);
|
||||
|
||||
int failure = complete_array_type (&TREE_TYPE (decl),
|
||||
DECL_INITIAL (decl), true);
|
||||
gcc_assert (!failure);
|
||||
|
||||
type = TREE_TYPE (decl);
|
||||
TREE_TYPE (DECL_INITIAL (decl)) = type;
|
||||
}
|
||||
|
||||
type = TREE_TYPE (decl);
|
||||
if (type == error_mark_node || !COMPLETE_TYPE_P (type))
|
||||
return error_mark_node;
|
||||
|
||||
stmt = build_stmt (DECL_EXPR, decl);
|
||||
complit = build1 (COMPOUND_LITERAL_EXPR, TREE_TYPE (decl), stmt);
|
||||
complit = build1 (COMPOUND_LITERAL_EXPR, type, stmt);
|
||||
TREE_SIDE_EFFECTS (complit) = 1;
|
||||
|
||||
layout_decl (decl, 0);
|
||||
@ -3527,73 +3528,6 @@ build_compound_literal (tree type, tree init)
|
||||
return complit;
|
||||
}
|
||||
|
||||
/* Make TYPE a complete type based on INITIAL_VALUE.
|
||||
Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered,
|
||||
2 if there was no information (in which case assume 1 if DO_DEFAULT). */
|
||||
|
||||
int
|
||||
complete_array_type (tree type, tree initial_value, int do_default)
|
||||
{
|
||||
tree maxindex = NULL_TREE;
|
||||
int value = 0;
|
||||
|
||||
if (initial_value)
|
||||
{
|
||||
/* Note MAXINDEX is really the maximum index,
|
||||
one less than the size. */
|
||||
if (TREE_CODE (initial_value) == STRING_CST)
|
||||
{
|
||||
int eltsize
|
||||
= int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value)));
|
||||
maxindex = build_int_cst (NULL_TREE,
|
||||
(TREE_STRING_LENGTH (initial_value)
|
||||
/ eltsize) - 1);
|
||||
}
|
||||
else if (TREE_CODE (initial_value) == CONSTRUCTOR)
|
||||
{
|
||||
tree elts = CONSTRUCTOR_ELTS (initial_value);
|
||||
maxindex = build_int_cst (NULL_TREE, -1);
|
||||
for (; elts; elts = TREE_CHAIN (elts))
|
||||
{
|
||||
if (TREE_PURPOSE (elts))
|
||||
maxindex = TREE_PURPOSE (elts);
|
||||
else
|
||||
maxindex = fold (build2 (PLUS_EXPR, integer_type_node,
|
||||
maxindex, integer_one_node));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Make an error message unless that happened already. */
|
||||
if (initial_value != error_mark_node)
|
||||
value = 1;
|
||||
|
||||
/* Prevent further error messages. */
|
||||
maxindex = build_int_cst (NULL_TREE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!maxindex)
|
||||
{
|
||||
if (do_default)
|
||||
maxindex = build_int_cst (NULL_TREE, 0);
|
||||
value = 2;
|
||||
}
|
||||
|
||||
if (maxindex)
|
||||
{
|
||||
TYPE_DOMAIN (type) = build_index_type (maxindex);
|
||||
|
||||
gcc_assert (TREE_TYPE (maxindex));
|
||||
}
|
||||
|
||||
/* Lay out the type now that we can get the real answer. */
|
||||
|
||||
layout_type (type);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Determine whether TYPE is a structure with a flexible array member,
|
||||
or a union containing such a structure (possibly recursively). */
|
||||
|
||||
|
@ -378,7 +378,6 @@ extern struct c_declarator *build_array_declarator (tree, struct c_declspecs *,
|
||||
extern tree build_enumerator (tree, tree);
|
||||
extern void check_for_loop_decls (void);
|
||||
extern void mark_forward_parm_decls (void);
|
||||
extern int complete_array_type (tree, tree, int);
|
||||
extern void declare_parm_level (void);
|
||||
extern void undeclared_variable (tree, location_t);
|
||||
extern tree declare_label (tree);
|
||||
|
@ -1,3 +1,10 @@
|
||||
2005-03-29 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR c/20519
|
||||
* decl.c (cp_complete_array_type): Rename from complete_array_type.
|
||||
Use the new complete_array_type in c-common.c. Update all callers.
|
||||
* cp-tree.h (cp_complete_array_type): Update to match.
|
||||
|
||||
2005-03-24 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* typeck.c (build_static_cast_1): Allow scalar_cast between
|
||||
|
@ -3787,7 +3787,7 @@ extern tree start_decl (const cp_declarator *, cp_decl_specifier_seq *, int,
|
||||
extern void start_decl_1 (tree);
|
||||
extern void cp_finish_decl (tree, tree, tree, int);
|
||||
extern void finish_decl (tree, tree, tree);
|
||||
extern int complete_array_type (tree, tree, int);
|
||||
extern int cp_complete_array_type (tree *, tree, bool);
|
||||
extern tree build_ptrmemfunc_type (tree);
|
||||
extern tree build_ptrmem_type (tree, tree);
|
||||
/* the grokdeclarator prototype is in decl.h */
|
||||
|
@ -3913,7 +3913,8 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
|
||||
But let's leave it here to ease the eventual merge. */
|
||||
int do_default = !DECL_EXTERNAL (decl);
|
||||
tree initializer = init ? init : DECL_INITIAL (decl);
|
||||
int failure = complete_array_type (type, initializer, do_default);
|
||||
int failure = cp_complete_array_type (&TREE_TYPE (decl), initializer,
|
||||
do_default);
|
||||
|
||||
if (failure == 1)
|
||||
error ("initializer fails to determine size of %qD", decl);
|
||||
@ -5331,102 +5332,41 @@ expand_static_init (tree decl, tree init)
|
||||
3 if the initializer list is empty (in pedantic mode). */
|
||||
|
||||
int
|
||||
complete_array_type (tree type, tree initial_value, int do_default)
|
||||
cp_complete_array_type (tree *ptype, tree initial_value, bool do_default)
|
||||
{
|
||||
tree maxindex = NULL_TREE;
|
||||
int value = 0;
|
||||
int failure;
|
||||
tree type, elt_type;
|
||||
|
||||
if (initial_value)
|
||||
{
|
||||
/* An array of character type can be initialized from a
|
||||
brace-enclosed string constant. */
|
||||
if (char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type)))
|
||||
if (char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (*ptype)))
|
||||
&& TREE_CODE (initial_value) == CONSTRUCTOR
|
||||
&& CONSTRUCTOR_ELTS (initial_value)
|
||||
&& (TREE_CODE (TREE_VALUE (CONSTRUCTOR_ELTS (initial_value)))
|
||||
== STRING_CST)
|
||||
&& TREE_CHAIN (CONSTRUCTOR_ELTS (initial_value)) == NULL_TREE)
|
||||
initial_value = TREE_VALUE (CONSTRUCTOR_ELTS (initial_value));
|
||||
|
||||
/* Note MAXINDEX is really the maximum index, one less than the
|
||||
size. */
|
||||
if (TREE_CODE (initial_value) == STRING_CST)
|
||||
{
|
||||
int eltsize
|
||||
= int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value)));
|
||||
maxindex = build_int_cst (NULL_TREE,
|
||||
(TREE_STRING_LENGTH (initial_value)
|
||||
/ eltsize) - 1);
|
||||
}
|
||||
else if (TREE_CODE (initial_value) == CONSTRUCTOR)
|
||||
{
|
||||
tree elts = CONSTRUCTOR_ELTS (initial_value);
|
||||
|
||||
maxindex = ssize_int (-1);
|
||||
for (; elts; elts = TREE_CHAIN (elts))
|
||||
{
|
||||
if (TREE_PURPOSE (elts))
|
||||
maxindex = TREE_PURPOSE (elts);
|
||||
else
|
||||
maxindex = size_binop (PLUS_EXPR, maxindex, ssize_int (1));
|
||||
}
|
||||
|
||||
if (pedantic && tree_int_cst_equal (maxindex, ssize_int (-1)))
|
||||
value = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Make an error message unless that happened already. */
|
||||
if (initial_value != error_mark_node)
|
||||
value = 1;
|
||||
else
|
||||
initial_value = NULL_TREE;
|
||||
|
||||
/* Prevent further error messages. */
|
||||
maxindex = build_int_cst (NULL_TREE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!maxindex)
|
||||
failure = complete_array_type (ptype, initial_value, do_default);
|
||||
|
||||
/* We can create the array before the element type is complete, which
|
||||
means that we didn't have these two bits set in the original type
|
||||
either. In completing the type, we are expected to propagate these
|
||||
bits. See also complete_type which does the same thing for arrays
|
||||
of fixed size. */
|
||||
type = *ptype;
|
||||
if (TYPE_DOMAIN (type))
|
||||
{
|
||||
if (do_default)
|
||||
maxindex = build_int_cst (NULL_TREE, 0);
|
||||
value = 2;
|
||||
}
|
||||
|
||||
if (maxindex)
|
||||
{
|
||||
tree itype;
|
||||
tree domain;
|
||||
tree elt_type;
|
||||
|
||||
domain = build_index_type (maxindex);
|
||||
TYPE_DOMAIN (type) = domain;
|
||||
|
||||
if (initial_value)
|
||||
itype = TREE_TYPE (initial_value);
|
||||
else
|
||||
itype = NULL;
|
||||
if (itype && !TYPE_DOMAIN (itype))
|
||||
TYPE_DOMAIN (itype) = domain;
|
||||
/* The type of the main variant should never be used for arrays
|
||||
of different sizes. It should only ever be completed with the
|
||||
size of the array. */
|
||||
if (! TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)))
|
||||
TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)) = domain;
|
||||
|
||||
elt_type = TREE_TYPE (type);
|
||||
TYPE_NEEDS_CONSTRUCTING (type)
|
||||
= TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (elt_type));
|
||||
TYPE_NEEDS_CONSTRUCTING (type) = TYPE_NEEDS_CONSTRUCTING (elt_type);
|
||||
TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
|
||||
= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (elt_type));
|
||||
= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (elt_type);
|
||||
}
|
||||
|
||||
/* Lay out the type now that we can get the real answer. */
|
||||
|
||||
layout_type (type);
|
||||
|
||||
return value;
|
||||
return failure;
|
||||
}
|
||||
|
||||
/* Return zero if something is declared to be a member of type
|
||||
|
@ -1996,7 +1996,8 @@ finish_compound_literal (tree type, tree initializer_list)
|
||||
|
||||
implies that the array has two elements. */
|
||||
if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
|
||||
complete_array_type (type, compound_literal, 1);
|
||||
cp_complete_array_type (&TREE_TYPE (compound_literal),
|
||||
compound_literal, 1);
|
||||
}
|
||||
|
||||
return compound_literal;
|
||||
|
@ -1123,7 +1123,7 @@ process_init_constructor (tree type, tree init, tree* elts)
|
||||
|
||||
result = build_constructor (type, nreverse (members));
|
||||
if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE)
|
||||
complete_array_type (type, result, /*do_default=*/0);
|
||||
cp_complete_array_type (&TREE_TYPE (result), result, /*do_default=*/0);
|
||||
if (init)
|
||||
TREE_HAS_CONSTRUCTOR (result) = TREE_HAS_CONSTRUCTOR (init);
|
||||
if (allconstant)
|
||||
|
Loading…
x
Reference in New Issue
Block a user