aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-06-20 00:48:44 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-06-20 00:48:44 +0000
commit170b020fe4be4eadea27d389257778d952fb5a13 (patch)
tree18750127388f053e1dd83e7ae5f29fc9e9fe0bfb /gcc/cp
parent7a1d37e9102a1bbc34b4544161ddf283c667bc0b (diff)
downloadgcc-170b020fe4be4eadea27d389257778d952fb5a13.zip
gcc-170b020fe4be4eadea27d389257778d952fb5a13.tar.gz
gcc-170b020fe4be4eadea27d389257778d952fb5a13.tar.bz2
re PR middle-end/11041 (ICE: const myclass &x = *x; (when operator*() defined))
PR c++/11041 * call.c (initialize_reference): Do not use cp_finish_decl to emit temporary variables. * cp-tree.h (static_aggregates): Declare. (pushdecl_top_level_and_finish): Likewise. * decl.c (pushdecl_top_level_1): New function. (pushdecl_top_level): Use it. (pushdecl_top_level_and_finish): New function. (initialize_local_var): Remove redundant code. (cp_finish_decl): Remove support for RESULT_DECLs. Don't check building_stmt_tree. * decl.h (static_aggregates): Remove. * decl2.c (get_guard): Use pushdecl_top_level_and_finish. * rtti.c (get_tinfo_decl): Use pushdecl_top_level_and_finish. (tinfo_base_init): Likewise. PR c++/11041 * g++.dg/init/ref7.C: New test. From-SVN: r68236
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog18
-rw-r--r--gcc/cp/call.c30
-rw-r--r--gcc/cp/cp-tree.h7
-rw-r--r--gcc/cp/decl.c57
-rw-r--r--gcc/cp/decl.h6
-rw-r--r--gcc/cp/decl2.c3
-rw-r--r--gcc/cp/rtti.c6
7 files changed, 87 insertions, 40 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ba1fb35..30e01f2 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,21 @@
+2003-06-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11041
+ * call.c (initialize_reference): Do not use cp_finish_decl to emit
+ temporary variables.
+ * cp-tree.h (static_aggregates): Declare.
+ (pushdecl_top_level_and_finish): Likewise.
+ * decl.c (pushdecl_top_level_1): New function.
+ (pushdecl_top_level): Use it.
+ (pushdecl_top_level_and_finish): New function.
+ (initialize_local_var): Remove redundant code.
+ (cp_finish_decl): Remove support for RESULT_DECLs. Don't check
+ building_stmt_tree.
+ * decl.h (static_aggregates): Remove.
+ * decl2.c (get_guard): Use pushdecl_top_level_and_finish.
+ * rtti.c (get_tinfo_decl): Use pushdecl_top_level_and_finish.
+ (tinfo_base_init): Likewise.
+
2003-06-19 Matt Austern <austern@apple.com>
PR c++/11228
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 589a789..9bc55be 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -6144,7 +6144,7 @@ initialize_reference (tree type, tree expr, tree decl)
T t;
const S& s = t;
- we can extend the lifetime of the returnn value of the conversion
+ we can extend the lifetime of the return value of the conversion
operator. */
my_friendly_assert (TREE_CODE (conv) == REF_BIND, 20030302);
if (decl)
@@ -6167,13 +6167,33 @@ initialize_reference (tree type, tree expr, tree decl)
expr = convert_like (conv, expr);
if (!real_non_cast_lvalue_p (expr))
{
+ tree init;
+ tree type;
+
/* Create the temporary variable. */
- var = make_temporary_var_for_ref_to_temp (decl, TREE_TYPE (expr));
- DECL_INITIAL (var) = expr;
- cp_finish_decl (var, expr, NULL_TREE,
- LOOKUP_ONLYCONVERTING|DIRECT_BIND);
+ type = TREE_TYPE (expr);
+ var = make_temporary_var_for_ref_to_temp (decl, type);
+ layout_decl (var, 0);
+ if (at_function_scope_p ())
+ {
+ tree cleanup;
+
+ add_decl_stmt (var);
+ cleanup = cxx_maybe_build_cleanup (var);
+ if (cleanup)
+ finish_decl_cleanup (var, cleanup);
+ }
+ else
+ {
+ rest_of_decl_compilation (var, NULL, /*toplev=*/1, at_eof);
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+ static_aggregates = tree_cons (NULL_TREE, var,
+ static_aggregates);
+ }
+ init = build (INIT_EXPR, type, var, expr);
/* Use its address to initialize the reference variable. */
expr = build_address (var);
+ expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
}
else
/* Take the address of EXPR. */
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index d3d20e7..bfb7e0f 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3263,6 +3263,12 @@ extern GTY(()) varray_type local_classes;
extern int at_eof;
+/* A list of namespace-scope objects which have constructors or
+ destructors which reside in the global scope. The decl is stored
+ in the TREE_VALUE slot and the initializer is stored in the
+ TREE_PURPOSE slot. */
+extern GTY(()) tree static_aggregates;
+
/* Functions called along with real static constructors and destructors. */
extern GTY(()) tree static_ctors;
@@ -3631,6 +3637,7 @@ extern void clear_anon_tags (void);
extern int decls_match (tree, tree);
extern int duplicate_decls (tree, tree);
extern tree pushdecl_top_level (tree);
+extern tree pushdecl_top_level_and_finish (tree, tree);
extern void pushdecl_class_level (tree);
extern tree pushdecl_namespace_level (tree);
extern tree push_using_decl (tree, tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 4ec5c31..d025a6f 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -4143,18 +4143,40 @@ pushdecl_namespace_level (tree x)
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
-/* Like pushdecl, only it places X in the global scope if appropriate. */
+/* Like pushdecl, only it places X in the global scope if appropriate.
+ Calls cp_finish_decl to register the variable, initializing it with
+ *INIT, if INIT is non-NULL. */
-tree
-pushdecl_top_level (tree x)
+static tree
+pushdecl_top_level_1 (tree x, tree *init)
{
timevar_push (TV_NAME_LOOKUP);
push_to_top_level ();
x = pushdecl_namespace_level (x);
+ if (init)
+ cp_finish_decl (x, *init, NULL_TREE, 0);
pop_from_top_level ();
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
}
+/* Like pushdecl, only it places X in the global scope if appropriate. */
+
+tree
+pushdecl_top_level (tree x)
+{
+ return pushdecl_top_level_1 (x, NULL);
+}
+
+/* Like pushdecl, only it places X in the global scope if
+ appropriate. Calls cp_finish_decl to register the variable,
+ initializing it with INIT. */
+
+tree
+pushdecl_top_level_and_finish (tree x, tree init)
+{
+ return pushdecl_top_level_1 (x, &init);
+}
+
/* Make the declaration of X appear in CLASS scope. */
void
@@ -7903,6 +7925,7 @@ static void
initialize_local_var (tree decl, tree init)
{
tree type = TREE_TYPE (decl);
+ tree cleanup;
my_friendly_assert (TREE_CODE (decl) == VAR_DECL
|| TREE_CODE (decl) == RESULT_DECL,
@@ -7952,17 +7975,9 @@ initialize_local_var (tree decl, tree init)
}
/* Generate a cleanup, if necessary. */
- if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
- {
- tree cleanup;
-
- /* Compute the cleanup. */
- cleanup = cxx_maybe_build_cleanup (decl);
-
- /* Record the cleanup required for this declaration. */
- if (DECL_SIZE (decl) && cleanup)
- finish_decl_cleanup (decl, cleanup);
- }
+ cleanup = cxx_maybe_build_cleanup (decl);
+ if (DECL_SIZE (decl) && cleanup)
+ finish_decl_cleanup (decl, cleanup);
}
/* Finish processing of a declaration;
@@ -7991,6 +8006,8 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
return;
}
+ my_friendly_assert (TREE_CODE (decl) != RESULT_DECL, 20030619);
+
/* If a name was specified, get the string. */
if (global_scope_p (current_binding_level))
asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
@@ -8031,8 +8048,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
if (processing_template_decl)
{
/* Add this declaration to the statement-tree. */
- if (at_function_scope_p ()
- && TREE_CODE (decl) != RESULT_DECL)
+ if (at_function_scope_p ())
add_decl_stmt (decl);
if (init && DECL_INITIAL (decl))
@@ -8089,8 +8105,6 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec));
make_decl_rtl (decl, asmspec);
}
- else if (TREE_CODE (decl) == RESULT_DECL)
- init = check_initializer (decl, init, flags);
else if (TREE_CODE (decl) == VAR_DECL)
{
/* Only PODs can have thread-local storage. Other types may require
@@ -8146,9 +8160,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
/* Add this declaration to the statement-tree. This needs to happen
after the call to check_initializer so that the DECL_STMT for a
reference temp is added before the DECL_STMT for the reference itself. */
- if (building_stmt_tree ()
- && at_function_scope_p ()
- && TREE_CODE (decl) != RESULT_DECL)
+ if (at_function_scope_p ())
add_decl_stmt (decl);
if (TREE_CODE (decl) == VAR_DECL)
@@ -8157,8 +8169,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
/* Output the assembler code and/or RTL code for variables and functions,
unless the type is an undefined structure or union.
If not, it will get done when the type is completed. */
- if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL
- || TREE_CODE (decl) == RESULT_DECL)
+ if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
{
if (TREE_CODE (decl) == VAR_DECL)
maybe_commonize_var (decl);
diff --git a/gcc/cp/decl.h b/gcc/cp/decl.h
index b942687..2a7a765 100644
--- a/gcc/cp/decl.h
+++ b/gcc/cp/decl.h
@@ -37,12 +37,6 @@ extern tree grokdeclarator (tree, tree, enum decl_context, int, tree*);
or a chain or parameter decls here. */
extern GTY(()) tree last_function_parms;
-/* A list of objects which have constructors or destructors
- which reside in the global scope. The decl is stored in
- the TREE_VALUE slot and the initializer is stored
- in the TREE_PURPOSE slot. */
-extern GTY(()) tree static_aggregates;
-
#ifdef DEBUG_CP_BINDING_LEVELS
/* Purely for debugging purposes. */
extern int debug_bindings_indentation;
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 1413f39..3fa4d74 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1886,8 +1886,7 @@ get_guard (tree decl)
DECL_ARTIFICIAL (guard) = 1;
TREE_USED (guard) = 1;
- pushdecl_top_level (guard);
- cp_finish_decl (guard, NULL_TREE, NULL_TREE, 0);
+ pushdecl_top_level_and_finish (guard, NULL_TREE);
}
return guard;
}
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index ac117fa..1a29c1c 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -364,9 +364,8 @@ get_tinfo_decl (tree type)
DECL_EXTERNAL (d) = 1;
SET_DECL_ASSEMBLER_NAME (d, name);
DECL_COMDAT (d) = 1;
- cp_finish_decl (d, NULL_TREE, NULL_TREE, 0);
- pushdecl_top_level (d);
+ pushdecl_top_level_and_finish (d, NULL_TREE);
if (CLASS_TYPE_P (type))
CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type)) = d;
@@ -770,8 +769,7 @@ tinfo_base_init (tree desc, tree target)
SET_DECL_ASSEMBLER_NAME (name_decl,
mangle_typeinfo_string_for_type (target));
DECL_INITIAL (name_decl) = name_string;
- cp_finish_decl (name_decl, name_string, NULL_TREE, 0);
- pushdecl_top_level (name_decl);
+ pushdecl_top_level_and_finish (name_decl, name_string);
}
vtable_ptr = TINFO_VTABLE_DECL (desc);