https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86201
--- Comment #2 from Marek Polacek <mpolacek at gcc dot gnu.org> --- The problem here is that we report the missing return value: 9224 permerror (input_location, "return-statement with no value, in " 9225 "function returning %qT", valtype); but permerror will end up calling print_instantiation_full_context, which ends up calling dump_template_bindings and then tsubst -> tsubst_copy_and_build -> build_functional_cast -> ... -> ocp_convert which has (complain is tf_none) 829 if (complain & tf_warning) 830 return cp_truthvalue_conversion (e); 831 else 832 { 833 /* Prevent bogus -Wint-in-bool-context warnings coming 834 from c_common_truthvalue_conversion down the line. */ 835 warning_sentinel w (warn_int_in_bool_context); 836 return cp_truthvalue_conversion (e); 837 } So we call cp_truthvalue_conversion -> c_common_truthvalue_conversion -> build_binary_op which only calls cp_build_binary_op but with tf_warning_or_error. So even though the warning 4736 if ((complain & tf_warning) 4737 && (FLOAT_TYPE_P (type0) || FLOAT_TYPE_P (type1))) 4738 warning (OPT_Wfloat_equal, 4739 "comparing floating point with == or != is unsafe"); is properly guarded, we still re-enter the diagnostic routines.