Commit aab038d5 by Richard Henderson Committed by Richard Henderson

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
parent 748e31c3
2005-03-29 Richard Henderson <rth@redhat.com> 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 PR tree-opt/19108
* tree-sra.c (generate_element_init_1): Handle RANGE_EXPR. * tree-sra.c (generate_element_init_1): Handle RANGE_EXPR.
......
...@@ -5756,5 +5756,94 @@ lvalue_error (enum lvalue_use use) ...@@ -5756,5 +5756,94 @@ lvalue_error (enum lvalue_use use)
gcc_unreachable (); 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" #include "gt-c-common.h"
...@@ -888,6 +888,8 @@ enum lvalue_use { ...@@ -888,6 +888,8 @@ enum lvalue_use {
extern void lvalue_error (enum lvalue_use); extern void lvalue_error (enum lvalue_use);
extern int complete_array_type (tree *, tree, bool);
/* In c-gimplify.c */ /* In c-gimplify.c */
extern void c_genericize (tree); extern void c_genericize (tree);
extern int c_gimplify_expr (tree *, tree *, tree *); extern int c_gimplify_expr (tree *, tree *, tree *);
......
...@@ -529,7 +529,7 @@ c_finish_incomplete_decl (tree decl) ...@@ -529,7 +529,7 @@ c_finish_incomplete_decl (tree decl)
{ {
warning ("%Jarray %qD assumed to have one element", decl, 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); layout_decl (decl, 0);
} }
...@@ -3168,14 +3168,15 @@ finish_decl (tree decl, tree init, tree asmspec_tree) ...@@ -3168,14 +3168,15 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
&& TYPE_DOMAIN (type) == 0 && TYPE_DOMAIN (type) == 0
&& TREE_CODE (decl) != TYPE_DECL) && TREE_CODE (decl) != TYPE_DECL)
{ {
int do_default bool do_default
= (TREE_STATIC (decl) = (TREE_STATIC (decl)
/* Even if pedantic, an external linkage array /* Even if pedantic, an external linkage array
may have incomplete type at first. */ may have incomplete type at first. */
? pedantic && !TREE_PUBLIC (decl) ? pedantic && !TREE_PUBLIC (decl)
: !DECL_EXTERNAL (decl)); : !DECL_EXTERNAL (decl));
int failure 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. */ /* Get the completed type made by complete_array_type. */
type = TREE_TYPE (decl); type = TREE_TYPE (decl);
...@@ -3196,14 +3197,12 @@ finish_decl (tree decl, tree init, tree asmspec_tree) ...@@ -3196,14 +3197,12 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl)) else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl))
DECL_EXTERNAL (decl) = 1; DECL_EXTERNAL (decl) = 1;
} }
else if (failure == 3)
/* 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)
error ("%Jzero or negative size array %qD", decl, decl); error ("%Jzero or negative size array %qD", decl, decl);
if (DECL_INITIAL (decl))
TREE_TYPE (DECL_INITIAL (decl)) = type;
layout_decl (decl, 0); layout_decl (decl, 0);
} }
...@@ -3491,17 +3490,19 @@ build_compound_literal (tree type, tree init) ...@@ -3491,17 +3490,19 @@ build_compound_literal (tree type, tree init)
if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type)) 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); 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)) if (type == error_mark_node || !COMPLETE_TYPE_P (type))
return error_mark_node; return error_mark_node;
stmt = build_stmt (DECL_EXPR, decl); 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; TREE_SIDE_EFFECTS (complit) = 1;
layout_decl (decl, 0); layout_decl (decl, 0);
...@@ -3527,73 +3528,6 @@ build_compound_literal (tree type, tree init) ...@@ -3527,73 +3528,6 @@ build_compound_literal (tree type, tree init)
return complit; 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, /* Determine whether TYPE is a structure with a flexible array member,
or a union containing such a structure (possibly recursively). */ or a union containing such a structure (possibly recursively). */
......
...@@ -378,7 +378,6 @@ extern struct c_declarator *build_array_declarator (tree, struct c_declspecs *, ...@@ -378,7 +378,6 @@ extern struct c_declarator *build_array_declarator (tree, struct c_declspecs *,
extern tree build_enumerator (tree, tree); extern tree build_enumerator (tree, tree);
extern void check_for_loop_decls (void); extern void check_for_loop_decls (void);
extern void mark_forward_parm_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 declare_parm_level (void);
extern void undeclared_variable (tree, location_t); extern void undeclared_variable (tree, location_t);
extern tree declare_label (tree); extern tree declare_label (tree);
......
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> 2005-03-24 Geoffrey Keating <geoffk@apple.com>
* typeck.c (build_static_cast_1): Allow scalar_cast between * 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, ...@@ -3787,7 +3787,7 @@ extern tree start_decl (const cp_declarator *, cp_decl_specifier_seq *, int,
extern void start_decl_1 (tree); extern void start_decl_1 (tree);
extern void cp_finish_decl (tree, tree, tree, int); extern void cp_finish_decl (tree, tree, tree, int);
extern void finish_decl (tree, tree, tree); 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_ptrmemfunc_type (tree);
extern tree build_ptrmem_type (tree, tree); extern tree build_ptrmem_type (tree, tree);
/* the grokdeclarator prototype is in decl.h */ /* the grokdeclarator prototype is in decl.h */
......
...@@ -3913,7 +3913,8 @@ maybe_deduce_size_from_array_init (tree decl, tree init) ...@@ -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. */ But let's leave it here to ease the eventual merge. */
int do_default = !DECL_EXTERNAL (decl); int do_default = !DECL_EXTERNAL (decl);
tree initializer = init ? init : DECL_INITIAL (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) if (failure == 1)
error ("initializer fails to determine size of %qD", decl); error ("initializer fails to determine size of %qD", decl);
...@@ -5331,102 +5332,41 @@ expand_static_init (tree decl, tree init) ...@@ -5331,102 +5332,41 @@ expand_static_init (tree decl, tree init)
3 if the initializer list is empty (in pedantic mode). */ 3 if the initializer list is empty (in pedantic mode). */
int 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 failure;
int value = 0; tree type, elt_type;
if (initial_value) if (initial_value)
{ {
/* An array of character type can be initialized from a /* An array of character type can be initialized from a
brace-enclosed string constant. */ 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 && TREE_CODE (initial_value) == CONSTRUCTOR
&& CONSTRUCTOR_ELTS (initial_value) && CONSTRUCTOR_ELTS (initial_value)
&& (TREE_CODE (TREE_VALUE (CONSTRUCTOR_ELTS (initial_value))) && (TREE_CODE (TREE_VALUE (CONSTRUCTOR_ELTS (initial_value)))
== STRING_CST) == STRING_CST)
&& TREE_CHAIN (CONSTRUCTOR_ELTS (initial_value)) == NULL_TREE) && TREE_CHAIN (CONSTRUCTOR_ELTS (initial_value)) == NULL_TREE)
initial_value = TREE_VALUE (CONSTRUCTOR_ELTS (initial_value)); 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);
{
if (do_default)
maxindex = build_int_cst (NULL_TREE, 0);
value = 2;
}
if (maxindex) /* 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))
{ {
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); elt_type = TREE_TYPE (type);
TYPE_NEEDS_CONSTRUCTING (type) TYPE_NEEDS_CONSTRUCTING (type) = TYPE_NEEDS_CONSTRUCTING (elt_type);
= TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (elt_type));
TYPE_HAS_NONTRIVIAL_DESTRUCTOR (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. */ return failure;
layout_type (type);
return value;
} }
/* Return zero if something is declared to be a member of type /* Return zero if something is declared to be a member of type
......
...@@ -1996,7 +1996,8 @@ finish_compound_literal (tree type, tree initializer_list) ...@@ -1996,7 +1996,8 @@ finish_compound_literal (tree type, tree initializer_list)
implies that the array has two elements. */ implies that the array has two elements. */
if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type)) 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; return compound_literal;
......
...@@ -1123,7 +1123,7 @@ process_init_constructor (tree type, tree init, tree* elts) ...@@ -1123,7 +1123,7 @@ process_init_constructor (tree type, tree init, tree* elts)
result = build_constructor (type, nreverse (members)); result = build_constructor (type, nreverse (members));
if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE) 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) if (init)
TREE_HAS_CONSTRUCTOR (result) = TREE_HAS_CONSTRUCTOR (init); TREE_HAS_CONSTRUCTOR (result) = TREE_HAS_CONSTRUCTOR (init);
if (allconstant) if (allconstant)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment