https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89850
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org, | |mpolacek at gcc dot gnu.org --- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Guess that is because /* Compare the hashes. */ if (h0 == h1 && operand_equal_p (thenb, elseb, OEP_LEXICOGRAPHIC) /* 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, NULL) && !walk_tree_without_duplicates (&elseb, expr_from_macro_expansion_r, NULL)) warning_at (EXPR_LOCATION (expr), OPT_Wduplicated_branches, "this condition has identical branches"); calls operand_equal_p with OEP_LEXICOGRAPHIC and that doesn't handle SAVE_EXPRs occuring more than once and nested inside of each other very well. case SAVE_EXPR: if (flags & OEP_LEXICOGRAPHIC) return OP_SAME (0); return 0; There is also a problem already before, when computing the hash, as inchash::add_expr doesn't special-case SAVE_EXPR at all. Now, to fix this properly we'd need to create some hash_map from the SAVE_EXPRs to their hash values and merge in that hash value each time we see it, instead of computing it again. And similarly for operand_equal_p, noting we've compared this SAVE_EXPR with that SAVE_EXPR successfully already once with OEP_LEXICOGRAPHIC and so that comparison pair is ok even in all following cases (at least with the same flags). But unfortunately there is no inchash::add_expr or operand_equal_p context where we could stick such a hash_map, unless it would be a global variable and we'd say required that if OEP_LEXICOGRAPHIC is used, then the caller must set the hash_map global var and release it at the end or something similar.