re PR c++/27819 (ICE casting static const variables)
PR c++/27819 * decl.c (cp_finish_decl): Process initializers for static data members with non-dependent initializers, even in templates. PR c++/27722 * decl.c (maybe_deduce_size_from_array_init): If the declaration is erroneous, give it an erroneous type. (layout_var_decl): If the type is erroneous, give up. (check_initializer): Likewise. PR c++/27807 * cp-tree.h (TYPE_OBJ_P): New macro. (TYPE_PTROB_P): Use it. (TYPE_REF_OBJ_P): Likewise. * semantics.c (finish_compound_literal): Do not permit compound literals of non-object types. PR c++/27806 * typeck.c (original_type): Robustify. PR c++/27819 * g++.dg/template/static25.C: New test. PR c++/27722 * g++.dg/init/array21.C: New test. PR c++/27807 * g++.dg/ext/complit7.C: New test. PR c++/27806 * g++.dg/parse/ptrmem5.C: New test. From-SVN: r114382
This commit is contained in:
parent
b42b286aa6
commit
2b643edaf8
10 changed files with 159 additions and 50 deletions
|
@ -1,3 +1,25 @@
|
|||
2006-06-04 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/27819
|
||||
* decl.c (cp_finish_decl): Process initializers for static data
|
||||
members with non-dependent initializers, even in templates.
|
||||
|
||||
PR c++/27722
|
||||
* decl.c (maybe_deduce_size_from_array_init): If the declaration
|
||||
is erroneous, give it an erroneous type.
|
||||
(layout_var_decl): If the type is erroneous, give up.
|
||||
(check_initializer): Likewise.
|
||||
|
||||
PR c++/27807
|
||||
* cp-tree.h (TYPE_OBJ_P): New macro.
|
||||
(TYPE_PTROB_P): Use it.
|
||||
(TYPE_REF_OBJ_P): Likewise.
|
||||
* semantics.c (finish_compound_literal): Do not permit compound
|
||||
literals of non-object types.
|
||||
|
||||
PR c++/27806
|
||||
* typeck.c (original_type): Robustify.
|
||||
|
||||
2006-06-05 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
|
||||
|
||||
PR c++/27804
|
||||
|
|
|
@ -2515,30 +2515,43 @@ extern void decl_shadowed_for_var_insert (tree, tree);
|
|||
/* Returns true if NODE is a pointer. */
|
||||
#define TYPE_PTR_P(NODE) \
|
||||
(TREE_CODE (NODE) == POINTER_TYPE)
|
||||
|
||||
/* Returns true if NODE is an object type:
|
||||
|
||||
[basic.types]
|
||||
|
||||
An object type is a (possibly cv-qualified) type that is not a
|
||||
function type, not a reference type, and not a void type.
|
||||
|
||||
Keep these checks in ascending order, for speed. */
|
||||
#define TYPE_OBJ_P(NODE) \
|
||||
(TREE_CODE (NODE) != REFERENCE_TYPE \
|
||||
&& TREE_CODE (NODE) != VOID_TYPE \
|
||||
&& TREE_CODE (NODE) != FUNCTION_TYPE \
|
||||
&& TREE_CODE (NODE) != METHOD_TYPE)
|
||||
|
||||
/* Returns true if NODE is a pointer to an object. Keep these checks
|
||||
in ascending tree code order. */
|
||||
#define TYPE_PTROB_P(NODE) \
|
||||
(TYPE_PTR_P (NODE) \
|
||||
&& !(TREE_CODE (TREE_TYPE (NODE)) == VOID_TYPE \
|
||||
|| TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE \
|
||||
|| TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE))
|
||||
(TYPE_PTR_P (NODE) && TYPE_OBJ_P (TREE_TYPE (NODE)))
|
||||
|
||||
/* Returns true if NODE is a reference to an object. Keep these checks
|
||||
in ascending tree code order. */
|
||||
#define TYPE_REF_OBJ_P(NODE) \
|
||||
(TREE_CODE (NODE) == REFERENCE_TYPE \
|
||||
&& !(TREE_CODE (TREE_TYPE (NODE)) == VOID_TYPE \
|
||||
|| TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE \
|
||||
|| TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE))
|
||||
(TREE_CODE (NODE) == REFERENCE_TYPE && TYPE_OBJ_P (TREE_TYPE (NODE)))
|
||||
|
||||
/* Returns true if NODE is a pointer to an object, or a pointer to
|
||||
void. Keep these checks in ascending tree code order. */
|
||||
#define TYPE_PTROBV_P(NODE) \
|
||||
(TYPE_PTR_P (NODE) \
|
||||
&& !(TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE \
|
||||
|| TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE))
|
||||
|
||||
/* Returns true if NODE is a pointer to function. */
|
||||
#define TYPE_PTRFN_P(NODE) \
|
||||
(TREE_CODE (NODE) == POINTER_TYPE \
|
||||
&& TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE)
|
||||
|
||||
/* Returns true if NODE is a reference to function. */
|
||||
#define TYPE_REFFN_P(NODE) \
|
||||
(TREE_CODE (NODE) == REFERENCE_TYPE \
|
||||
|
|
101
gcc/cp/decl.c
101
gcc/cp/decl.c
|
@ -4111,12 +4111,17 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
|
|||
do_default);
|
||||
|
||||
if (failure == 1)
|
||||
error ("initializer fails to determine size of %qD", decl);
|
||||
|
||||
if (failure == 2)
|
||||
{
|
||||
error ("initializer fails to determine size of %qD", decl);
|
||||
TREE_TYPE (decl) = error_mark_node;
|
||||
}
|
||||
else if (failure == 2)
|
||||
{
|
||||
if (do_default)
|
||||
error ("array size missing in %qD", decl);
|
||||
{
|
||||
error ("array size missing in %qD", decl);
|
||||
TREE_TYPE (decl) = error_mark_node;
|
||||
}
|
||||
/* If a `static' var's size isn't known, make it extern as
|
||||
well as static, so it does not get allocated. If it's not
|
||||
`static', then don't mark it extern; finish_incomplete_decl
|
||||
|
@ -4124,9 +4129,11 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
|
|||
else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl))
|
||||
DECL_EXTERNAL (decl) = 1;
|
||||
}
|
||||
|
||||
if (failure == 3)
|
||||
error ("zero-size array %qD", decl);
|
||||
else if (failure == 3)
|
||||
{
|
||||
error ("zero-size array %qD", decl);
|
||||
TREE_TYPE (decl) = error_mark_node;
|
||||
}
|
||||
|
||||
cp_apply_type_quals_to_decl (cp_type_quals (TREE_TYPE (decl)), decl);
|
||||
|
||||
|
@ -4140,7 +4147,17 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
|
|||
static void
|
||||
layout_var_decl (tree decl)
|
||||
{
|
||||
tree type = TREE_TYPE (decl);
|
||||
tree type;
|
||||
|
||||
if (TREE_STATIC (decl)
|
||||
&& !DECL_ARTIFICIAL (decl)
|
||||
&& current_function_decl
|
||||
&& DECL_CONTEXT (decl) == current_function_decl)
|
||||
push_local_name (decl);
|
||||
|
||||
type = TREE_TYPE (decl);
|
||||
if (type == error_mark_node)
|
||||
return;
|
||||
|
||||
/* If we haven't already layed out this declaration, do so now.
|
||||
Note that we must not call complete type for an external object
|
||||
|
@ -4186,12 +4203,6 @@ layout_var_decl (tree decl)
|
|||
else
|
||||
error ("storage size of %qD isn't constant", decl);
|
||||
}
|
||||
|
||||
if (TREE_STATIC (decl)
|
||||
&& !DECL_ARTIFICIAL (decl)
|
||||
&& current_function_decl
|
||||
&& DECL_CONTEXT (decl) == current_function_decl)
|
||||
push_local_name (decl);
|
||||
}
|
||||
|
||||
/* If a local static variable is declared in an inline function, or if
|
||||
|
@ -4714,6 +4725,8 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
|
|||
array size from the initializer. */
|
||||
maybe_deduce_size_from_array_init (decl, init);
|
||||
type = TREE_TYPE (decl);
|
||||
if (type == error_mark_node)
|
||||
return NULL_TREE;
|
||||
|
||||
if (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type))
|
||||
{
|
||||
|
@ -4977,6 +4990,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
|
|||
const char *asmspec = NULL;
|
||||
int was_readonly = 0;
|
||||
bool var_definition_p = false;
|
||||
int saved_processing_template_decl;
|
||||
|
||||
if (decl == error_mark_node)
|
||||
return;
|
||||
|
@ -4988,9 +5002,16 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
|
|||
}
|
||||
|
||||
gcc_assert (TREE_CODE (decl) != RESULT_DECL);
|
||||
/* Parameters are handled by store_parm_decls, not cp_finish_decl. */
|
||||
gcc_assert (TREE_CODE (decl) != PARM_DECL);
|
||||
|
||||
type = TREE_TYPE (decl);
|
||||
if (type == error_mark_node)
|
||||
return;
|
||||
|
||||
/* Assume no cleanup is required. */
|
||||
cleanup = NULL_TREE;
|
||||
saved_processing_template_decl = processing_template_decl;
|
||||
|
||||
/* If a name was specified, get the string. */
|
||||
if (global_scope_p (current_binding_level))
|
||||
|
@ -4998,51 +5019,48 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
|
|||
if (asmspec_tree)
|
||||
asmspec = TREE_STRING_POINTER (asmspec_tree);
|
||||
|
||||
if (init && TREE_CODE (init) == NAMESPACE_DECL)
|
||||
{
|
||||
error ("cannot initialize %qD to namespace %qD", decl, init);
|
||||
init = NULL_TREE;
|
||||
}
|
||||
|
||||
if (current_class_type
|
||||
&& CP_DECL_CONTEXT (decl) == current_class_type
|
||||
&& TYPE_BEING_DEFINED (current_class_type)
|
||||
&& (DECL_INITIAL (decl) || init))
|
||||
DECL_INITIALIZED_IN_CLASS_P (decl) = 1;
|
||||
|
||||
type = TREE_TYPE (decl);
|
||||
|
||||
if (type == error_mark_node)
|
||||
goto finish_end;
|
||||
|
||||
if (processing_template_decl)
|
||||
{
|
||||
bool type_dependent_p;
|
||||
|
||||
/* Add this declaration to the statement-tree. */
|
||||
if (at_function_scope_p ())
|
||||
add_decl_expr (decl);
|
||||
|
||||
if (init)
|
||||
type_dependent_p = dependent_type_p (type);
|
||||
|
||||
if (init && init_const_expr_p)
|
||||
{
|
||||
DECL_INITIAL (decl) = init;
|
||||
if (init_const_expr_p)
|
||||
{
|
||||
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
|
||||
if (DECL_INTEGRAL_CONSTANT_VAR_P (decl))
|
||||
TREE_CONSTANT (decl) = 1;
|
||||
}
|
||||
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
|
||||
if (DECL_INTEGRAL_CONSTANT_VAR_P (decl))
|
||||
TREE_CONSTANT (decl) = 1;
|
||||
}
|
||||
|
||||
if (TREE_CODE (decl) == VAR_DECL
|
||||
&& !DECL_PRETTY_FUNCTION_P (decl)
|
||||
&& !dependent_type_p (TREE_TYPE (decl)))
|
||||
maybe_deduce_size_from_array_init (decl, init);
|
||||
if (!init
|
||||
|| !DECL_CLASS_SCOPE_P (decl)
|
||||
|| !DECL_INTEGRAL_CONSTANT_VAR_P (decl)
|
||||
|| type_dependent_p
|
||||
|| value_dependent_expression_p (init))
|
||||
{
|
||||
if (init)
|
||||
DECL_INITIAL (decl) = init;
|
||||
if (TREE_CODE (decl) == VAR_DECL
|
||||
&& !DECL_PRETTY_FUNCTION_P (decl)
|
||||
&& !type_dependent_p)
|
||||
maybe_deduce_size_from_array_init (decl, init);
|
||||
goto finish_end;
|
||||
}
|
||||
|
||||
goto finish_end;
|
||||
init = fold_non_dependent_expr (init);
|
||||
processing_template_decl = 0;
|
||||
}
|
||||
|
||||
/* Parameters are handled by store_parm_decls, not cp_finish_decl. */
|
||||
gcc_assert (TREE_CODE (decl) != PARM_DECL);
|
||||
|
||||
/* Take care of TYPE_DECLs up front. */
|
||||
if (TREE_CODE (decl) == TYPE_DECL)
|
||||
{
|
||||
|
@ -5236,6 +5254,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
|
|||
push_cleanup (decl, cleanup, false);
|
||||
|
||||
finish_end:
|
||||
processing_template_decl = saved_processing_template_decl;
|
||||
|
||||
if (was_readonly)
|
||||
TREE_READONLY (decl) = 1;
|
||||
|
|
|
@ -2021,6 +2021,12 @@ finish_compound_literal (tree type, VEC(constructor_elt,gc) *initializer_list)
|
|||
tree var;
|
||||
tree compound_literal;
|
||||
|
||||
if (!TYPE_OBJ_P (type))
|
||||
{
|
||||
error ("compound literal of non-object type %qT", type);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* Build a CONSTRUCTOR for the INITIALIZER_LIST. */
|
||||
compound_literal = build_constructor (NULL_TREE, initializer_list);
|
||||
if (processing_template_decl)
|
||||
|
|
|
@ -228,7 +228,8 @@ commonparms (tree p1, tree p2)
|
|||
static tree
|
||||
original_type (tree t)
|
||||
{
|
||||
while (TYPE_NAME (t) != NULL_TREE)
|
||||
while (t != error_mark_node
|
||||
&& TYPE_NAME (t) != NULL_TREE)
|
||||
{
|
||||
tree x = TYPE_NAME (t);
|
||||
if (TREE_CODE (x) != TYPE_DECL)
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
2006-06-04 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/27819
|
||||
* g++.dg/template/static25.C: New test.
|
||||
|
||||
PR c++/27722
|
||||
* g++.dg/init/array21.C: New test.
|
||||
|
||||
PR c++/27807
|
||||
* g++.dg/ext/complit7.C: New test.
|
||||
|
||||
PR c++/27806
|
||||
* g++.dg/parse/ptrmem5.C: New test.
|
||||
|
||||
2006-06-04 Roger Sayle <roger@eyesopen.com>
|
||||
Andrew Pinski <pinskia@physics.uc.edu>
|
||||
|
||||
|
|
4
gcc/testsuite/g++.dg/ext/complit7.C
Normal file
4
gcc/testsuite/g++.dg/ext/complit7.C
Normal file
|
@ -0,0 +1,4 @@
|
|||
// PR c++/27807
|
||||
// { dg-options "" }
|
||||
|
||||
int i = (int()){0}; // { dg-error "type" }
|
7
gcc/testsuite/g++.dg/init/array21.C
Normal file
7
gcc/testsuite/g++.dg/init/array21.C
Normal file
|
@ -0,0 +1,7 @@
|
|||
// PR c++/27722
|
||||
|
||||
void foo()
|
||||
{
|
||||
const int x[] = 0; // { dg-error "size" }
|
||||
++x;
|
||||
}
|
9
gcc/testsuite/g++.dg/parse/ptrmem5.C
Normal file
9
gcc/testsuite/g++.dg/parse/ptrmem5.C
Normal file
|
@ -0,0 +1,9 @@
|
|||
// PR c++/27806
|
||||
|
||||
struct A {};
|
||||
|
||||
void foo()
|
||||
{
|
||||
p; // { dg-error "p" }
|
||||
extern int A::* p;
|
||||
}
|
14
gcc/testsuite/g++.dg/template/static25.C
Normal file
14
gcc/testsuite/g++.dg/template/static25.C
Normal file
|
@ -0,0 +1,14 @@
|
|||
// PR c++/27819
|
||||
|
||||
struct A
|
||||
{
|
||||
static const char i = 1;
|
||||
};
|
||||
|
||||
template<int> struct B
|
||||
{
|
||||
static const int j = A::i;
|
||||
int x[int(j)];
|
||||
};
|
||||
|
||||
B<0> b;
|
Loading…
Add table
Reference in a new issue