Commit cec24319 by Mark Mitchell Committed by Mark Mitchell

re PR c++/9683 (bug in initialization chains for static const variables from template classes)

	PR c++/9683
	* decl2.c (prune_vars_needing_no_initialization): Do not throw
	away initializations for DECL_EXTERNAL VAR_DECLs.
	(finish_file): Adjust accordingly.
	* pt.c (instantiate_decl): Do not defer VAR_DECLs.

	PR c++/9683
	* g++.dg/template/static3.C: New test.

From-SVN: r63455
parent 38a84391
2003-02-25 Mark Mitchell <mark@codesourcery.com>
PR c++/9683
* decl2.c (prune_vars_needing_no_initialization): Do not throw
away initializations for DECL_EXTERNAL VAR_DECLs.
(finish_file): Adjust accordingly.
* pt.c (instantiate_decl): Do not defer VAR_DECLs.
2003-02-24 Gabriel Dos Reis <gdr@integrable-solutions.net> 2003-02-24 Gabriel Dos Reis <gdr@integrable-solutions.net>
* decl.c (add_binding): Time TV_NAME_LOOKUP. * decl.c (add_binding): Time TV_NAME_LOOKUP.
......
...@@ -84,7 +84,7 @@ static void finish_static_initialization_or_destruction (tree); ...@@ -84,7 +84,7 @@ static void finish_static_initialization_or_destruction (tree);
static void generate_ctor_or_dtor_function (bool, int); static void generate_ctor_or_dtor_function (bool, int);
static int generate_ctor_and_dtor_functions_for_priority (splay_tree_node, static int generate_ctor_and_dtor_functions_for_priority (splay_tree_node,
void *); void *);
static tree prune_vars_needing_no_initialization (tree); static tree prune_vars_needing_no_initialization (tree *);
static void write_out_vars (tree); static void write_out_vars (tree);
static void import_export_class (tree); static void import_export_class (tree);
static tree get_guard_bits (tree); static tree get_guard_bits (tree);
...@@ -2400,21 +2400,23 @@ do_static_destruction (tree decl) ...@@ -2400,21 +2400,23 @@ do_static_destruction (tree decl)
i.e., the first variable should be initialized first. */ i.e., the first variable should be initialized first. */
static tree static tree
prune_vars_needing_no_initialization (tree vars) prune_vars_needing_no_initialization (tree *vars)
{ {
tree var; tree *var = vars;
tree result; tree result = NULL_TREE;
for (var = vars, result = NULL_TREE; while (*var)
var;
var = TREE_CHAIN (var))
{ {
tree decl = TREE_VALUE (var); tree t = *var;
tree init = TREE_PURPOSE (var); tree decl = TREE_VALUE (t);
tree init = TREE_PURPOSE (t);
/* Deal gracefully with error. */ /* Deal gracefully with error. */
if (decl == error_mark_node) if (decl == error_mark_node)
continue; {
var = &TREE_CHAIN (t);
continue;
}
/* The only things that can be initialized are variables. */ /* The only things that can be initialized are variables. */
my_friendly_assert (TREE_CODE (decl) == VAR_DECL, 19990420); my_friendly_assert (TREE_CODE (decl) == VAR_DECL, 19990420);
...@@ -2422,17 +2424,25 @@ prune_vars_needing_no_initialization (tree vars) ...@@ -2422,17 +2424,25 @@ prune_vars_needing_no_initialization (tree vars)
/* If this object is not defined, we don't need to do anything /* If this object is not defined, we don't need to do anything
here. */ here. */
if (DECL_EXTERNAL (decl)) if (DECL_EXTERNAL (decl))
continue; {
var = &TREE_CHAIN (t);
continue;
}
/* Also, if the initializer already contains errors, we can bail /* Also, if the initializer already contains errors, we can bail
out now. */ out now. */
if (init && TREE_CODE (init) == TREE_LIST if (init && TREE_CODE (init) == TREE_LIST
&& value_member (error_mark_node, init)) && value_member (error_mark_node, init))
continue; {
var = &TREE_CHAIN (t);
continue;
}
/* This variable is going to need initialization and/or /* This variable is going to need initialization and/or
finalization, so we add it to the list. */ finalization, so we add it to the list. */
result = tree_cons (init, decl, result); *var = TREE_CHAIN (t);
TREE_CHAIN (t) = result;
result = t;
} }
return result; return result;
...@@ -2625,8 +2635,7 @@ finish_file () ...@@ -2625,8 +2635,7 @@ finish_file ()
aggregates added during the initialization of these will be aggregates added during the initialization of these will be
initialized in the correct order when we next come around the initialized in the correct order when we next come around the
loop. */ loop. */
vars = prune_vars_needing_no_initialization (static_aggregates); vars = prune_vars_needing_no_initialization (&static_aggregates);
static_aggregates = NULL_TREE;
if (vars) if (vars)
{ {
......
...@@ -10647,6 +10647,14 @@ instantiate_decl (d, defer_ok) ...@@ -10647,6 +10647,14 @@ instantiate_decl (d, defer_ok)
my_friendly_assert (TREE_CODE (d) == FUNCTION_DECL my_friendly_assert (TREE_CODE (d) == FUNCTION_DECL
|| TREE_CODE (d) == VAR_DECL, 0); || TREE_CODE (d) == VAR_DECL, 0);
/* Variables are never deferred; if instantiation is required, they
are instantiated right away. That allows for better code in the
case that an expression refers to the value of the variable --
if the variable has a constant value the referring expression can
take advantage of that fact. */
if (TREE_CODE (d) == VAR_DECL)
defer_ok = 0;
/* Don't instantiate cloned functions. Instead, instantiate the /* Don't instantiate cloned functions. Instead, instantiate the
functions they cloned. */ functions they cloned. */
if (TREE_CODE (d) == FUNCTION_DECL && DECL_CLONED_FUNCTION_P (d)) if (TREE_CODE (d) == FUNCTION_DECL && DECL_CLONED_FUNCTION_P (d))
......
2003-02-25 Mark Mitchell <mark@codesourcery.com> 2003-02-25 Mark Mitchell <mark@codesourcery.com>
PR c++/9683
* g++.dg/template/static3.C: New test.
PR c++/9829 PR c++/9829
* g++.dg/parse/namespace6.C: New test. * g++.dg/parse/namespace6.C: New test.
......
template <class data> class foo
{
public:
static const int a;
static const int b;
static const int c;
static const int d;
};
template <class data> const int foo<data>::a = 1;
template <class data> const int foo<data>::b = a;
template <class data> const int foo<data>::c = b;
template <class data> const int foo<data>::d = c;
typedef foo<int> fooInt;
int main( void )
{
fooInt *f;
f = new fooInt();
if (f->c != 1 || f->d != 1)
return 1;
}
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