This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/82134] warn_unused_result triggers on empty structs even when they are used
- From: "jakub at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Thu, 07 Sep 2017 15:06:20 +0000
- Subject: [Bug c/82134] warn_unused_result triggers on empty structs even when they are used
- Auto-submitted: auto-generated
- References: <bug-82134-4@http.gcc.gnu.org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82134
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jakub at gcc dot gnu.org
--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I fail to see the usefulness of warn_unused_result attribute on functions that
return such types, what kind of problem is calling those without assigning that
to a var? There are no data copied...
>From implementation POV, the problem is that the empty structure copies are
discarded during gimplification (in different spots, for C++ they are discarded
through cp-gimplify.c (cp_gimplify_expr) doing:
else if (simple_empty_class_p (TREE_TYPE (op0), op1))
{
/* Remove any copies of empty classes. Also drop volatile
variables on the RHS to avoid infinite recursion from
gimplify_expr trying to load the value. */
if (TREE_SIDE_EFFECTS (op1))
{
if (TREE_THIS_VOLATILE (op1)
&& (REFERENCE_CLASS_P (op1) || DECL_P (op1)))
op1 = build_fold_addr_expr (op1);
gimplify_and_add (op1, pre_p);
}
gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
is_gimple_lvalue, fb_lvalue);
*expr_p = TREE_OPERAND (*expr_p, 0);
}
while for C, it is done through gimplify.c (gimplify_modify_expr) doing:
/* For zero sized types only gimplify the left hand side and right hand
side as statements and throw away the assignment. Do this after
gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
types properly. */
if (zero_sized_type (TREE_TYPE (*from_p)) && !want_value)
{
gimplify_stmt (from_p, pre_p);
gimplify_stmt (to_p, pre_p);
*expr_p = NULL_TREE;
return GS_ALL_DONE;
}
and after that there is no way to differentiate if the call had a lhs or not.
Perhaps we could add a langhook and for zero_sized_type or if the langhook is
true (would use simple_empty_class_p for C++, otherwise false) just ignore the
warn_unused_result attribute or something similar; that would mean we wouldn't
warn in should_warn at least for C though (for C++ we would, because we turn it
into a TARGET_EXPR and warn as we voidify the call).