https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104702
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #2) > I think the problem in this case are primarily the warning-control.cc > changes. > In GCC 11, build_vec_init did at the end: > /* Now make the result have the correct type. */ > if (TREE_CODE (atype) == ARRAY_TYPE) > { > atype = build_pointer_type (atype); > stmt_expr = build1 (NOP_EXPR, atype, stmt_expr); > stmt_expr = cp_build_fold_indirect_ref (stmt_expr); > TREE_NO_WARNING (stmt_expr) = 1; > } > GCC 12 does instead: > if (TREE_CODE (atype) == ARRAY_TYPE) > { > atype = build_pointer_type (atype); > stmt_expr = build1 (NOP_EXPR, atype, stmt_expr); > stmt_expr = cp_build_fold_indirect_ref (stmt_expr); > suppress_warning (stmt_expr /* What warning? */); > } > Clearly, at least one of the intended warnings that should be suppressed is > OPT_Wunused_value. > But as EXPR_LOCATION (stmt_expr) == UNKNOWN_LOCATION here, all > suppress_warning > does is set TREE_NO_WARNING bit on it (i.e. like GCC 11 used). > Later on, add_stmt is called on it and does: > if (!EXPR_HAS_LOCATION (t)) > SET_EXPR_LOCATION (t, input_location); > There was also even before build_vec_init a call to > suppress_warning with some unrelated expression that had the > 284032 {file = 0x3f67310 "pr104702.C", line = 11, column = 31, data = 0x0, > sysp = false} > location (with OPT_Wparentheses) which is the input_location now newly set > by add_stmt on the INDIRECT_REF. > Later on, convert_to_void calls > && !warning_suppressed_p (expr, OPT_Wunused_value) > on the INDIRECT_REF. TREE_NO_WARNING bit is set, but at this point it has a > location, so it looks up the location in hash map, finds that > OPT_Wparantheses > is the warning to be suppressed there and returns that OPT_Wunused_value > isn't suppressed there, even when we wanted to suppress all warnings on the > tree. So shouldn't warning_suppressed_p (tree, ...) also honor TREE_NO_WARNING even if a location is present? That is, diff --git a/gcc/warning-control.cc b/gcc/warning-control.cc index 0cbb4f079fa..d36f3ff6965 100644 --- a/gcc/warning-control.cc +++ b/gcc/warning-control.cc @@ -120,10 +120,12 @@ get_nowarn_spec (const gimple *stmt) bool warning_suppressed_p (const_tree expr, opt_code opt /* = all_warnings */) { - const nowarn_spec_t *spec = get_nowarn_spec (expr); + if (get_no_warning_bit (expr)) + return true; + const nowarn_spec_t *spec = get_nowarn_spec (expr); if (!spec) - return get_no_warning_bit (expr); + return false; const nowarn_spec_t optspec (opt); bool dis = *spec & optspec; or, if that's not desired, at least gcc_checking_assert (!get_no_warning_bit (expr)); when there's a spec?