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. */
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))
return error_mark_node;
}
if (code == BOOLEAN_TYPE)
- {
- tree fn = NULL_TREE;
-
- /* Common Ada/Pascal programmer's mistake. We always warn
- about this since it is so bad. */
- if (TREE_CODE (expr) == FUNCTION_DECL)
- fn = expr;
- else if (TREE_CODE (expr) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (expr, 0)) == FUNCTION_DECL)
- fn = TREE_OPERAND (expr, 0);
- if (fn && !DECL_WEAK (fn))
- warning ("the address of `%D', will always be `true'", fn);
- return cp_truthvalue_conversion (e);
- }
+ return cp_truthvalue_conversion (e);
+
return fold (convert_to_integer (type, e));
}
if (POINTER_TYPE_P (type) || TYPE_PTR_TO_MEMBER_P (type))