From c1bc6829b439dfd3590a54dd298b34a0b34ccf89 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 3 Sep 1997 20:01:18 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 3 + gcc/cp/decl2.c | 4 +- gcc/cp/typeck.c | 146 ++++++++++++++++++++--------------------------- 3 files changed, 67 insertions(+), 86 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index fe2bdbaf004..21f2c6c982e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ Wed Sep 3 11:09:25 1997 Jason Merrill + * 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. diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index a8975ecd4d4..e78b00d25a7 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 2204c1f9c32..a442d4ec85a 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -7204,79 +7204,6 @@ 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; - - /* convert to reference now, so we can give error if we - return an reference to a non-lvalue. */ - retval = convert_for_initialization - (tmp_result, valtype, retval, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING, - "return", NULL_TREE, 0); - - /* Sort through common things to see what it is - we are returning. */ - whats_returned = retval; - if (TREE_CODE (whats_returned) == COMPOUND_EXPR) - { - whats_returned = TREE_OPERAND (whats_returned, 1); - if (TREE_CODE (whats_returned) == ADDR_EXPR) - whats_returned = TREE_OPERAND (whats_returned, 0); - } - while (TREE_CODE (whats_returned) == CONVERT_EXPR - || TREE_CODE (whats_returned) == NOP_EXPR) - whats_returned = TREE_OPERAND (whats_returned, 0); - if (TREE_CODE (whats_returned) == ADDR_EXPR) - { - whats_returned = TREE_OPERAND (whats_returned, 0); - while (TREE_CODE (whats_returned) == NEW_EXPR - || TREE_CODE (whats_returned) == TARGET_EXPR) - { - /* Get the target. */ - whats_returned = TREE_OPERAND (whats_returned, 0); - warning ("returning reference to temporary"); - } - } - - if (TREE_CODE (whats_returned) == VAR_DECL && DECL_NAME (whats_returned)) - { - if (TEMP_NAME_P (DECL_NAME (whats_returned))) - warning ("reference to non-lvalue returned"); - else if (! TREE_STATIC (whats_returned) - && IDENTIFIER_LOCAL_VALUE (DECL_NAME (whats_returned)) - && !TREE_PUBLIC (whats_returned)) - cp_warning_at ("reference to local variable `%D' returned", whats_returned); - } - } - else if (TREE_CODE (retval) == ADDR_EXPR) - { - tree whats_returned = TREE_OPERAND (retval, 0); - - if (TREE_CODE (whats_returned) == VAR_DECL - && DECL_NAME (whats_returned) - && IDENTIFIER_LOCAL_VALUE (DECL_NAME (whats_returned)) - && !TREE_STATIC (whats_returned) - && !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. @@ -7297,18 +7224,9 @@ c_expand_return (retval) } 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)); + retval = convert_for_initialization + (NULL_TREE, valtype, retval, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING, + "return", NULL_TREE, 0); if (retval == error_mark_node) { @@ -7316,6 +7234,64 @@ c_expand_return (retval) 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; + if (TREE_CODE (whats_returned) == COMPOUND_EXPR) + { + whats_returned = TREE_OPERAND (whats_returned, 1); + if (TREE_CODE (whats_returned) == ADDR_EXPR) + whats_returned = TREE_OPERAND (whats_returned, 0); + } + while (TREE_CODE (whats_returned) == CONVERT_EXPR + || TREE_CODE (whats_returned) == NOP_EXPR) + whats_returned = TREE_OPERAND (whats_returned, 0); + if (TREE_CODE (whats_returned) == ADDR_EXPR) + { + whats_returned = TREE_OPERAND (whats_returned, 0); + while (TREE_CODE (whats_returned) == NEW_EXPR + || TREE_CODE (whats_returned) == TARGET_EXPR) + { + /* Get the target. */ + whats_returned = TREE_OPERAND (whats_returned, 0); + warning ("returning reference to temporary"); + } + } + + if (TREE_CODE (whats_returned) == VAR_DECL && DECL_NAME (whats_returned)) + { + if (TEMP_NAME_P (DECL_NAME (whats_returned))) + warning ("reference to non-lvalue returned"); + else if (! TREE_STATIC (whats_returned) + && IDENTIFIER_LOCAL_VALUE (DECL_NAME (whats_returned)) + && !TREE_PUBLIC (whats_returned)) + cp_warning_at ("reference to local variable `%D' returned", whats_returned); + } + } + else if (TREE_CODE (retval) == ADDR_EXPR) + { + tree whats_returned = TREE_OPERAND (retval, 0); + + if (TREE_CODE (whats_returned) == VAR_DECL + && DECL_NAME (whats_returned) + && IDENTIFIER_LOCAL_VALUE (DECL_NAME (whats_returned)) + && !TREE_STATIC (whats_returned) + && !TREE_PUBLIC (whats_returned)) + cp_warning_at ("address of local variable `%D' returned", whats_returned); + } } if (retval != NULL_TREE