From c72350ea9ff3d0df5206130c36fdb81f23b972da Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Sat, 10 Apr 2010 10:14:54 +0000 Subject: [PATCH] When a member pointer is dereferenced, the class it points into must be complete. Enforce this. llvm-svn: 100925 --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ clang/lib/Sema/SemaExprCXX.cpp | 3 +++ clang/test/SemaCXX/member-pointer.cpp | 4 ++-- clang/test/SemaTemplate/instantiate-complete.cpp | 5 +++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index b29d07115f82..7f99cff5949d 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2140,6 +2140,8 @@ def err_qualified_catch_declarator : Error< def err_early_catch_all : Error<"catch-all handler must come last">; def err_bad_memptr_rhs : Error< "right hand operand to %0 has non pointer-to-member type %1">; +def err_memptr_rhs_to_incomplete : Error< + "cannot dereference pointer into incomplete class type %0">; def err_bad_memptr_lhs : Error< "left hand operand to %0 must be a %select{|pointer to }1class " "compatible with the right hand operand, but is %2">; diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 7efba3ab67f1..04b3d83f3e31 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1847,6 +1847,9 @@ QualType Sema::CheckPointerToMemberOperands( QualType Class(MemPtr->getClass(), 0); + if (RequireCompleteType(Loc, Class, diag::err_memptr_rhs_to_incomplete)) + return QualType(); + // C++ 5.5p2 // [...] to its first operand, which shall be of class T or of a class of // which T is an unambiguous and accessible base class. [p3: a pointer to diff --git a/clang/test/SemaCXX/member-pointer.cpp b/clang/test/SemaCXX/member-pointer.cpp index ebdc9210bfa5..aa941a19f61b 100644 --- a/clang/test/SemaCXX/member-pointer.cpp +++ b/clang/test/SemaCXX/member-pointer.cpp @@ -88,7 +88,7 @@ void g() { void (HasMembers::*pmd)() = &HasMembers::d; } -struct Incomplete; +struct Incomplete; // expected-note {{forward declaration}} void h() { HasMembers hm, *phm = &hm; @@ -123,7 +123,7 @@ void h() { Incomplete *inc; int Incomplete::*pii = 0; - (void)(inc->*pii); // okay + (void)(inc->*pii); // expected-error {{pointer into incomplete}} } struct OverloadsPtrMem diff --git a/clang/test/SemaTemplate/instantiate-complete.cpp b/clang/test/SemaTemplate/instantiate-complete.cpp index 82cc320fd3c4..bc91112497de 100644 --- a/clang/test/SemaTemplate/instantiate-complete.cpp +++ b/clang/test/SemaTemplate/instantiate-complete.cpp @@ -11,7 +11,8 @@ struct X { // expected-error{{data member instantiated with function type 'int (int)'}} \ // expected-error{{data member instantiated with function type 'char (char)'}} \ // expected-error{{data member instantiated with function type 'short (short)'}} \ - // expected-error{{data member instantiated with function type 'float (float)'}} + // expected-error{{data member instantiated with function type 'float (float)'}} \ + // expected-error{{data member instantiated with function type 'long (long)'}} }; X f() { return 0; } @@ -43,7 +44,7 @@ void test_memptr(X *p1, long X::*pm1, X *p2, long (X::*pm2)(long)) { (void)(p1->*pm1); - (void)((p2->*pm2)(0)); + (void)((p2->*pm2)(0)); // expected-note{{in instantiation of template class 'X' requested here}} } // Reference binding to a base