зеркало из https://github.com/microsoft/clang-1.git
There is no reason for dereferencing a pointer-to-member to require
that the class type into which the pointer points be complete, even though the standard requires it. GCC/EDG do not require a complete type here, so we're calling this a problem with the standard. Fixes PR8328. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116429 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
43c0a4cae0
Коммит
7d520baec9
|
@ -2279,8 +2279,11 @@ QualType Sema::CheckPointerToMemberOperands(
|
|||
|
||||
QualType Class(MemPtr->getClass(), 0);
|
||||
|
||||
if (RequireCompleteType(Loc, Class, diag::err_memptr_rhs_to_incomplete))
|
||||
return QualType();
|
||||
// Note: C++ [expr.mptr.oper]p2-3 says that the class type into which the
|
||||
// member pointer points must be completely-defined. However, there is no
|
||||
// reason for this semantic distinction, and the rule is not enforced by
|
||||
// other compilers. Therefore, we do not check this property, as it is
|
||||
// likely to be considered a defect.
|
||||
|
||||
// C++ 5.5p2
|
||||
// [...] to its first operand, which shall be of class T or of a class of
|
||||
|
|
|
@ -88,7 +88,7 @@ void g() {
|
|||
void (HasMembers::*pmd)() = &HasMembers::d;
|
||||
}
|
||||
|
||||
struct Incomplete; // expected-note {{forward declaration}}
|
||||
struct Incomplete;
|
||||
|
||||
void h() {
|
||||
HasMembers hm, *phm = &hm;
|
||||
|
@ -121,9 +121,10 @@ void h() {
|
|||
(void)(hm.*i); // expected-error {{pointer-to-member}}
|
||||
(void)(phm->*i); // expected-error {{pointer-to-member}}
|
||||
|
||||
// Okay
|
||||
Incomplete *inc;
|
||||
int Incomplete::*pii = 0;
|
||||
(void)(inc->*pii); // expected-error {{pointer into incomplete}}
|
||||
(void)(inc->*pii);
|
||||
}
|
||||
|
||||
struct OverloadsPtrMem
|
||||
|
|
|
@ -11,8 +11,7 @@ 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 'long (long)'}}
|
||||
// expected-error{{data member instantiated with function type 'float (float)'}}
|
||||
};
|
||||
|
||||
X<int> f() { return 0; }
|
||||
|
@ -44,7 +43,6 @@ void test_memptr(X<long> *p1, long X<long>::*pm1,
|
|||
X<long(long)> *p2,
|
||||
long (X<long(long)>::*pm2)(long)) {
|
||||
(void)(p1->*pm1);
|
||||
(void)((p2->*pm2)(0)); // expected-note{{in instantiation of template class 'X<long (long)>' requested here}}
|
||||
}
|
||||
|
||||
// Reference binding to a base
|
||||
|
|
Загрузка…
Ссылка в новой задаче