This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for c++/87357, missing -Wconversion warning


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.

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

2018-09-18  Marek Polacek  <polacek@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" }
+};


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]