mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-12 19:58:01 +08:00
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
This commit is contained in:
parent
7a1d37e910
commit
170b020fe4
@ -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>
|
2003-06-19 Matt Austern <austern@apple.com>
|
||||||
|
|
||||||
PR c++/11228
|
PR c++/11228
|
||||||
|
@ -6144,7 +6144,7 @@ initialize_reference (tree type, tree expr, tree decl)
|
|||||||
T t;
|
T t;
|
||||||
const S& s = 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. */
|
operator. */
|
||||||
my_friendly_assert (TREE_CODE (conv) == REF_BIND, 20030302);
|
my_friendly_assert (TREE_CODE (conv) == REF_BIND, 20030302);
|
||||||
if (decl)
|
if (decl)
|
||||||
@ -6167,13 +6167,33 @@ initialize_reference (tree type, tree expr, tree decl)
|
|||||||
expr = convert_like (conv, expr);
|
expr = convert_like (conv, expr);
|
||||||
if (!real_non_cast_lvalue_p (expr))
|
if (!real_non_cast_lvalue_p (expr))
|
||||||
{
|
{
|
||||||
|
tree init;
|
||||||
|
tree type;
|
||||||
|
|
||||||
/* Create the temporary variable. */
|
/* Create the temporary variable. */
|
||||||
var = make_temporary_var_for_ref_to_temp (decl, TREE_TYPE (expr));
|
type = TREE_TYPE (expr);
|
||||||
DECL_INITIAL (var) = expr;
|
var = make_temporary_var_for_ref_to_temp (decl, type);
|
||||||
cp_finish_decl (var, expr, NULL_TREE,
|
layout_decl (var, 0);
|
||||||
LOOKUP_ONLYCONVERTING|DIRECT_BIND);
|
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. */
|
/* Use its address to initialize the reference variable. */
|
||||||
expr = build_address (var);
|
expr = build_address (var);
|
||||||
|
expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Take the address of EXPR. */
|
/* Take the address of EXPR. */
|
||||||
|
@ -3263,6 +3263,12 @@ extern GTY(()) varray_type local_classes;
|
|||||||
|
|
||||||
extern int at_eof;
|
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. */
|
/* Functions called along with real static constructors and destructors. */
|
||||||
|
|
||||||
extern GTY(()) tree static_ctors;
|
extern GTY(()) tree static_ctors;
|
||||||
@ -3631,6 +3637,7 @@ extern void clear_anon_tags (void);
|
|||||||
extern int decls_match (tree, tree);
|
extern int decls_match (tree, tree);
|
||||||
extern int duplicate_decls (tree, tree);
|
extern int duplicate_decls (tree, tree);
|
||||||
extern tree pushdecl_top_level (tree);
|
extern tree pushdecl_top_level (tree);
|
||||||
|
extern tree pushdecl_top_level_and_finish (tree, tree);
|
||||||
extern void pushdecl_class_level (tree);
|
extern void pushdecl_class_level (tree);
|
||||||
extern tree pushdecl_namespace_level (tree);
|
extern tree pushdecl_namespace_level (tree);
|
||||||
extern tree push_using_decl (tree, tree);
|
extern tree push_using_decl (tree, tree);
|
||||||
|
@ -4143,16 +4143,38 @@ pushdecl_namespace_level (tree x)
|
|||||||
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
|
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
|
||||||
|
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. */
|
/* Like pushdecl, only it places X in the global scope if appropriate. */
|
||||||
|
|
||||||
tree
|
tree
|
||||||
pushdecl_top_level (tree x)
|
pushdecl_top_level (tree x)
|
||||||
{
|
{
|
||||||
timevar_push (TV_NAME_LOOKUP);
|
return pushdecl_top_level_1 (x, NULL);
|
||||||
push_to_top_level ();
|
}
|
||||||
x = pushdecl_namespace_level (x);
|
|
||||||
pop_from_top_level ();
|
/* Like pushdecl, only it places X in the global scope if
|
||||||
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
|
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. */
|
/* Make the declaration of X appear in CLASS scope. */
|
||||||
@ -7903,6 +7925,7 @@ static void
|
|||||||
initialize_local_var (tree decl, tree init)
|
initialize_local_var (tree decl, tree init)
|
||||||
{
|
{
|
||||||
tree type = TREE_TYPE (decl);
|
tree type = TREE_TYPE (decl);
|
||||||
|
tree cleanup;
|
||||||
|
|
||||||
my_friendly_assert (TREE_CODE (decl) == VAR_DECL
|
my_friendly_assert (TREE_CODE (decl) == VAR_DECL
|
||||||
|| TREE_CODE (decl) == RESULT_DECL,
|
|| TREE_CODE (decl) == RESULT_DECL,
|
||||||
@ -7952,17 +7975,9 @@ initialize_local_var (tree decl, tree init)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Generate a cleanup, if necessary. */
|
/* Generate a cleanup, if necessary. */
|
||||||
if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
|
cleanup = cxx_maybe_build_cleanup (decl);
|
||||||
{
|
if (DECL_SIZE (decl) && cleanup)
|
||||||
tree cleanup;
|
finish_decl_cleanup (decl, 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finish processing of a declaration;
|
/* Finish processing of a declaration;
|
||||||
@ -7991,6 +8006,8 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my_friendly_assert (TREE_CODE (decl) != RESULT_DECL, 20030619);
|
||||||
|
|
||||||
/* If a name was specified, get the string. */
|
/* If a name was specified, get the string. */
|
||||||
if (global_scope_p (current_binding_level))
|
if (global_scope_p (current_binding_level))
|
||||||
asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
|
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)
|
if (processing_template_decl)
|
||||||
{
|
{
|
||||||
/* Add this declaration to the statement-tree. */
|
/* Add this declaration to the statement-tree. */
|
||||||
if (at_function_scope_p ()
|
if (at_function_scope_p ())
|
||||||
&& TREE_CODE (decl) != RESULT_DECL)
|
|
||||||
add_decl_stmt (decl);
|
add_decl_stmt (decl);
|
||||||
|
|
||||||
if (init && DECL_INITIAL (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));
|
SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec));
|
||||||
make_decl_rtl (decl, 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)
|
else if (TREE_CODE (decl) == VAR_DECL)
|
||||||
{
|
{
|
||||||
/* Only PODs can have thread-local storage. Other types may require
|
/* 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
|
/* Add this declaration to the statement-tree. This needs to happen
|
||||||
after the call to check_initializer so that the DECL_STMT for a
|
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. */
|
reference temp is added before the DECL_STMT for the reference itself. */
|
||||||
if (building_stmt_tree ()
|
if (at_function_scope_p ())
|
||||||
&& at_function_scope_p ()
|
|
||||||
&& TREE_CODE (decl) != RESULT_DECL)
|
|
||||||
add_decl_stmt (decl);
|
add_decl_stmt (decl);
|
||||||
|
|
||||||
if (TREE_CODE (decl) == VAR_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,
|
/* Output the assembler code and/or RTL code for variables and functions,
|
||||||
unless the type is an undefined structure or union.
|
unless the type is an undefined structure or union.
|
||||||
If not, it will get done when the type is completed. */
|
If not, it will get done when the type is completed. */
|
||||||
if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL
|
if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
|
||||||
|| TREE_CODE (decl) == RESULT_DECL)
|
|
||||||
{
|
{
|
||||||
if (TREE_CODE (decl) == VAR_DECL)
|
if (TREE_CODE (decl) == VAR_DECL)
|
||||||
maybe_commonize_var (decl);
|
maybe_commonize_var (decl);
|
||||||
|
@ -37,12 +37,6 @@ extern tree grokdeclarator (tree, tree, enum decl_context, int, tree*);
|
|||||||
or a chain or parameter decls here. */
|
or a chain or parameter decls here. */
|
||||||
extern GTY(()) tree last_function_parms;
|
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
|
#ifdef DEBUG_CP_BINDING_LEVELS
|
||||||
/* Purely for debugging purposes. */
|
/* Purely for debugging purposes. */
|
||||||
extern int debug_bindings_indentation;
|
extern int debug_bindings_indentation;
|
||||||
|
@ -1886,8 +1886,7 @@ get_guard (tree decl)
|
|||||||
|
|
||||||
DECL_ARTIFICIAL (guard) = 1;
|
DECL_ARTIFICIAL (guard) = 1;
|
||||||
TREE_USED (guard) = 1;
|
TREE_USED (guard) = 1;
|
||||||
pushdecl_top_level (guard);
|
pushdecl_top_level_and_finish (guard, NULL_TREE);
|
||||||
cp_finish_decl (guard, NULL_TREE, NULL_TREE, 0);
|
|
||||||
}
|
}
|
||||||
return guard;
|
return guard;
|
||||||
}
|
}
|
||||||
|
@ -364,9 +364,8 @@ get_tinfo_decl (tree type)
|
|||||||
DECL_EXTERNAL (d) = 1;
|
DECL_EXTERNAL (d) = 1;
|
||||||
SET_DECL_ASSEMBLER_NAME (d, name);
|
SET_DECL_ASSEMBLER_NAME (d, name);
|
||||||
DECL_COMDAT (d) = 1;
|
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))
|
if (CLASS_TYPE_P (type))
|
||||||
CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type)) = d;
|
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,
|
SET_DECL_ASSEMBLER_NAME (name_decl,
|
||||||
mangle_typeinfo_string_for_type (target));
|
mangle_typeinfo_string_for_type (target));
|
||||||
DECL_INITIAL (name_decl) = name_string;
|
DECL_INITIAL (name_decl) = name_string;
|
||||||
cp_finish_decl (name_decl, name_string, NULL_TREE, 0);
|
pushdecl_top_level_and_finish (name_decl, name_string);
|
||||||
pushdecl_top_level (name_decl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vtable_ptr = TINFO_VTABLE_DECL (desc);
|
vtable_ptr = TINFO_VTABLE_DECL (desc);
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2003-06-19 Mark Mitchell <mark@codesourcery.com>
|
||||||
|
|
||||||
|
PR c++/11041
|
||||||
|
* g++.dg/init/ref7.C: New test.
|
||||||
|
|
||||||
2003-06-19 Matt Austern <austern@apple.com>
|
2003-06-19 Matt Austern <austern@apple.com>
|
||||||
|
|
||||||
PR c++/11228
|
PR c++/11228
|
||||||
|
9
gcc/testsuite/g++.dg/init/ref7.C
Normal file
9
gcc/testsuite/g++.dg/init/ref7.C
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
class hop
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
hop operator* () const;
|
||||||
|
};
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
const hop &x = *x;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user