Ping.

On Mon, Jun 22, 2020 at 10:09:27PM -0400, Marek Polacek via Gcc-patches wrote:
> convert_like issues errors about bad_p conversions at the beginning
> of the function, but in the ck_ref_bind case, it only issues them
> after we've called convert_like on the next conversion.
> 
> This doesn't work as expected since r10-7096 because when we see
> a conversion from/to class type in a template, we return early, thereby
> missing the error, and a bad_p conversion goes by undetected.  That
> made the attached test to compile even though it should not.
> 
> I had thought that I could just move the ck_ref_bind/bad_p errors
> above to the rest of them, but that regressed diagnostics because
> expr then wasn't converted yet by the nested convert_like_real call.
> 
> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk and 10?
> 
> gcc/cp/ChangeLog:
> 
>       PR c++/95789
>       * call.c (convert_like_real): Do the normal processing for
>       ck_ref_bind conversion that are bad_p.
> 
> gcc/testsuite/ChangeLog:
> 
>       PR c++/95789
>       * g++.dg/conversion/ref4.C: New test.
> ---
>  gcc/cp/call.c                          |  9 ++++++++-
>  gcc/testsuite/g++.dg/conversion/ref4.C | 22 ++++++++++++++++++++++
>  2 files changed, 30 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/g++.dg/conversion/ref4.C
> 
> diff --git a/gcc/cp/call.c b/gcc/cp/call.c
> index 2b39a3700fc..7b16895d5db 100644
> --- a/gcc/cp/call.c
> +++ b/gcc/cp/call.c
> @@ -7402,7 +7402,14 @@ convert_like_real (conversion *convs, tree expr, tree 
> fn, int argnum,
>       function.  */
>    if (processing_template_decl
>        && convs->kind != ck_identity
> -      && (CLASS_TYPE_P (totype) || CLASS_TYPE_P (TREE_TYPE (expr))))
> +      && (CLASS_TYPE_P (totype) || CLASS_TYPE_P (TREE_TYPE (expr)))
> +      /* Do the normal processing to give the bad_p errors in ck_ref_bind
> +      to avoid losing the fact that this conversion was bad.  Since we
> +      are going to return error_mark_node, we don't care about trees
> +      breaking in templates.  */
> +      && !(convs->kind == ck_ref_bind
> +        && convs->bad_p
> +        && !next_conversion (convs)->bad_p))
>      {
>        expr = build1 (IMPLICIT_CONV_EXPR, totype, expr);
>        return convs->kind == ck_ref_bind ? expr : convert_from_reference 
> (expr);
> diff --git a/gcc/testsuite/g++.dg/conversion/ref4.C 
> b/gcc/testsuite/g++.dg/conversion/ref4.C
> new file mode 100644
> index 00000000000..464a4cf6c0f
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/conversion/ref4.C
> @@ -0,0 +1,22 @@
> +// PR c++/95789
> +// { dg-do compile { target c++11 } }
> +
> +struct B {
> +    int n;
> +};
> +
> +template <typename T>
> +struct A {
> +    B& get() const { return f; } // { dg-error "binding reference" }
> +
> +    B f;
> +};
> +
> +int main() {
> +    A<int> a;
> +    a.f = {};
> +
> +    a.get().n = 10;
> +    if (a.f.n != 0)
> +      __builtin_abort();
> +}
> 
> base-commit: 0164e59835de81d758fd4c56248ad7a46435fbfa
> -- 
> Marek Polacek • Red Hat, Inc. • 300 A St, Boston, MA
> 

Marek

Reply via email to