@@ -9391,6 +9391,19 @@ In a cast involving pointer to member types this warning warns whenever
the type cast is changing the pointer to member type.
This warning is enabled by @option{-Wextra}.
+@opindex Wcast-user-defined
+@opindex Wno-cast-user-defined
+@item -Wcast-user-defined
+Warn when a cast to reference type does not involve a user-defined
+conversion that the programmer might expect to be called.
+
+@smallexample
+struct A @{ operator const int&(); @} a;
+auto r = (int&)a; // warning
+@end smallexample
+
+This warning is enabled by default.
+
@opindex Wwrite-strings
@opindex Wno-write-strings
@item -Wwrite-strings
@@ -514,6 +514,10 @@ Wcast-qual
C ObjC C++ ObjC++ Var(warn_cast_qual) Warning
Warn about casts which discard qualifiers.
+Wcast-user-defined
+C++ ObjC++ Var(warn_cast_user_defined) Warning Init(1)
+Warn about a cast to reference type that does not use a related user-defined conversion function.
+
Wcatch-value
C++ ObjC++ Warning Alias(Wcatch-value=, 1, 0)
Warn about catch handlers of non-reference type.
@@ -2034,7 +2034,17 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
recalculate the second conversion sequence. */
for (conversion *t = conv; t; t = next_conversion (t))
if (t->kind == ck_user
- && DECL_CONV_FN_P (t->cand->fn))
+ && c_cast_p && !maybe_valid_p)
+ {
+ if (complain & tf_warning)
+ warning (OPT_Wcast_user_defined,
+ "casting %qT to %qT does not use %qD",
+ from, rto, t->cand->fn);
+ /* Don't let recalculation try to make this valid. */
+ break;
+ }
+ else if (t->kind == ck_user
+ && DECL_CONV_FN_P (t->cand->fn))
{
tree ftype = TREE_TYPE (TREE_TYPE (t->cand->fn));
/* A prvalue of non-class type is cv-unqualified. */
new file mode 100644
@@ -0,0 +1,20 @@
+// PR c++/113141
+
+struct Matrix { };
+
+struct TPoint3 { private: operator const Matrix(); };
+
+void f(Matrix&);
+
+int main() {
+ TPoint3 X;
+ Matrix& m = (Matrix &)X; // { dg-warning "does not use" }
+ f((Matrix &)X); // { dg-warning "does not use" }
+}
+
+struct A { private: operator const int&(); } a;
+int &r = (int&)a; // { dg-warning "does not use" }
+
+struct B { B(int); };
+int i;
+B &br = (B&)i; // { dg-warning "does not use" }