On Tue, Sep 18, 2018 at 11:47 PM, Marek Polacek <pola...@redhat.com> wrote:
> As I mentioned in the PR, [class.conv.fct] says "A conversion function is 
> never
> used to convert a (possibly cv-qualified) object to the (possibly 
> cv-qualified)
> same object type (or a reference to it), to a (possibly cv-qualified) base 
> class
> of that type (or a reference to it), or to (possibly cv-qualified) void." but 
> I
> noticed we weren't warning about
>
> struct X {
>   operator X();
> };
>
> (and there are no tests for this case) because comparing types directly only
> works for TYPE_CANONICAL, otherwise we have to use same_type_*.
>
> I'm also changing the warning about 'void' since we can't form a reference to
> void.
>
> I'll also note that I think we should warn about this by default, not only
> when -Wconversion is in effect.

Agreed, this should get a new flag that is on by default.

> Bootstrapped/regtested on x86_64-linux, ok for trunk?

OK.

> 2018-09-18  Marek Polacek  <pola...@redhat.com>
>
>         PR c++/87357 - missing -Wconversion warning
>         * decl.c (grok_op_properties): Remove diagnostic parts mentioning
>         a conversion to a reference to void.  Use
>         same_type_ignoring_top_level_qualifiers_p rather than comparing types
>         directly.
>
>         * g++.dg/warn/Wconversion5.C: New test.
>
> diff --git gcc/cp/decl.c gcc/cp/decl.c
> index 827c1720335..503b433cbd1 100644
> --- gcc/cp/decl.c
> +++ gcc/cp/decl.c
> @@ -13553,15 +13553,11 @@ grok_op_properties (tree decl, bool complain)
>         t = TYPE_MAIN_VARIANT (TREE_TYPE (t));
>
>        if (VOID_TYPE_P (t))
> -       warning_at (loc, OPT_Wconversion,
> -                   ref
> -                   ? G_("conversion to a reference to void "
> -                        "will never use a type conversion operator")
> -                   : G_("conversion to void "
> -                        "will never use a type conversion operator"));
> +       warning_at (loc, OPT_Wconversion, "conversion to void "
> +                   "will never use a type conversion operator");
>        else if (class_type)
>         {
> -         if (t == class_type)
> +         if (same_type_ignoring_top_level_qualifiers_p (t, class_type))
>             warning_at (loc, OPT_Wconversion,
>                         ref
>                         ? G_("conversion to a reference to the same type "
> diff --git gcc/testsuite/g++.dg/warn/Wconversion5.C 
> gcc/testsuite/g++.dg/warn/Wconversion5.C
> index e69de29bb2d..00b1ddab188 100644
> --- gcc/testsuite/g++.dg/warn/Wconversion5.C
> +++ gcc/testsuite/g++.dg/warn/Wconversion5.C
> @@ -0,0 +1,20 @@
> +// PR c++/87357
> +// { dg-do compile }
> +// { dg-options "-Wconversion" }
> +
> +struct B { };
> +
> +struct X : public B {
> +  operator X(); // { dg-warning "3:conversion to the same type will never 
> use a type conversion operator" }
> +  operator X&(); // { dg-warning "3:conversion to a reference to the same 
> type will never use a type conversion operator" }
> +  operator X() const; // { dg-warning "3:conversion to the same type will 
> never use a type conversion operator" }
> +  operator const X(); // { dg-warning "3:conversion to the same type will 
> never use a type conversion operator" }
> +
> +  operator B(); // { dg-warning "3:conversion to a base class will never use 
> a type conversion operator" }
> +  operator B&(); // { dg-warning "3:conversion to a reference to a base 
> class will never use a type conversion operator" }
> +  operator B() const; // { dg-warning "3:conversion to a base class will 
> never use a type conversion operator" }
> +  operator const B(); // { dg-warning "3:conversion to a base class will 
> never use a type conversion operator" }
> +
> +  operator void(); // { dg-warning "3:conversion to void will never use a 
> type conversion operator" }
> +  operator void() const; // { dg-warning "3:conversion to void will never 
> use a type conversion operator" }
> +};

Reply via email to