2
0
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:
Richard Henderson 2005-03-29 17:35:15 -08:00 committed by Richard Henderson
parent 748e31c326
commit aab038d54a
10 changed files with 151 additions and 162 deletions

@ -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 *);

@ -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)