PR c++/52321 print note for static_cast to/from incomplete type
authorJonathan Wakely <jwakely@redhat.com>
Mon, 17 Dec 2018 21:49:58 +0000 (21:49 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Mon, 17 Dec 2018 21:49:58 +0000 (21:49 +0000)
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.

From-SVN: r267219

gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/g++.dg/expr/static_cast8.C [new file with mode: 0644]

index d12173e69e9dcbf8dee80c48161a3e729247a650..a7ec887d9c02afd56b9572f0fa30ef3100e72e43 100644 (file)
@@ -1,3 +1,9 @@
+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
index ac0c81155b5a7db77896976c20b9dbf042df133e..47ddad16fc1019473fe1a0dfa045abd531aac832 100644 (file)
@@ -7348,8 +7348,21 @@ build_static_cast (tree type, tree oexpr, tsubst_flags_t complain)
     }
 
   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;
 }
 
diff --git a/gcc/testsuite/g++.dg/expr/static_cast8.C b/gcc/testsuite/g++.dg/expr/static_cast8.C
new file mode 100644 (file)
index 0000000..dc4d216
--- /dev/null
@@ -0,0 +1,27 @@
+// 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" }
+}