aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1994-01-22 17:18:10 -0500
committerRichard Kenner <kenner@gcc.gnu.org>1994-01-22 17:18:10 -0500
commit88a3dbc1a94b7bed9dfd556d4064d9b3ed721a11 (patch)
tree04c92440c5472daddbbdd32f096eecff6067cb6c
parent3a19aabc45f40cf20c867d292d9a38ebd29a6f48 (diff)
downloadgcc-88a3dbc1a94b7bed9dfd556d4064d9b3ed721a11.zip
gcc-88a3dbc1a94b7bed9dfd556d4064d9b3ed721a11.tar.gz
gcc-88a3dbc1a94b7bed9dfd556d4064d9b3ed721a11.tar.bz2
(c_expand_return): Issue a warning if returning address of non-static
local object. From-SVN: r6405
-rw-r--r--gcc/c-typeck.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index b952828..f2f507d 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -1,5 +1,5 @@
/* Build expressions with type checking for C compiler.
- Copyright (C) 1987, 1988, 1989, 1992, 1993 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 91, 92, 93, 1994 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -6202,12 +6202,36 @@ c_expand_return (retval)
tree t = convert_for_assignment (valtype, retval, "return",
NULL_TREE, NULL_TREE, 0);
tree res = DECL_RESULT (current_function_decl);
+ tree inner;
if (t == error_mark_node)
return;
- t = build (MODIFY_EXPR, TREE_TYPE (res),
- res, convert (TREE_TYPE (res), t));
+ inner = t = convert (TREE_TYPE (res), t);
+
+ /* Strip any conversions, additions, and subtractions, and see if
+ we are returning the address of a local variable. Warn if so. */
+ while (TREE_CODE (inner) == NOP_EXPR
+ || TREE_CODE (inner) == NON_LVALUE_EXPR
+ || TREE_CODE (inner) == CONVERT_EXPR
+ || TREE_CODE (inner) == PLUS_EXPR
+ || TREE_CODE (inner) == MINUS_EXPR)
+ inner = TREE_OPERAND (inner, 0);
+
+ if (TREE_CODE (inner) == ADDR_EXPR)
+ {
+ inner = TREE_OPERAND (inner, 0);
+
+ while (TREE_CODE_CLASS (TREE_CODE (inner)) == 'r')
+ inner = TREE_OPERAND (inner, 0);
+
+ if (TREE_CODE (inner) == VAR_DECL
+ && ! TREE_STATIC (inner)
+ && DECL_CONTEXT (inner) == current_function_decl)
+ warning ("function returns address of local variable");
+ }
+
+ t = build (MODIFY_EXPR, TREE_TYPE (res), res, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_return (t);
current_function_returns_value = 1;