+2018-12-17 Jonathan Wakely <jwakely@redhat.com>
+
+ PR c++/52321
+ * typeck.c (build_static_cast): Print a note when the destination
+ type or the operand is a pointer/reference to incomplete class type.
+
2018-12-16 Jakub Jelinek <jakub@redhat.com>
PR c++/88482
}
if (complain & tf_error)
- error ("invalid static_cast from type %qT to type %qT",
- TREE_TYPE (expr), type);
+ {
+ error ("invalid static_cast from type %qT to type %qT",
+ TREE_TYPE (expr), type);
+ if ((TYPE_PTR_P (type) || TYPE_REF_P (type))
+ && CLASS_TYPE_P (TREE_TYPE (type))
+ && !COMPLETE_TYPE_P (TREE_TYPE (type)))
+ inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (TREE_TYPE (type))),
+ "class type %qT is incomplete", TREE_TYPE (type));
+ tree expr_type = TREE_TYPE (expr);
+ if (TYPE_PTR_P (expr_type))
+ expr_type = TREE_TYPE (expr_type);
+ if (CLASS_TYPE_P (expr_type) && !COMPLETE_TYPE_P (expr_type))
+ inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (expr_type)),
+ "class type %qT is incomplete", expr_type);
+ }
return error_mark_node;
}
--- /dev/null
+// PR c++/52321
+struct A1; // { dg-message "note: class type 'A1' is incomplete" }
+struct A2; // { dg-message "note: class type 'A2' is incomplete" }
+struct B1; // { dg-message "note: class type 'B1' is incomplete" }
+struct B2; // { dg-message "note: class type 'B2' is incomplete" }
+
+struct C { };
+extern C* c;
+
+void pointers(C* c, A2* a2, B1* b1)
+{
+ (void) static_cast<A1*>(c); // { dg-error "invalid static_cast" }
+ (void) static_cast<C*>(a2); // { dg-error "invalid static_cast" }
+ (void) static_cast<B2*>(b1); // { dg-error "invalid static_cast" }
+}
+
+struct D1; // { dg-message "note: class type 'D1' is incomplete" }
+struct D2; // { dg-message "note: class type 'D2' is incomplete" }
+struct E1; // { dg-message "note: class type 'E1' is incomplete" }
+struct E2; // { dg-message "note: class type 'E2' is incomplete" }
+
+void references(C& c, D2& d2, E1& e1)
+{
+ (void) static_cast<D1&>(c); // { dg-error "invalid static_cast" }
+ (void) static_cast<C&>(d2); // { dg-error "invalid static_cast" }
+ (void) static_cast<E2&>(e1); // { dg-error "invalid static_cast" }
+}