- /* FIXME: This is where we should check for expressions with no
- effects. At the moment we do that in both build_x_component_expr
- and expand_expr_stmt -- inconsistently too. For the moment
- leave implicit void conversions unadorned so that expand_expr_stmt
- has a chance of detecting some of the cases. */
- if (!implicit)
- expr = build1 (CONVERT_EXPR, void_type_node, expr);
+ if (implicit
+ && warn_unused_value
+ && !TREE_NO_WARNING (expr)
+ && !processing_template_decl)
+ {
+ /* The middle end does not warn about expressions that have
+ been explicitly cast to void, so we must do so here. */
+ if (!TREE_SIDE_EFFECTS (expr)) {
+ if (complain & tf_warning)
+ warning (OPT_Wunused_value, "%s has no effect", implicit);
+ }
+ else
+ {
+ tree e;
+ enum tree_code code;
+ enum tree_code_class tclass;
+
+ e = expr;
+ /* We might like to warn about (say) "(int) f()", as the
+ cast has no effect, but the compiler itself will
+ generate implicit conversions under some
+ circumstances. (For example a block copy will be
+ turned into a call to "__builtin_memcpy", with a
+ conversion of the return value to an appropriate
+ type.) So, to avoid false positives, we strip
+ conversions. Do not use STRIP_NOPs because it will
+ not strip conversions to "void", as that is not a
+ mode-preserving conversion. */
+ while (TREE_CODE (e) == NOP_EXPR)
+ e = TREE_OPERAND (e, 0);
+
+ code = TREE_CODE (e);
+ tclass = TREE_CODE_CLASS (code);
+ if ((tclass == tcc_comparison
+ || tclass == tcc_unary
+ || (tclass == tcc_binary
+ && !(code == MODIFY_EXPR
+ || code == INIT_EXPR
+ || code == PREDECREMENT_EXPR
+ || code == PREINCREMENT_EXPR
+ || code == POSTDECREMENT_EXPR
+ || code == POSTINCREMENT_EXPR)))
+ && (complain & tf_warning))
+ warning (OPT_Wunused_value, "value computed is not used");
+ }
+ }
+ expr = build1 (CONVERT_EXPR, void_type_node, expr);