re PR c++/26266 (Trouble with static const data members in template classes)
PR c++/26266 * cp-tree.h (cp_finish_decl): Adjust declaration. (grokbitfield): Likewise. (finish_static_data_member_decl): Likewise. * init.c (constant_value_1): Ensure processing_template_decl when folding non-dependent initializers for static data members of dependent types. Return error_mark_node for erroneous initailizers. * class.c (get_vtable_decl): Use finish_decl, not cp_finish_decl. * decl.c (cp_make_fname_decl): Adjust call to cp_finish_decl. (cp_finish_decl): Add init_const_expr_p parameter. Set DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P here. (finish_decl): Adjust call to cp_finish_decl. (compute_array_index_type): Robustify. (start_method): Use finish_decl, not cp_finish_decl. * rtti.c (emit_tinfo_decl): Likewise. * except.c (initialize_handler_parm): Adjust call to cp_finish_decl. (expand_start_catch_block): Likewise. * cvt.c (build_up_reference): Adjust call to cp_finish_decl. * pt.c (instantiate_class_template): Adjust call to finish_static_data_member_decl. (tsubst_expr): Use finish_decl, not cp_finish_decl. (instantiate_decl): Adjust call to cp_finish_decl. * name-lookup.c (pushdecl_top_level_1): Use finish_decl, not cp_finish_decl. * decl2.c (finish_static_data_member_decl): Add init_const_expr_p parameter. (grokfield): Likewise. * parser.c (cp_parser_condition): Check for constant initializers. (cp_parser_init_declarator): Adjust calls to grokfield and cp_finish_decl. Don't set DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P here. (cp_parser_member_declaration): Likewise. (cp_parser_objc_class_ivars): Likewise. PR c++/26266 * g++.dg/template/static22.C: New test. * g++.dg/template/static23.C: New test. * g++.dg/template/static24.C: New test. * g++.dg/template/non-dependent13.C: New test. From-SVN: r111229
This commit is contained in:
parent
8305d7868d
commit
d174af6c58
@ -1,3 +1,41 @@
|
||||
2006-02-18 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/26266
|
||||
* cp-tree.h (cp_finish_decl): Adjust declaration.
|
||||
(grokbitfield): Likewise.
|
||||
(finish_static_data_member_decl): Likewise.
|
||||
* init.c (constant_value_1): Ensure processing_template_decl when
|
||||
folding non-dependent initializers for static data members of
|
||||
dependent types. Return error_mark_node for erroneous
|
||||
initailizers.
|
||||
* class.c (get_vtable_decl): Use finish_decl, not cp_finish_decl.
|
||||
* decl.c (cp_make_fname_decl): Adjust call to cp_finish_decl.
|
||||
(cp_finish_decl): Add init_const_expr_p parameter. Set
|
||||
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P here.
|
||||
(finish_decl): Adjust call to cp_finish_decl.
|
||||
(compute_array_index_type): Robustify.
|
||||
(start_method): Use finish_decl, not cp_finish_decl.
|
||||
* rtti.c (emit_tinfo_decl): Likewise.
|
||||
* except.c (initialize_handler_parm): Adjust call to
|
||||
cp_finish_decl.
|
||||
(expand_start_catch_block): Likewise.
|
||||
* cvt.c (build_up_reference): Adjust call to cp_finish_decl.
|
||||
* pt.c (instantiate_class_template): Adjust call to
|
||||
finish_static_data_member_decl.
|
||||
(tsubst_expr): Use finish_decl, not cp_finish_decl.
|
||||
(instantiate_decl): Adjust call to cp_finish_decl.
|
||||
* name-lookup.c (pushdecl_top_level_1): Use finish_decl, not
|
||||
cp_finish_decl.
|
||||
* decl2.c (finish_static_data_member_decl): Add init_const_expr_p
|
||||
parameter.
|
||||
(grokfield): Likewise.
|
||||
* parser.c (cp_parser_condition): Check for constant initializers.
|
||||
(cp_parser_init_declarator): Adjust calls to grokfield and
|
||||
cp_finish_decl. Don't set
|
||||
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P here.
|
||||
(cp_parser_member_declaration): Likewise.
|
||||
(cp_parser_objc_class_ivars): Likewise.
|
||||
|
||||
2006-02-14 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
|
||||
|
||||
* call.c (standard_conversion): Return NULL instead of 0.
|
||||
|
@ -741,7 +741,7 @@ get_vtable_decl (tree type, int complete)
|
||||
if (complete)
|
||||
{
|
||||
DECL_EXTERNAL (decl) = 1;
|
||||
cp_finish_decl (decl, NULL_TREE, NULL_TREE, 0);
|
||||
finish_decl (decl, NULL_TREE, NULL_TREE);
|
||||
}
|
||||
|
||||
return decl;
|
||||
|
@ -3802,7 +3802,7 @@ extern tree shadow_tag (cp_decl_specifier_seq *);
|
||||
extern tree groktypename (cp_decl_specifier_seq *, const cp_declarator *);
|
||||
extern tree start_decl (const cp_declarator *, cp_decl_specifier_seq *, int, tree, tree, tree *);
|
||||
extern void start_decl_1 (tree);
|
||||
extern void cp_finish_decl (tree, tree, tree, int);
|
||||
extern void cp_finish_decl (tree, tree, bool, tree, int);
|
||||
extern void finish_decl (tree, tree, tree);
|
||||
extern int cp_complete_array_type (tree *, tree, bool);
|
||||
extern tree build_ptrmemfunc_type (tree);
|
||||
@ -3876,7 +3876,7 @@ extern tree delete_sanity (tree, tree, bool, int);
|
||||
extern tree check_classfn (tree, tree, tree);
|
||||
extern void check_member_template (tree);
|
||||
extern tree grokfield (const cp_declarator *, cp_decl_specifier_seq *,
|
||||
tree, tree, tree);
|
||||
tree, bool, tree, tree);
|
||||
extern tree grokbitfield (const cp_declarator *, cp_decl_specifier_seq *,
|
||||
tree);
|
||||
extern void cplus_decl_attributes (tree *, tree, int);
|
||||
@ -3891,7 +3891,7 @@ extern tree build_cleanup (tree);
|
||||
extern tree build_offset_ref_call_from_tree (tree, tree);
|
||||
extern void check_default_args (tree);
|
||||
extern void mark_used (tree);
|
||||
extern void finish_static_data_member_decl (tree, tree, tree, int);
|
||||
extern void finish_static_data_member_decl (tree, tree, bool, tree, int);
|
||||
extern tree cp_build_parm_decl (tree, tree);
|
||||
extern tree get_guard (tree);
|
||||
extern tree get_guard_cond (tree);
|
||||
|
@ -365,7 +365,7 @@ build_up_reference (tree type, tree arg, int flags, tree decl)
|
||||
|
||||
/* Process the initializer for the declaration. */
|
||||
DECL_INITIAL (arg) = targ;
|
||||
cp_finish_decl (arg, targ, NULL_TREE,
|
||||
cp_finish_decl (arg, targ, /*init_const_expr_p=*/false, NULL_TREE,
|
||||
LOOKUP_ONLYCONVERTING|DIRECT_BIND);
|
||||
}
|
||||
else if (!(flags & DIRECT_BIND) && ! lvalue_p (arg))
|
||||
|
@ -3197,7 +3197,8 @@ cp_make_fname_decl (tree id, int type_dep)
|
||||
while (b->level_chain->kind != sk_function_parms)
|
||||
b = b->level_chain;
|
||||
pushdecl_with_scope (decl, b, /*is_friend=*/false);
|
||||
cp_finish_decl (decl, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
|
||||
cp_finish_decl (decl, init, /*init_const_expr_p=*/false, NULL_TREE,
|
||||
LOOKUP_ONLYCONVERTING);
|
||||
}
|
||||
else
|
||||
pushdecl_top_level_and_finish (decl, init);
|
||||
@ -4855,14 +4856,15 @@ initialize_artificial_var (tree decl, tree init)
|
||||
If the length of an array type is not known before,
|
||||
it must be determined now, from the initial value, or it is an error.
|
||||
|
||||
INIT holds the value of an initializer that should be allowed to escape
|
||||
the normal rules.
|
||||
INIT is the initializer (if any) for DECL. If INIT_CONST_EXPR_P is
|
||||
true, then INIT is an integral constant expression.
|
||||
|
||||
FLAGS is LOOKUP_ONLYCONVERTING if the = init syntax was used, else 0
|
||||
if the (init) syntax was used. */
|
||||
|
||||
void
|
||||
cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
|
||||
cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
|
||||
tree asmspec_tree, int flags)
|
||||
{
|
||||
tree type;
|
||||
tree cleanup;
|
||||
@ -4914,7 +4916,16 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
|
||||
add_decl_expr (decl);
|
||||
|
||||
if (init && DECL_INITIAL (decl))
|
||||
DECL_INITIAL (decl) = init;
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (TREE_CODE (decl) == VAR_DECL
|
||||
&& !DECL_PRETTY_FUNCTION_P (decl)
|
||||
&& !dependent_type_p (TREE_TYPE (decl)))
|
||||
@ -4975,7 +4986,15 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
|
||||
&& (!DECL_EXTERNAL (decl) || init))
|
||||
{
|
||||
if (init)
|
||||
DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
|
||||
{
|
||||
DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
|
||||
if (init_const_expr_p)
|
||||
{
|
||||
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
|
||||
if (DECL_INTEGRAL_CONSTANT_VAR_P (decl))
|
||||
TREE_CONSTANT (decl) = 1;
|
||||
}
|
||||
}
|
||||
init = check_initializer (decl, init, flags, &cleanup);
|
||||
/* Thread-local storage cannot be dynamically initialized. */
|
||||
if (DECL_THREAD_LOCAL_P (decl) && init)
|
||||
@ -5127,7 +5146,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
|
||||
void
|
||||
finish_decl (tree decl, tree init, tree asmspec_tree)
|
||||
{
|
||||
cp_finish_decl (decl, init, asmspec_tree, 0);
|
||||
cp_finish_decl (decl, init, /*init_const_expr_p=*/false, asmspec_tree, 0);
|
||||
}
|
||||
|
||||
/* Returns a declaration for a VAR_DECL as if:
|
||||
@ -5152,7 +5171,7 @@ declare_global_var (tree name, tree type)
|
||||
library), then it is possible that our declaration will be merged
|
||||
with theirs by pushdecl. */
|
||||
decl = pushdecl (decl);
|
||||
cp_finish_decl (decl, NULL_TREE, NULL_TREE, 0);
|
||||
finish_decl (decl, NULL_TREE, NULL_TREE);
|
||||
pop_from_top_level ();
|
||||
|
||||
return decl;
|
||||
@ -6274,9 +6293,13 @@ check_static_variable_definition (tree decl, tree type)
|
||||
tree
|
||||
compute_array_index_type (tree name, tree size)
|
||||
{
|
||||
tree type = TREE_TYPE (size);
|
||||
tree type;
|
||||
tree itype;
|
||||
|
||||
if (error_operand_p (size))
|
||||
return error_mark_node;
|
||||
|
||||
type = TREE_TYPE (size);
|
||||
/* The array bound must be an integer type. */
|
||||
if (!dependent_type_p (type) && !INTEGRAL_TYPE_P (type))
|
||||
{
|
||||
@ -11033,7 +11056,7 @@ start_method (cp_decl_specifier_seq *declspecs,
|
||||
grok_special_member_properties (fndecl);
|
||||
}
|
||||
|
||||
cp_finish_decl (fndecl, NULL_TREE, NULL_TREE, 0);
|
||||
finish_decl (fndecl, NULL_TREE, NULL_TREE);
|
||||
|
||||
/* Make a place for the parms. */
|
||||
begin_scope (sk_function_parms, fndecl);
|
||||
|
@ -737,12 +737,12 @@ note_vague_linkage_var (tree var)
|
||||
}
|
||||
|
||||
/* We have just processed the DECL, which is a static data member.
|
||||
Its initializer, if present, is INIT. The ASMSPEC_TREE, if
|
||||
present, is the assembly-language name for the data member.
|
||||
FLAGS is as for cp_finish_decl. */
|
||||
The other parameters are as for cp_finish_decl. */
|
||||
|
||||
void
|
||||
finish_static_data_member_decl (tree decl, tree init, tree asmspec_tree,
|
||||
finish_static_data_member_decl (tree decl,
|
||||
tree init, bool init_const_expr_p,
|
||||
tree asmspec_tree,
|
||||
int flags)
|
||||
{
|
||||
gcc_assert (TREE_PUBLIC (decl));
|
||||
@ -783,31 +783,18 @@ finish_static_data_member_decl (tree decl, tree init, tree asmspec_tree,
|
||||
DECL_INITIAL (decl) = init;
|
||||
DECL_IN_AGGR_P (decl) = 1;
|
||||
|
||||
cp_finish_decl (decl, init, asmspec_tree, flags);
|
||||
cp_finish_decl (decl, init, init_const_expr_p, asmspec_tree, flags);
|
||||
}
|
||||
|
||||
/* Process the specs, declarator (NULL if omitted) and width (NULL if omitted)
|
||||
of a structure component, returning a _DECL node.
|
||||
QUALS is a list of type qualifiers for this decl (such as for declaring
|
||||
const member functions).
|
||||
|
||||
This is done during the parsing of the struct declaration.
|
||||
The _DECL nodes are chained together and the lot of them
|
||||
are ultimately passed to `build_struct' to make the RECORD_TYPE node.
|
||||
|
||||
If class A defines that certain functions in class B are friends, then
|
||||
the way I have set things up, it is B who is interested in permission
|
||||
granted by A. However, it is in A's context that these declarations
|
||||
are parsed. By returning a void_type_node, class A does not attempt
|
||||
to incorporate the declarations of the friends within its structure.
|
||||
|
||||
DO NOT MAKE ANY CHANGES TO THIS CODE WITHOUT MAKING CORRESPONDING
|
||||
CHANGES TO CODE IN `start_method'. */
|
||||
/* DECLARATOR and DECLSPECS correspond to a class member. The othe
|
||||
parameters are as for cp_finish_decl. Return the DECL for the
|
||||
class member declared. */
|
||||
|
||||
tree
|
||||
grokfield (const cp_declarator *declarator,
|
||||
cp_decl_specifier_seq *declspecs,
|
||||
tree init, tree asmspec_tree,
|
||||
tree init, bool init_const_expr_p,
|
||||
tree asmspec_tree,
|
||||
tree attrlist)
|
||||
{
|
||||
tree value;
|
||||
@ -946,8 +933,8 @@ grokfield (const cp_declarator *declarator,
|
||||
switch (TREE_CODE (value))
|
||||
{
|
||||
case VAR_DECL:
|
||||
finish_static_data_member_decl (value, init, asmspec_tree,
|
||||
flags);
|
||||
finish_static_data_member_decl (value, init, init_const_expr_p,
|
||||
asmspec_tree, flags);
|
||||
return value;
|
||||
|
||||
case FIELD_DECL:
|
||||
@ -955,7 +942,8 @@ grokfield (const cp_declarator *declarator,
|
||||
error ("%<asm%> specifiers are not permitted on non-static data members");
|
||||
if (DECL_INITIAL (value) == error_mark_node)
|
||||
init = error_mark_node;
|
||||
cp_finish_decl (value, init, NULL_TREE, flags);
|
||||
cp_finish_decl (value, init, /*init_const_expr_p=*/false,
|
||||
NULL_TREE, flags);
|
||||
DECL_INITIAL (value) = init;
|
||||
DECL_IN_AGGR_P (value) = 1;
|
||||
return value;
|
||||
@ -966,7 +954,8 @@ grokfield (const cp_declarator *declarator,
|
||||
if (!DECL_FRIEND_P (value))
|
||||
grok_special_member_properties (value);
|
||||
|
||||
cp_finish_decl (value, init, asmspec_tree, flags);
|
||||
cp_finish_decl (value, init, /*init_const_expr_p=*/false,
|
||||
asmspec_tree, flags);
|
||||
|
||||
/* Pass friends back this way. */
|
||||
if (DECL_FRIEND_P (value))
|
||||
@ -1025,7 +1014,7 @@ grokbitfield (const cp_declarator *declarator,
|
||||
error ("static member %qD cannot be a bit-field", value);
|
||||
return NULL_TREE;
|
||||
}
|
||||
cp_finish_decl (value, NULL_TREE, NULL_TREE, 0);
|
||||
finish_decl (value, NULL_TREE, NULL_TREE);
|
||||
|
||||
if (width != error_mark_node)
|
||||
{
|
||||
|
@ -397,7 +397,7 @@ initialize_handler_parm (tree decl, tree exp)
|
||||
decl = pushdecl (decl);
|
||||
|
||||
start_decl_1 (decl);
|
||||
cp_finish_decl (decl, init, NULL_TREE,
|
||||
cp_finish_decl (decl, init, /*init_const_expr_p=*/false, NULL_TREE,
|
||||
LOOKUP_ONLYCONVERTING|DIRECT_BIND);
|
||||
}
|
||||
|
||||
@ -461,7 +461,8 @@ expand_start_catch_block (tree decl)
|
||||
tree init = do_begin_catch ();
|
||||
exp = create_temporary_var (ptr_type_node);
|
||||
DECL_REGISTER (exp) = 1;
|
||||
cp_finish_decl (exp, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
|
||||
cp_finish_decl (exp, init, /*init_const_expr=*/false,
|
||||
NULL_TREE, LOOKUP_ONLYCONVERTING);
|
||||
finish_expr_stmt (build_modify_expr (exp, INIT_EXPR, init));
|
||||
initialize_handler_parm (decl, exp);
|
||||
}
|
||||
|
@ -1484,7 +1484,7 @@ constant_value_1 (tree decl, bool integral_p)
|
||||
tree init;
|
||||
/* Static data members in template classes may have
|
||||
non-dependent initializers. References to such non-static
|
||||
data members are no value-dependent, so we must retrieve the
|
||||
data members are not value-dependent, so we must retrieve the
|
||||
initializer here. The DECL_INITIAL will have the right type,
|
||||
but will not have been folded because that would prevent us
|
||||
from performing all appropriate semantic checks at
|
||||
@ -1493,7 +1493,11 @@ constant_value_1 (tree decl, bool integral_p)
|
||||
&& CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (decl))
|
||||
&& uses_template_parms (CLASSTYPE_TI_ARGS
|
||||
(DECL_CONTEXT (decl))))
|
||||
init = fold_non_dependent_expr (DECL_INITIAL (decl));
|
||||
{
|
||||
++processing_template_decl;
|
||||
init = fold_non_dependent_expr (DECL_INITIAL (decl));
|
||||
--processing_template_decl;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If DECL is a static data member in a template
|
||||
@ -1503,7 +1507,9 @@ constant_value_1 (tree decl, bool integral_p)
|
||||
mark_used (decl);
|
||||
init = DECL_INITIAL (decl);
|
||||
}
|
||||
if (!init || init == error_mark_node
|
||||
if (init == error_mark_node)
|
||||
return error_mark_node;
|
||||
if (!init
|
||||
|| !TREE_TYPE (init)
|
||||
|| (integral_p
|
||||
? !INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (init))
|
||||
|
@ -3324,7 +3324,7 @@ pushdecl_top_level_1 (tree x, tree *init, bool is_friend)
|
||||
push_to_top_level ();
|
||||
x = pushdecl_namespace_level (x, is_friend);
|
||||
if (init)
|
||||
cp_finish_decl (x, *init, NULL_TREE, 0);
|
||||
finish_decl (x, *init, NULL_TREE);
|
||||
pop_from_top_level ();
|
||||
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
|
||||
}
|
||||
|
@ -6500,6 +6500,7 @@ cp_parser_condition (cp_parser* parser)
|
||||
if (cp_parser_parse_definitely (parser))
|
||||
{
|
||||
tree pushed_scope;
|
||||
bool non_constant_p;
|
||||
|
||||
/* Create the declaration. */
|
||||
decl = start_decl (declarator, &type_specifiers,
|
||||
@ -6507,12 +6508,16 @@ cp_parser_condition (cp_parser* parser)
|
||||
attributes, /*prefix_attributes=*/NULL_TREE,
|
||||
&pushed_scope);
|
||||
/* Parse the assignment-expression. */
|
||||
initializer = cp_parser_assignment_expression (parser,
|
||||
/*cast_p=*/false);
|
||||
initializer
|
||||
= cp_parser_constant_expression (parser,
|
||||
/*allow_non_constant_p=*/true,
|
||||
&non_constant_p);
|
||||
if (!non_constant_p)
|
||||
initializer = fold_non_dependent_expr (initializer);
|
||||
|
||||
/* Process the initializer. */
|
||||
cp_finish_decl (decl,
|
||||
initializer,
|
||||
initializer, !non_constant_p,
|
||||
asm_specification,
|
||||
LOOKUP_ONLYCONVERTING);
|
||||
|
||||
@ -11061,7 +11066,8 @@ cp_parser_init_declarator (cp_parser* parser,
|
||||
pushed_scope = false;
|
||||
}
|
||||
decl = grokfield (declarator, decl_specifiers,
|
||||
initializer, /*asmspec=*/NULL_TREE,
|
||||
initializer, !is_non_constant_init,
|
||||
/*asmspec=*/NULL_TREE,
|
||||
prefix_attributes);
|
||||
if (decl && TREE_CODE (decl) == FUNCTION_DECL)
|
||||
cp_parser_save_default_args (parser, decl);
|
||||
@ -11072,7 +11078,7 @@ cp_parser_init_declarator (cp_parser* parser,
|
||||
if (!friend_p && decl && decl != error_mark_node)
|
||||
{
|
||||
cp_finish_decl (decl,
|
||||
initializer,
|
||||
initializer, !is_non_constant_init,
|
||||
asm_specification,
|
||||
/* If the initializer is in parentheses, then this is
|
||||
a direct-initialization, which means that an
|
||||
@ -11084,12 +11090,6 @@ cp_parser_init_declarator (cp_parser* parser,
|
||||
if (!friend_p && pushed_scope)
|
||||
pop_scope (pushed_scope);
|
||||
|
||||
/* Remember whether or not variables were initialized by
|
||||
constant-expressions. */
|
||||
if (decl && TREE_CODE (decl) == VAR_DECL
|
||||
&& is_initialized && !is_non_constant_init)
|
||||
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = true;
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
@ -13706,16 +13706,11 @@ cp_parser_member_declaration (cp_parser* parser)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Create the declaration. */
|
||||
decl = grokfield (declarator, &decl_specifiers,
|
||||
initializer, asm_specification,
|
||||
attributes);
|
||||
/* Any initialization must have been from a
|
||||
constant-expression. */
|
||||
if (decl && TREE_CODE (decl) == VAR_DECL && initializer)
|
||||
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
|
||||
}
|
||||
/* Create the declaration. */
|
||||
decl = grokfield (declarator, &decl_specifiers,
|
||||
initializer, /*init_const_expr_p=*/true,
|
||||
asm_specification,
|
||||
attributes);
|
||||
}
|
||||
|
||||
/* Reset PREFIX_ATTRIBUTES. */
|
||||
@ -17278,7 +17273,8 @@ cp_parser_objc_class_ivars (cp_parser* parser)
|
||||
cplus_decl_attributes (&decl, attributes, /*flags=*/0);
|
||||
}
|
||||
else
|
||||
decl = grokfield (declarator, &declspecs, NULL_TREE,
|
||||
decl = grokfield (declarator, &declspecs,
|
||||
NULL_TREE, /*init_const_expr_p=*/false,
|
||||
NULL_TREE, attributes);
|
||||
|
||||
/* Add the instance variable. */
|
||||
|
@ -5743,6 +5743,7 @@ instantiate_class_template (tree type)
|
||||
finish_static_data_member_decl
|
||||
(r,
|
||||
/*init=*/NULL_TREE,
|
||||
/*init_const_expr_p=*/false,
|
||||
/*asmspec_tree=*/NULL_TREE,
|
||||
/*flags=*/0);
|
||||
if (DECL_INITIALIZED_IN_CLASS_P (r))
|
||||
@ -8218,7 +8219,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
||||
}
|
||||
else
|
||||
init = tsubst_expr (init, args, complain, in_decl);
|
||||
cp_finish_decl (decl, init, NULL_TREE, 0);
|
||||
finish_decl (decl, init, NULL_TREE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -11694,7 +11695,8 @@ instantiate_decl (tree d, int defer_ok,
|
||||
args,
|
||||
tf_warning_or_error, NULL_TREE);
|
||||
DECL_INITIAL (d) = init;
|
||||
cp_finish_decl (d, init, /*asmspec_tree=*/NULL_TREE,
|
||||
cp_finish_decl (d, init, /*init_const_expr_p=*/false,
|
||||
/*asmspec_tree=*/NULL_TREE,
|
||||
LOOKUP_ONLYCONVERTING);
|
||||
pop_nested_class ();
|
||||
pop_nested_namespace (ns);
|
||||
@ -11771,7 +11773,7 @@ instantiate_decl (tree d, int defer_ok,
|
||||
|
||||
/* Enter the scope of D so that access-checking works correctly. */
|
||||
push_nested_class (DECL_CONTEXT (d));
|
||||
cp_finish_decl (d, DECL_INITIAL (d), NULL_TREE, 0);
|
||||
finish_decl (d, DECL_INITIAL (d), NULL_TREE);
|
||||
pop_nested_class ();
|
||||
}
|
||||
else if (TREE_CODE (d) == FUNCTION_DECL)
|
||||
|
@ -1482,7 +1482,7 @@ emit_tinfo_decl (tree decl)
|
||||
init = get_pseudo_ti_init (type, get_pseudo_ti_index (type));
|
||||
DECL_INITIAL (decl) = init;
|
||||
mark_used (decl);
|
||||
cp_finish_decl (decl, init, NULL_TREE, 0);
|
||||
finish_decl (decl, init, NULL_TREE);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -1,3 +1,11 @@
|
||||
2006-02-18 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/26266
|
||||
* g++.dg/template/static22.C: New test.
|
||||
* g++.dg/template/static23.C: New test.
|
||||
* g++.dg/template/static24.C: New test.
|
||||
* g++.dg/template/non-dependent13.C: New test.
|
||||
|
||||
2006-02-16 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
|
||||
|
||||
PR target/26255
|
||||
|
11
gcc/testsuite/g++.dg/template/non-dependent13.C
Normal file
11
gcc/testsuite/g++.dg/template/non-dependent13.C
Normal file
@ -0,0 +1,11 @@
|
||||
// PR c++/26266
|
||||
|
||||
template <int I>
|
||||
struct S;
|
||||
|
||||
template <int I>
|
||||
void f() {
|
||||
if (const int i = 3) {
|
||||
S<i>::j; // { dg-error "incomplete" }
|
||||
}
|
||||
}
|
11
gcc/testsuite/g++.dg/template/static22.C
Normal file
11
gcc/testsuite/g++.dg/template/static22.C
Normal file
@ -0,0 +1,11 @@
|
||||
// PR c++/26266
|
||||
|
||||
template<typename> struct A
|
||||
{
|
||||
static const int i = 1;
|
||||
static const int j = i;
|
||||
static const int k = int(j);
|
||||
int x[k];
|
||||
};
|
||||
|
||||
A<char> a;
|
15
gcc/testsuite/g++.dg/template/static23.C
Normal file
15
gcc/testsuite/g++.dg/template/static23.C
Normal file
@ -0,0 +1,15 @@
|
||||
// PR c++/26266
|
||||
|
||||
template<typename> struct A
|
||||
{
|
||||
static const int i = 1;
|
||||
};
|
||||
|
||||
template<typename> struct B
|
||||
{
|
||||
static const int j = A<char>::i;
|
||||
static const int k = int(j);
|
||||
int x[k];
|
||||
};
|
||||
|
||||
B<char> b;
|
15
gcc/testsuite/g++.dg/template/static24.C
Normal file
15
gcc/testsuite/g++.dg/template/static24.C
Normal file
@ -0,0 +1,15 @@
|
||||
template<typename> struct A;
|
||||
|
||||
template<> struct A<char>
|
||||
{
|
||||
static const char i = 1;
|
||||
};
|
||||
|
||||
template<typename T> struct B
|
||||
{
|
||||
static const int j = A<T>::i;
|
||||
static const int k = int(j);
|
||||
int x[k];
|
||||
};
|
||||
|
||||
B<char> b;
|
Loading…
Reference in New Issue
Block a user