diff options
author | Steven Bosscher <steven@gcc.gnu.org> | 2003-10-12 22:09:29 +0000 |
---|---|---|
committer | Steven Bosscher <steven@gcc.gnu.org> | 2003-10-12 22:09:29 +0000 |
commit | 1998463c5498f70d5add37cdbeb3e73277a47851 (patch) | |
tree | d8508ce937bd1981385a02639c802f8107997f26 /gcc/c-common.c | |
parent | d60004eecf62e69a63dae2a66f4688e003ca3a62 (diff) | |
download | gcc-1998463c5498f70d5add37cdbeb3e73277a47851.zip gcc-1998463c5498f70d5add37cdbeb3e73277a47851.tar.gz gcc-1998463c5498f70d5add37cdbeb3e73277a47851.tar.bz2 |
c-common.c (c_common_truthvalue_conversion): Warn if the address of a non-weak function is used as a truth value.
gcc/
* c-common.c (c_common_truthvalue_conversion): Warn if the
address of a non-weak function is used as a truth value.
cp/
* cvt.c (ocp_convert): Move warning to C common code.
testsuite/
* gcc.dg/weak/weak-3.c: Fix for new warning.
From-SVN: r72409
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r-- | gcc/c-common.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c index b58eda1..e8ed13b 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -2602,6 +2602,9 @@ c_common_truthvalue_conversion (tree expr) if (TREE_CODE (expr) == ERROR_MARK) return expr; + if (TREE_CODE (expr) == FUNCTION_DECL) + expr = build_unary_op (ADDR_EXPR, expr, 0); + #if 0 /* This appears to be wrong for C++. */ /* These really should return error_mark_node after 2.4 is stable. But not all callers handle ERROR_MARK properly. */ @@ -2647,17 +2650,29 @@ c_common_truthvalue_conversion (tree expr) return real_zerop (expr) ? truthvalue_false_node : truthvalue_true_node; case ADDR_EXPR: - /* If we are taking the address of an external decl, it might be zero - if it is weak, so we cannot optimize. */ - if (DECL_P (TREE_OPERAND (expr, 0)) - && DECL_EXTERNAL (TREE_OPERAND (expr, 0))) - break; + { + if (TREE_CODE (TREE_OPERAND (expr, 0)) == FUNCTION_DECL + && ! DECL_WEAK (TREE_OPERAND (expr, 0))) + { + /* Common Ada/Pascal programmer's mistake. We always warn + about this since it is so bad. */ + warning ("the address of `%D', will always evaluate as `true'", + TREE_OPERAND (expr, 0)); + return truthvalue_true_node; + } - if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0))) - return build (COMPOUND_EXPR, truthvalue_type_node, - TREE_OPERAND (expr, 0), truthvalue_true_node); - else - return truthvalue_true_node; + /* If we are taking the address of an external decl, it might be + zero if it is weak, so we cannot optimize. */ + if (DECL_P (TREE_OPERAND (expr, 0)) + && DECL_EXTERNAL (TREE_OPERAND (expr, 0))) + break; + + if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0))) + return build (COMPOUND_EXPR, truthvalue_type_node, + TREE_OPERAND (expr, 0), truthvalue_true_node); + else + return truthvalue_true_node; + } case COMPLEX_EXPR: return build_binary_op ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)) |