Consider the following ptrtomem4.C file.
Now for test1 and test3 it produces the following errors:
ptrtomem4.C: In function 'int test1(int Base::*, X*)':
ptrtomem4.C:8:21: error: pointer to member type 'int Base::*' incompatible with incomplete object type 'X'
ptrtomem4.C: In function 'int test3(int Base::*, Y*)':
ptrtomem4.C:22:21: error: pointer to member type 'int Base::*' incompatible with object type 'Y' because 'Y' is not derived from 'Base'
PR c++/38612
gcc/cp/ChangeLog:
* typeck2.cc (build_m_component_ref): Improve class mismatch
diagnostic.
gcc/testsuite/ChangeLog:
* g++.dg/diagnostic/ptrtomem4.C: New test.
Signed-off-by: Alex Yesmanchyk <aliaksandr.yesmanchyk@gmail.com>
Co-authored-by: Jason Merrill <jason@redhat.com>
{
mismatch:
if (complain & tf_error)
- error ("pointer to member type %qT incompatible with object "
- "type %qT", type, objtype);
+ {
+ if (COMPLETE_TYPE_P (objtype))
+ error ("pointer to member type %qT incompatible "
+ "with object type %qT because %qT is not "
+ "derived from %qT", ptrmem_type, objtype,
+ objtype, ctype);
+ else
+ error ("pointer to member type %qT incompatible with "
+ "incomplete object type %qT", ptrmem_type, objtype);
+ }
return error_mark_node;
}
else if (binfo == error_mark_node)
--- /dev/null
+// PR c++/38612
+
+struct Base {};
+struct X; // X derived from Base later but incomplete here
+struct Y {}; // Y not derived from Base
+
+int test1(int Base::* p2m, X* object)
+{
+ return object->*p2m; // { dg-error "int Base::.' incompatible with incomplete object type 'X'" }
+}
+
+struct X : Base
+{
+};
+
+int test2(int Base::* p2m, X* object)
+{
+ return object->*p2m; // OK
+}
+
+int test3(int Base::* p2m, Y* object)
+{
+ return object->*p2m; // { dg-error "int Base::.' incompatible with object type 'Y' because 'Y' is not derived from 'Base'" }
+}