On Tue, Mar 16, 2021 at 06:56:47PM +0100, Jakub Jelinek wrote:
> Hi!
> 
> Honza has fairly recently changed operand_equal_p to compare
> DECL_FIELD_OFFSET for COMPONENT_REFs when comparing addresses.
> As the first testcase in this patch shows, while that is very nice
> for optimizations, for the -Wduplicated-branches warning it causes
> regressions.  Pedantically a union in both C and C++ has only one
> active member at a time, so using some other union member even if it has the
> same type is UB, so I think the warning shouldn't warn when it sees access
> to different fields that happen to have the same offset and should consider
> them different.
> In my first attempt to fix this I've keyed the old behavior on
> OEP_LEXICOGRAPHIC, but unfortunately that has various problems, the warning
> has a quick non-lexicographic compare in build_conditional_expr* and another
> lexicographic more expensive one later during genericization and turning the
> first one into lexicographic would mean wasting compile time on large
> conditionals.
> So, this patch instead introduces a new OEP_ flag and makes sure to pass it
> to operand_equal_p in all -Wduplicated-branches cases.
> 
> The cvt.c changes are because on the other testcase we were warning with
> UNKNOWN_LOCATION, so the user wouldn't really know where the questionable
> code is.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> 
> 2021-03-16  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR c++/99565
>       * tree-core.h (enum operand_equal_flag): Add OEP_DUPLICATED_BRANCHES.
>       * fold-const.c (operand_compare::operand_equal_p): Don't compare
>       field offsets if OEP_DUPLICATED_BRANCHES.
> 
>       * c-warn.c (do_warn_duplicated_branches): Pass also
>       OEP_DUPLICATED_BRANCHES to operand_equal_p.
> 
>       * c-typeck.c (build_conditional_expr): Pass OEP_DUPLICATED_BRANCHES
>       to operand_equal_p.
> 
>       * call.c (build_conditional_expr_1): Pass OEP_DUPLICATED_BRANCHES
>       to operand_equal_p.
>       * cvt.c (convert_to_void): Preserve location_t on COND_EXPR or
>       or COMPOUND_EXPR.
> 
>       * g++.dg/warn/Wduplicated-branches6.C: New test.
>       * g++.dg/warn/Wduplicated-branches7.C: New test.
> 
> --- gcc/tree-core.h.jj        2021-01-16 22:52:33.654413400 +0100
> +++ gcc/tree-core.h   2021-03-16 16:24:06.136829900 +0100
> @@ -896,7 +896,10 @@ enum operand_equal_flag {
>    OEP_HASH_CHECK = 32,
>    /* Makes operand_equal_p handle more expressions:  */
>    OEP_LEXICOGRAPHIC = 64,
> -  OEP_BITWISE = 128
> +  OEP_BITWISE = 128,
> +  /* Considers different fields different even when they have
> +     the same offset.  */
> +  OEP_DUPLICATED_BRANCHES = 256
>  };
>  
>  /* Enum and arrays used for tree allocation stats.
> --- gcc/fold-const.c.jj       2021-02-24 12:10:17.571212194 +0100
> +++ gcc/fold-const.c  2021-03-16 16:19:16.327018956 +0100
> @@ -3317,7 +3317,7 @@ operand_compare::operand_equal_p (const_
>           flags &= ~OEP_ADDRESS_OF;
>           if (!OP_SAME (1))
>             {
> -             if (compare_address)
> +             if (compare_address && (flags & OEP_DUPLICATED_BRANCHES) == 0)
>                 {
>                   if (TREE_OPERAND (arg0, 2)
>                       || TREE_OPERAND (arg1, 2))
> --- gcc/c-family/c-warn.c.jj  2021-02-12 23:57:30.459142340 +0100
> +++ gcc/c-family/c-warn.c     2021-03-16 16:24:19.224685926 +0100
> @@ -2779,7 +2779,8 @@ do_warn_duplicated_branches (tree expr)
>  
>    /* Compare the hashes.  */
>    if (h0 == h1
> -      && operand_equal_p (thenb, elseb, OEP_LEXICOGRAPHIC)
> +      && operand_equal_p (thenb, elseb, OEP_LEXICOGRAPHIC
> +                                     | OEP_DUPLICATED_BRANCHES)

This change isn't strictly necessary, OEP_DUPLICATED_BRANCHES is needed
mainly in build_conditional_expr*, right?  (It makes sense to me though,
so let's leave it in.)

>        /* Don't warn if any of the branches or their subexpressions comes
>        from a macro.  */
>        && !walk_tree_without_duplicates (&thenb, expr_from_macro_expansion_r,
> --- gcc/c/c-typeck.c.jj       2021-02-18 22:17:44.184657291 +0100
> +++ gcc/c/c-typeck.c  2021-03-16 16:23:58.335915719 +0100
> @@ -5490,7 +5490,7 @@ build_conditional_expr (location_t colon
>       warn here, because the COND_EXPR will be turned into OP1.  */
>    if (warn_duplicated_branches
>        && TREE_CODE (ret) == COND_EXPR
> -      && (op1 == op2 || operand_equal_p (op1, op2, 0)))
> +      && (op1 == op2 || operand_equal_p (op1, op2, OEP_DUPLICATED_BRANCHES)))
>      warning_at (EXPR_LOCATION (ret), OPT_Wduplicated_branches,
>               "this condition has identical branches");

The c/ and c-family/ parts are ok, thanks.

Marek

Reply via email to