Commit c1bc6829 by Jason Merrill Committed by Jason Merrill

typeck.c (c_expand_return): Always convert_for_initialization before checking…

typeck.c (c_expand_return): Always convert_for_initialization before checking for returning a pointer to local.

	* typeck.c (c_expand_return): Always convert_for_initialization
 	before checking for returning a pointer to local.

From-SVN: r15064
parent fa8b6024
Wed Sep 3 11:09:25 1997 Jason Merrill <jason@yorick.cygnus.com>
* typeck.c (c_expand_return): Always convert_for_initialization
before checking for returning a pointer to local.
* pt.c (type_unification): If strict and the function parm doesn't
use template parms, just compare types.
......
......@@ -321,7 +321,9 @@ int flag_memoize_lookups; int flag_save_memoized_contexts;
int write_virtuals;
/* Nonzero means we should attempt to elide constructors when possible. */
/* Nonzero means we should attempt to elide constructors when possible.
FIXME: This flag is obsolete, and should be torn out along with the
old overloading code. */
int flag_elide_constructors;
......
......@@ -7204,25 +7204,49 @@ c_expand_return (retval)
expand_return (retval);
return;
}
/* Add some useful error checking for C++. */
else if (TREE_CODE (valtype) == REFERENCE_TYPE)
{
tree whats_returned;
tree tmp_result = result;
/* Don't initialize directly into a non-BLKmode retval, since that
could lose when being inlined by another caller. (GCC can't
read the function return register in an inline function when
the return value is being ignored). */
if (result && TYPE_MODE (TREE_TYPE (tmp_result)) != BLKmode)
tmp_result = 0;
/* Now deal with possible C++ hair:
(1) Compute the return value.
(2) If there are aggregate values with destructors which
must be cleaned up, clean them (taking care
not to clobber the return value).
(3) If an X(X&) constructor is defined, the return
value must be returned via that. */
/* convert to reference now, so we can give error if we
return an reference to a non-lvalue. */
if (retval == result
|| DECL_CONSTRUCTOR_P (current_function_decl))
/* It's already done for us. */;
else if (TREE_TYPE (retval) == void_type_node)
{
pedwarn ("return of void value in function returning non-void");
expand_expr_stmt (retval);
retval = 0;
}
else
{
retval = convert_for_initialization
(tmp_result, valtype, retval, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING,
(NULL_TREE, valtype, retval, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING,
"return", NULL_TREE, 0);
if (retval == error_mark_node)
{
/* Avoid warning about control reaching end of function. */
expand_null_return ();
return;
}
/* We can't initialize a register from a NEW_EXPR. */
else if (! current_function_returns_struct
&& TREE_CODE (retval) == TARGET_EXPR
&& TREE_CODE (TREE_OPERAND (retval, 1)) == NEW_EXPR)
retval = build (COMPOUND_EXPR, TREE_TYPE (retval), retval,
TREE_OPERAND (retval, 0));
/* Add some useful error checking for C++. */
else if (TREE_CODE (valtype) == REFERENCE_TYPE)
{
tree whats_returned;
/* Sort through common things to see what it is
we are returning. */
whats_returned = retval;
......@@ -7268,54 +7292,6 @@ c_expand_return (retval)
&& !TREE_PUBLIC (whats_returned))
cp_warning_at ("address of local variable `%D' returned", whats_returned);
}
else if (TREE_CODE (retval) == VAR_DECL)
{
if (TREE_CODE (TREE_TYPE (retval)) == ARRAY_TYPE
&& DECL_NAME (retval)
&& IDENTIFIER_LOCAL_VALUE (DECL_NAME (retval))
&& !TREE_STATIC (retval)
&& !TREE_PUBLIC (retval))
cp_warning_at ("address of local array `%D' returned", retval);
}
/* Now deal with possible C++ hair:
(1) Compute the return value.
(2) If there are aggregate values with destructors which
must be cleaned up, clean them (taking care
not to clobber the return value).
(3) If an X(X&) constructor is defined, the return
value must be returned via that. */
if (retval == result
|| DECL_CONSTRUCTOR_P (current_function_decl))
/* It's already done for us. */;
else if (TREE_TYPE (retval) == void_type_node)
{
pedwarn ("return of void value in function returning non-void");
expand_expr_stmt (retval);
retval = 0;
}
else
{
/* We already did this above for refs, don't do it again. */
if (TREE_CODE (valtype) != REFERENCE_TYPE)
retval = convert_for_initialization
(NULL_TREE, valtype, retval, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING,
"return", NULL_TREE, 0);
/* We can't initialize a register from a NEW_EXPR. */
if (! current_function_returns_struct
&& TREE_CODE (retval) == TARGET_EXPR
&& TREE_CODE (TREE_OPERAND (retval, 1)) == NEW_EXPR)
retval = build (COMPOUND_EXPR, TREE_TYPE (retval), retval,
TREE_OPERAND (retval, 0));
if (retval == error_mark_node)
{
/* Avoid warning about control reaching end of function. */
expand_null_return ();
return;
}
}
if (retval != NULL_TREE
......
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