Commit 7993382e by Mark Mitchell Committed by Mark Mitchell

re PR c++/9878 (error: non-lvalue in unary `&' wrongly issued)

	PR c++/9878
	* call.c (convert_class_to_reference): Correct conversion
	sequences.
	(reference_binding): Add ref_bound_directly_to_rvalue_p parameter.
	(implicit_conversion): Adjust call to reference_binding.
	(add_candidate): Change type of candidates parameter.
	(add_function_candidate): Likewise.
	(add_conv_candidate): Likewise.
	(build_builtin_candidate): Likewise.
	(add_builtin_candidate): Likewise.
	(add_builtin_candidates): Likewise.
	(add_template_candidate_real): Likewise.
	(add_template_candidate): Likewise.
	(add_template_conv_candidate): Likewise.
	(build_user_type_conversion_1): Adjust accordingly.
	(build_object_call): Likewise.
	(build_conditional_expr): Likewise.
	(add_candidates): Likewise.
	(build_new_op): Likewise.
	(convert_like_real): Use USER_CONV_CAND.  Use build_nop.
	(build_new_method_call): Adjust calls to add_function_candidate.
	(make_temporary_var_for_ref_to_temp): New function.
	(initialize_reference): Add decl parameter.
	* class.c (build_rtti_vtbl_entries): Use build_address and
	build_nop.
	* cp-tree.h (initialize_reference): Change prototype.
	(make_temporary_var_for_ref_to_temp): New function.
	(build_type_conversion): Change prototype.
	(build_address): New function.
	(build_nop): Likewise.
	* cvt.c (cp_convert_to_pointer): Adjust call to
	build_type_conversion.  Avoid indicating redundant NOP_EXPRs.
	Use build_nop.
	(convert_to_pointer_force): Use build_nop.
	(build_up_reference): Use make_temporary_var_for_ref_to_temp.
	(convert_to_reference): Adjust call to build_type_conversion.
	(ocp_convert): Likewise.
	(build_type_conversion): Remove for_sure parameter.
	* decl.c (grok_reference_init): Use initialize_reference.
	* typeck.c (build_address): New function.
	(build_nop): Likewise.
	(build_unary_op): Use them.
	(build_ptrmemfunc): Tidy slightly.
	(convert_for_initialization): Adjust call to
	initialize_reference.
	* typeck2.c (store_init_value): Remove #if 0'd code.

	PR c++/9878
	* g++.dg/init/ref1.C: New test.

From-SVN: r63735
parent 03275f81
2003-03-03 Mark Mitchell <mark@codesourcery.com>
PR c++/9878
* call.c (convert_class_to_reference): Correct conversion
sequences.
(reference_binding): Add ref_bound_directly_to_rvalue_p parameter.
(implicit_conversion): Adjust call to reference_binding.
(add_candidate): Change type of candidates parameter.
(add_function_candidate): Likewise.
(add_conv_candidate): Likewise.
(build_builtin_candidate): Likewise.
(add_builtin_candidate): Likewise.
(add_builtin_candidates): Likewise.
(add_template_candidate_real): Likewise.
(add_template_candidate): Likewise.
(add_template_conv_candidate): Likewise.
(build_user_type_conversion_1): Adjust accordingly.
(build_object_call): Likewise.
(build_conditional_expr): Likewise.
(add_candidates): Likewise.
(build_new_op): Likewise.
(convert_like_real): Use USER_CONV_CAND. Use build_nop.
(build_new_method_call): Adjust calls to add_function_candidate.
(make_temporary_var_for_ref_to_temp): New function.
(initialize_reference): Add decl parameter.
* class.c (build_rtti_vtbl_entries): Use build_address and
build_nop.
* cp-tree.h (initialize_reference): Change prototype.
(make_temporary_var_for_ref_to_temp): New function.
(build_type_conversion): Change prototype.
(build_address): New function.
(build_nop): Likewise.
* cvt.c (cp_convert_to_pointer): Adjust call to
build_type_conversion. Avoid indicating redundant NOP_EXPRs.
Use build_nop.
(convert_to_pointer_force): Use build_nop.
(build_up_reference): Use make_temporary_var_for_ref_to_temp.
(convert_to_reference): Adjust call to build_type_conversion.
(ocp_convert): Likewise.
(build_type_conversion): Remove for_sure parameter.
* decl.c (grok_reference_init): Use initialize_reference.
* typeck.c (build_address): New function.
(build_nop): Likewise.
(build_unary_op): Use them.
(build_ptrmemfunc): Tidy slightly.
(convert_for_initialization): Adjust call to
initialize_reference.
* typeck2.c (store_init_value): Remove #if 0'd code.
2003-03-03 Jason Merrill <jason@redhat.com> 2003-03-03 Jason Merrill <jason@redhat.com>
* decl.c (start_function): Clear DECL_NUM_STMTS. * decl.c (start_function): Clear DECL_NUM_STMTS.
......
...@@ -7922,22 +7922,20 @@ build_rtti_vtbl_entries (tree binfo, vtbl_init_data* vid) ...@@ -7922,22 +7922,20 @@ build_rtti_vtbl_entries (tree binfo, vtbl_init_data* vid)
/* The second entry is the address of the typeinfo object. */ /* The second entry is the address of the typeinfo object. */
if (flag_rtti) if (flag_rtti)
decl = build_unary_op (ADDR_EXPR, get_tinfo_decl (t), 0); decl = build_address (get_tinfo_decl (t));
else else
decl = integer_zero_node; decl = integer_zero_node;
/* Convert the declaration to a type that can be stored in the /* Convert the declaration to a type that can be stored in the
vtable. */ vtable. */
init = build1 (NOP_EXPR, vfunc_ptr_type_node, decl); init = build_nop (vfunc_ptr_type_node, decl);
TREE_CONSTANT (init) = 1;
*vid->last_init = build_tree_list (NULL_TREE, init); *vid->last_init = build_tree_list (NULL_TREE, init);
vid->last_init = &TREE_CHAIN (*vid->last_init); vid->last_init = &TREE_CHAIN (*vid->last_init);
/* Add the offset-to-top entry. It comes earlier in the vtable that /* Add the offset-to-top entry. It comes earlier in the vtable that
the the typeinfo entry. Convert the offset to look like a the the typeinfo entry. Convert the offset to look like a
function pointer, so that we can put it in the vtable. */ function pointer, so that we can put it in the vtable. */
init = build1 (NOP_EXPR, vfunc_ptr_type_node, offset); init = build_nop (vfunc_ptr_type_node, offset);
TREE_CONSTANT (init) = 1;
*vid->last_init = build_tree_list (NULL_TREE, init); *vid->last_init = build_tree_list (NULL_TREE, init);
vid->last_init = &TREE_CHAIN (*vid->last_init); vid->last_init = &TREE_CHAIN (*vid->last_init);
} }
...@@ -3576,7 +3576,8 @@ extern tree type_passed_as (tree); ...@@ -3576,7 +3576,8 @@ extern tree type_passed_as (tree);
extern tree convert_for_arg_passing (tree, tree); extern tree convert_for_arg_passing (tree, tree);
extern tree cp_convert_parm_for_inlining (tree, tree, tree); extern tree cp_convert_parm_for_inlining (tree, tree, tree);
extern bool is_properly_derived_from (tree, tree); extern bool is_properly_derived_from (tree, tree);
extern tree initialize_reference (tree, tree); extern tree initialize_reference (tree, tree, tree);
extern tree make_temporary_var_for_ref_to_temp (tree);
extern tree strip_top_quals (tree); extern tree strip_top_quals (tree);
extern tree perform_implicit_conversion (tree, tree); extern tree perform_implicit_conversion (tree, tree);
extern tree in_charge_arg_for_name (tree); extern tree in_charge_arg_for_name (tree);
...@@ -3638,7 +3639,7 @@ extern tree ocp_convert (tree, tree, int, int); ...@@ -3638,7 +3639,7 @@ extern tree ocp_convert (tree, tree, int, int);
extern tree cp_convert (tree, tree); extern tree cp_convert (tree, tree);
extern tree convert_to_void (tree, const char */*implicit context*/); extern tree convert_to_void (tree, const char */*implicit context*/);
extern tree convert_force (tree, tree, int); extern tree convert_force (tree, tree, int);
extern tree build_type_conversion (tree, tree, int); extern tree build_type_conversion (tree, tree);
extern tree build_expr_type_conversion (int, tree, bool); extern tree build_expr_type_conversion (int, tree, bool);
extern tree type_promotes_to (tree); extern tree type_promotes_to (tree);
extern tree perform_qualification_conversions (tree, tree); extern tree perform_qualification_conversions (tree, tree);
...@@ -4355,6 +4356,8 @@ extern tree check_return_expr (tree); ...@@ -4355,6 +4356,8 @@ extern tree check_return_expr (tree);
#define cxx_sizeof(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, true) #define cxx_sizeof(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, true)
#define cxx_alignof(T) cxx_sizeof_or_alignof_type (T, ALIGNOF_EXPR, true) #define cxx_alignof(T) cxx_sizeof_or_alignof_type (T, ALIGNOF_EXPR, true)
extern tree build_ptrmemfunc_access_expr (tree, tree); extern tree build_ptrmemfunc_access_expr (tree, tree);
extern tree build_address (tree);
extern tree build_nop (tree, tree);
/* in typeck2.c */ /* in typeck2.c */
extern void require_complete_eh_spec_types (tree, tree); extern void require_complete_eh_spec_types (tree, tree);
......
...@@ -90,7 +90,7 @@ cp_convert_to_pointer (tree type, tree expr, bool force) ...@@ -90,7 +90,7 @@ cp_convert_to_pointer (tree type, tree expr, bool force)
return error_mark_node; return error_mark_node;
} }
rval = build_type_conversion (type, expr, true); rval = build_type_conversion (type, expr);
if (rval) if (rval)
{ {
if (rval == error_mark_node) if (rval == error_mark_node)
...@@ -148,31 +148,33 @@ cp_convert_to_pointer (tree type, tree expr, bool force) ...@@ -148,31 +148,33 @@ cp_convert_to_pointer (tree type, tree expr, bool force)
{ {
enum tree_code code = PLUS_EXPR; enum tree_code code = PLUS_EXPR;
tree binfo; tree binfo;
tree intype_class;
tree type_class;
bool same_p;
intype_class = TREE_TYPE (intype);
type_class = TREE_TYPE (type);
same_p = same_type_p (TYPE_MAIN_VARIANT (intype_class),
TYPE_MAIN_VARIANT (type_class));
binfo = NULL_TREE;
/* Try derived to base conversion. */ /* Try derived to base conversion. */
binfo = lookup_base (TREE_TYPE (intype), TREE_TYPE (type), if (!same_p)
ba_check, NULL); binfo = lookup_base (intype_class, type_class, ba_check, NULL);
if (!binfo) if (!same_p && !binfo)
{ {
/* Try base to derived conversion. */ /* Try base to derived conversion. */
binfo = lookup_base (TREE_TYPE (type), TREE_TYPE (intype), binfo = lookup_base (type_class, intype_class, ba_check, NULL);
ba_check, NULL);
code = MINUS_EXPR; code = MINUS_EXPR;
} }
if (binfo == error_mark_node) if (binfo == error_mark_node)
return error_mark_node; return error_mark_node;
if (binfo) if (binfo || same_p)
{ {
expr = build_base_path (code, expr, binfo, 0); if (binfo)
expr = build_base_path (code, expr, binfo, 0);
/* Add any qualifier conversions. */ /* Add any qualifier conversions. */
if (!same_type_p (TREE_TYPE (TREE_TYPE (expr)), return build_nop (type, expr);
TREE_TYPE (type)))
{
expr = build1 (NOP_EXPR, type, expr);
TREE_CONSTANT (expr) =
TREE_CONSTANT (TREE_OPERAND (expr, 0));
}
return expr;
} }
} }
...@@ -225,9 +227,7 @@ cp_convert_to_pointer (tree type, tree expr, bool force) ...@@ -225,9 +227,7 @@ cp_convert_to_pointer (tree type, tree expr, bool force)
return error_mark_node; return error_mark_node;
} }
rval = build1 (NOP_EXPR, type, expr); return build_nop (type, expr);
TREE_CONSTANT (rval) = TREE_CONSTANT (expr);
return rval;
} }
else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)) else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))
return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0); return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0);
...@@ -326,14 +326,9 @@ convert_to_pointer_force (tree type, tree expr) ...@@ -326,14 +326,9 @@ convert_to_pointer_force (tree type, tree expr)
/* Add any qualifier conversions. */ /* Add any qualifier conversions. */
if (!same_type_p (TREE_TYPE (TREE_TYPE (expr)), if (!same_type_p (TREE_TYPE (TREE_TYPE (expr)),
TREE_TYPE (type))) TREE_TYPE (type)))
{ expr = build_nop (type, expr);
expr = build1 (NOP_EXPR, type, expr);
TREE_CONSTANT (expr) =
TREE_CONSTANT (TREE_OPERAND (expr, 0));
}
return expr; return expr;
} }
} }
} }
...@@ -354,7 +349,6 @@ build_up_reference (tree type, tree arg, int flags, tree decl) ...@@ -354,7 +349,6 @@ build_up_reference (tree type, tree arg, int flags, tree decl)
tree rval; tree rval;
tree argtype = TREE_TYPE (arg); tree argtype = TREE_TYPE (arg);
tree target_type = TREE_TYPE (type); tree target_type = TREE_TYPE (type);
tree stmt_expr = NULL_TREE;
my_friendly_assert (TREE_CODE (type) == REFERENCE_TYPE, 187); my_friendly_assert (TREE_CODE (type) == REFERENCE_TYPE, 187);
...@@ -364,26 +358,7 @@ build_up_reference (tree type, tree arg, int flags, tree decl) ...@@ -364,26 +358,7 @@ build_up_reference (tree type, tree arg, int flags, tree decl)
here because it needs to live as long as DECL. */ here because it needs to live as long as DECL. */
tree targ = arg; tree targ = arg;
arg = build_decl (VAR_DECL, NULL_TREE, argtype); arg = make_temporary_var_for_ref_to_temp (decl);
DECL_ARTIFICIAL (arg) = 1;
TREE_USED (arg) = 1;
TREE_STATIC (arg) = TREE_STATIC (decl);
if (TREE_STATIC (decl))
{
/* Namespace-scope or local static; give it a mangled name. */
tree name = mangle_ref_init_variable (decl);
DECL_NAME (arg) = name;
SET_DECL_ASSEMBLER_NAME (arg, name);
arg = pushdecl_top_level (arg);
}
else
{
/* Automatic; make sure we handle the cleanup properly. */
maybe_push_cleanup_level (argtype);
/* Don't push unnamed temps. Do set DECL_CONTEXT, though. */
DECL_CONTEXT (arg) = current_function_decl;
}
/* Process the initializer for the declaration. */ /* Process the initializer for the declaration. */
DECL_INITIAL (arg) = targ; DECL_INITIAL (arg) = targ;
...@@ -416,16 +391,7 @@ build_up_reference (tree type, tree arg, int flags, tree decl) ...@@ -416,16 +391,7 @@ build_up_reference (tree type, tree arg, int flags, tree decl)
else else
rval rval
= convert_to_pointer_force (build_pointer_type (target_type), rval); = convert_to_pointer_force (build_pointer_type (target_type), rval);
rval = build1 (NOP_EXPR, type, rval); return build_nop (type, rval);
TREE_CONSTANT (rval) = TREE_CONSTANT (TREE_OPERAND (rval, 0));
/* If we created and initialized a new temporary variable, add the
representation of that initialization to the RVAL. */
if (stmt_expr)
rval = build (COMPOUND_EXPR, TREE_TYPE (rval), stmt_expr, rval);
/* And return the result. */
return rval;
} }
/* Subroutine of convert_to_reference. REFTYPE is the target reference type. /* Subroutine of convert_to_reference. REFTYPE is the target reference type.
...@@ -500,7 +466,7 @@ convert_to_reference (tree reftype, tree expr, int convtype, ...@@ -500,7 +466,7 @@ convert_to_reference (tree reftype, tree expr, int convtype,
/* Look for a user-defined conversion to lvalue that we can use. */ /* Look for a user-defined conversion to lvalue that we can use. */
rval_as_conversion rval_as_conversion
= build_type_conversion (reftype, expr, 1); = build_type_conversion (reftype, expr);
if (rval_as_conversion && rval_as_conversion != error_mark_node if (rval_as_conversion && rval_as_conversion != error_mark_node
&& real_lvalue_p (rval_as_conversion)) && real_lvalue_p (rval_as_conversion))
...@@ -705,7 +671,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags) ...@@ -705,7 +671,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
if (IS_AGGR_TYPE (intype)) if (IS_AGGR_TYPE (intype))
{ {
tree rval; tree rval;
rval = build_type_conversion (type, e, 1); rval = build_type_conversion (type, e);
if (rval) if (rval)
return rval; return rval;
if (flags & LOOKUP_COMPLAIN) if (flags & LOOKUP_COMPLAIN)
...@@ -741,7 +707,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags) ...@@ -741,7 +707,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
if (IS_AGGR_TYPE (TREE_TYPE (e))) if (IS_AGGR_TYPE (TREE_TYPE (e)))
{ {
tree rval; tree rval;
rval = build_type_conversion (type, e, 1); rval = build_type_conversion (type, e);
if (rval) if (rval)
return rval; return rval;
else else
...@@ -1015,24 +981,17 @@ convert_force (tree type, tree expr, int convtype) ...@@ -1015,24 +981,17 @@ convert_force (tree type, tree expr, int convtype)
allowed (references private members, etc). allowed (references private members, etc).
If no conversion exists, NULL_TREE is returned. If no conversion exists, NULL_TREE is returned.
If (FOR_SURE & 1) is nonzero, then we allow this type conversion
to take place immediately. Otherwise, we build a SAVE_EXPR
which can be evaluated if the results are ever needed.
Changes to this functions should be mirrored in user_harshness.
FIXME: Ambiguity checking is wrong. Should choose one by the implicit FIXME: Ambiguity checking is wrong. Should choose one by the implicit
object parameter, or by the second standard conversion sequence if object parameter, or by the second standard conversion sequence if
that doesn't do it. This will probably wait for an overloading rewrite. that doesn't do it. This will probably wait for an overloading rewrite.
(jason 8/9/95) */ (jason 8/9/95) */
tree tree
build_type_conversion (tree xtype, tree expr, int for_sure) build_type_conversion (tree xtype, tree expr)
{ {
/* C++: check to see if we can convert this aggregate type /* C++: check to see if we can convert this aggregate type
into the required type. */ into the required type. */
return build_user_type_conversion return build_user_type_conversion (xtype, expr, LOOKUP_NORMAL);
(xtype, expr, for_sure ? LOOKUP_NORMAL : 0);
} }
/* Convert the given EXPR to one of a group of types suitable for use in an /* Convert the given EXPR to one of a group of types suitable for use in an
......
...@@ -7288,10 +7288,7 @@ grok_reference_init (tree decl, tree type, tree init) ...@@ -7288,10 +7288,7 @@ grok_reference_init (tree decl, tree type, tree init)
DECL_INITIAL for local references (instead assigning to them DECL_INITIAL for local references (instead assigning to them
explicitly); we need to allow the temporary to be initialized explicitly); we need to allow the temporary to be initialized
first. */ first. */
tmp = convert_to_reference tmp = initialize_reference (type, init, decl);
(type, init, CONV_IMPLICIT,
LOOKUP_ONLYCONVERTING|LOOKUP_SPECULATIVELY|LOOKUP_NORMAL|DIRECT_BIND,
decl);
if (tmp == error_mark_node) if (tmp == error_mark_node)
return NULL_TREE; return NULL_TREE;
......
...@@ -4089,7 +4089,45 @@ condition_conversion (expr) ...@@ -4089,7 +4089,45 @@ condition_conversion (expr)
t = fold (build1 (CLEANUP_POINT_EXPR, boolean_type_node, t)); t = fold (build1 (CLEANUP_POINT_EXPR, boolean_type_node, t));
return t; return t;
} }
/* Return an ADDR_EXPR giving the address of T. This function
attempts no optimizations or simplifications; it is a low-level
primitive. */
tree
build_address (tree t)
{
tree addr;
if (error_operand_p (t) || !cxx_mark_addressable (t))
return error_mark_node;
addr = build1 (ADDR_EXPR,
build_pointer_type (TREE_TYPE (t)),
t);
if (staticp (t))
TREE_CONSTANT (addr) = 1;
return addr;
}
/* Return a NOP_EXPR converting EXPR to TYPE. */
tree
build_nop (tree type, tree expr)
{
tree nop;
if (type == error_mark_node || error_operand_p (expr))
return expr;
nop = build1 (NOP_EXPR, type, expr);
if (TREE_CONSTANT (expr))
TREE_CONSTANT (nop) = 1;
return nop;
}
/* C++: Must handle pointers to members. /* C++: Must handle pointers to members.
Perhaps type instantiation should be extended to handle conversion Perhaps type instantiation should be extended to handle conversion
...@@ -4479,9 +4517,6 @@ build_unary_op (code, xarg, noconvert) ...@@ -4479,9 +4517,6 @@ build_unary_op (code, xarg, noconvert)
if (argtype != error_mark_node) if (argtype != error_mark_node)
argtype = build_pointer_type (argtype); argtype = build_pointer_type (argtype);
if (!cxx_mark_addressable (arg))
return error_mark_node;
{ {
tree addr; tree addr;
...@@ -4515,12 +4550,7 @@ build_unary_op (code, xarg, noconvert) ...@@ -4515,12 +4550,7 @@ build_unary_op (code, xarg, noconvert)
cp_convert (argtype, byte_position (field)))); cp_convert (argtype, byte_position (field))));
} }
else else
addr = build1 (ADDR_EXPR, argtype, arg); addr = build_address (arg);
/* Address of a static or external variable or
function counts as a constant */
if (staticp (arg))
TREE_CONSTANT (addr) = 1;
if (TREE_CODE (argtype) == POINTER_TYPE if (TREE_CODE (argtype) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (argtype)) == METHOD_TYPE) && TREE_CODE (TREE_TYPE (argtype)) == METHOD_TYPE)
...@@ -5798,11 +5828,17 @@ build_ptrmemfunc (type, pfn, force) ...@@ -5798,11 +5828,17 @@ build_ptrmemfunc (type, pfn, force)
int force; int force;
{ {
tree fn; tree fn;
tree pfn_type = TREE_TYPE (pfn); tree pfn_type;
tree to_type = build_ptrmemfunc_type (type); tree to_type;
if (error_operand_p (pfn))
return error_mark_node;
pfn_type = TREE_TYPE (pfn);
to_type = build_ptrmemfunc_type (type);
/* Handle multiple conversions of pointer to member functions. */ /* Handle multiple conversions of pointer to member functions. */
if (TYPE_PTRMEMFUNC_P (TREE_TYPE (pfn))) if (TYPE_PTRMEMFUNC_P (pfn_type))
{ {
tree delta = NULL_TREE; tree delta = NULL_TREE;
tree npfn = NULL_TREE; tree npfn = NULL_TREE;
...@@ -6183,7 +6219,7 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum) ...@@ -6183,7 +6219,7 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
if (fndecl) if (fndecl)
savew = warningcount, savee = errorcount; savew = warningcount, savee = errorcount;
rhs = initialize_reference (type, rhs); rhs = initialize_reference (type, rhs, /*decl=*/NULL_TREE);
if (fndecl) if (fndecl)
{ {
if (warningcount > savew) if (warningcount > savew)
......
...@@ -388,32 +388,8 @@ store_init_value (decl, init) ...@@ -388,32 +388,8 @@ store_init_value (decl, init)
return value; return value;
else if (TREE_STATIC (decl) else if (TREE_STATIC (decl)
&& (! TREE_CONSTANT (value) && (! TREE_CONSTANT (value)
|| ! initializer_constant_valid_p (value, TREE_TYPE (value)) || ! initializer_constant_valid_p (value, TREE_TYPE (value))))
#if 0
/* A STATIC PUBLIC int variable doesn't have to be
run time inited when doing pic. (mrs) */
/* Since ctors and dtors are the only things that can
reference vtables, and they are always written down
the vtable definition, we can leave the
vtables in initialized data space.
However, other initialized data cannot be initialized
this way. Instead a global file-level initializer
must do the job. */
|| (flag_pic && !DECL_VIRTUAL_P (decl) && TREE_PUBLIC (decl))
#endif
))
return value; return value;
#if 0 /* No, that's C. jason 9/19/94 */
else
{
if (pedantic && TREE_CODE (value) == CONSTRUCTOR)
{
if (! TREE_CONSTANT (value) || ! TREE_STATIC (value))
pedwarn ("ISO C++ forbids non-constant aggregate initializer expressions");
}
}
#endif
/* Store the VALUE in DECL_INITIAL. If we're building a /* Store the VALUE in DECL_INITIAL. If we're building a
statement-tree we will actually expand the initialization later statement-tree we will actually expand the initialization later
......
2003-03-03 Mark Mitchell <mark@codesourcery.com>
PR c++/9878
* g++.dg/init/ref1.C: New test.
Mon Mar 3 20:42:04 2003 J"orn Rennecke <joern.rennecke@superh.com> Mon Mar 3 20:42:04 2003 J"orn Rennecke <joern.rennecke@superh.com>
* gcc.dg/sh-relax.c: New SH-only test. * gcc.dg/sh-relax.c: New SH-only test.
......
void f(void)
{
short x = 0;
const int &y = x;
}
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