зеркало из https://github.com/microsoft/clang-1.git
[ms-cxxabi] Add more tests for r178297
This covers a few cases where the class of a member pointer is not a CXXRecordDecl. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178307 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
4bbae38abf
Коммит
e93e2552e7
|
@ -1733,12 +1733,12 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class,
|
|||
// when passing pointers between TUs that disagree about the size.
|
||||
if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
|
||||
CXXRecordDecl *RD = Class->getAsCXXRecordDecl();
|
||||
if (!RD || !RD->hasAttr<MSInheritanceAttr>()) {
|
||||
if (RD && !RD->hasAttr<MSInheritanceAttr>()) {
|
||||
// Lock in the inheritance model on the first use of a member pointer.
|
||||
// Otherwise we may disagree about the size at different points in the TU.
|
||||
// FIXME: MSVC picks a model on the first use that needs to know the size,
|
||||
// rather than on the first mention of the type, e.g. typedefs.
|
||||
if (RequireCompleteType(Loc, Class, 0) && RD && !RD->isBeingDefined()) {
|
||||
if (RequireCompleteType(Loc, Class, 0) && !RD->isBeingDefined()) {
|
||||
// We know it doesn't have an attribute and it's incomplete, so use the
|
||||
// unspecified inheritance model. If we're in the record body, we can
|
||||
// figure out the inheritance model.
|
||||
|
|
|
@ -132,3 +132,36 @@ struct MemPtrInBody {
|
|||
};
|
||||
|
||||
static_assert(sizeof(MemPtrInBody::MemPtr) == kSingleDataSize, "");
|
||||
|
||||
// Passing a member pointer through a template should get the right size.
|
||||
template<typename T>
|
||||
struct SingleTemplate;
|
||||
template<typename T>
|
||||
struct SingleTemplate<void (T::*)(void)> {
|
||||
static_assert(sizeof(int T::*) == kSingleDataSize, "");
|
||||
static_assert(sizeof(void (T::*)()) == kSingleFunctionSize, "");
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct UnspecTemplate;
|
||||
template<typename T>
|
||||
struct UnspecTemplate<void (T::*)(void)> {
|
||||
static_assert(sizeof(int T::*) == kUnspecifiedDataSize, "");
|
||||
static_assert(sizeof(void (T::*)()) == kUnspecifiedFunctionSize, "");
|
||||
};
|
||||
|
||||
struct NewUnspecified;
|
||||
SingleTemplate<void (IncSingle::*)()> tmpl_single;
|
||||
UnspecTemplate<void (NewUnspecified::*)()> tmpl_unspec;
|
||||
|
||||
struct NewUnspecified { };
|
||||
|
||||
static_assert(sizeof(void (NewUnspecified::*)()) == kUnspecifiedFunctionSize, "");
|
||||
|
||||
template <typename T>
|
||||
struct MemPtrInTemplate {
|
||||
// We can't require that the template arg be complete until we're
|
||||
// instantiated.
|
||||
int T::*data_ptr;
|
||||
void (T::*func_ptr)();
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче