forked from OSchip/llvm-project
When a member pointer is dereferenced, the class it points into must be complete. Enforce this.
llvm-svn: 100925
This commit is contained in:
parent
e2f3524f83
commit
c72350ea9f
|
@ -2140,6 +2140,8 @@ def err_qualified_catch_declarator : Error<
|
||||||
def err_early_catch_all : Error<"catch-all handler must come last">;
|
def err_early_catch_all : Error<"catch-all handler must come last">;
|
||||||
def err_bad_memptr_rhs : Error<
|
def err_bad_memptr_rhs : Error<
|
||||||
"right hand operand to %0 has non pointer-to-member type %1">;
|
"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<
|
def err_bad_memptr_lhs : Error<
|
||||||
"left hand operand to %0 must be a %select{|pointer to }1class "
|
"left hand operand to %0 must be a %select{|pointer to }1class "
|
||||||
"compatible with the right hand operand, but is %2">;
|
"compatible with the right hand operand, but is %2">;
|
||||||
|
|
|
@ -1847,6 +1847,9 @@ QualType Sema::CheckPointerToMemberOperands(
|
||||||
|
|
||||||
QualType Class(MemPtr->getClass(), 0);
|
QualType Class(MemPtr->getClass(), 0);
|
||||||
|
|
||||||
|
if (RequireCompleteType(Loc, Class, diag::err_memptr_rhs_to_incomplete))
|
||||||
|
return QualType();
|
||||||
|
|
||||||
// C++ 5.5p2
|
// C++ 5.5p2
|
||||||
// [...] to its first operand, which shall be of class T or of a class of
|
// [...] 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
|
// which T is an unambiguous and accessible base class. [p3: a pointer to
|
||||||
|
|
|
@ -88,7 +88,7 @@ void g() {
|
||||||
void (HasMembers::*pmd)() = &HasMembers::d;
|
void (HasMembers::*pmd)() = &HasMembers::d;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Incomplete;
|
struct Incomplete; // expected-note {{forward declaration}}
|
||||||
|
|
||||||
void h() {
|
void h() {
|
||||||
HasMembers hm, *phm = &hm;
|
HasMembers hm, *phm = &hm;
|
||||||
|
@ -123,7 +123,7 @@ void h() {
|
||||||
|
|
||||||
Incomplete *inc;
|
Incomplete *inc;
|
||||||
int Incomplete::*pii = 0;
|
int Incomplete::*pii = 0;
|
||||||
(void)(inc->*pii); // okay
|
(void)(inc->*pii); // expected-error {{pointer into incomplete}}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OverloadsPtrMem
|
struct OverloadsPtrMem
|
||||||
|
|
|
@ -11,7 +11,8 @@ struct X {
|
||||||
// expected-error{{data member instantiated with function type 'int (int)'}} \
|
// 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 'char (char)'}} \
|
||||||
// expected-error{{data member instantiated with function type 'short (short)'}} \
|
// 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<int> f() { return 0; }
|
X<int> f() { return 0; }
|
||||||
|
@ -43,7 +44,7 @@ void test_memptr(X<long> *p1, long X<long>::*pm1,
|
||||||
X<long(long)> *p2,
|
X<long(long)> *p2,
|
||||||
long (X<long(long)>::*pm2)(long)) {
|
long (X<long(long)>::*pm2)(long)) {
|
||||||
(void)(p1->*pm1);
|
(void)(p1->*pm1);
|
||||||
(void)((p2->*pm2)(0));
|
(void)((p2->*pm2)(0)); // expected-note{{in instantiation of template class 'X<long (long)>' requested here}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reference binding to a base
|
// Reference binding to a base
|
||||||
|
|
Loading…
Reference in New Issue