diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1994-01-22 17:18:10 -0500 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1994-01-22 17:18:10 -0500 |
commit | 88a3dbc1a94b7bed9dfd556d4064d9b3ed721a11 (patch) | |
tree | 04c92440c5472daddbbdd32f096eecff6067cb6c | |
parent | 3a19aabc45f40cf20c867d292d9a38ebd29a6f48 (diff) | |
download | gcc-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.c | 30 |
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; |