Improve checking of member expressions where the base type is a dependent type.

llvm-svn: 71956
This commit is contained in:
Anders Carlsson 2009-05-16 20:31:20 +00:00
parent f39ea8535b
commit 524d5a4f5a
2 changed files with 30 additions and 10 deletions

View File

@ -2035,16 +2035,22 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
diag::err_typecheck_member_reference_arrow)
<< BaseType << BaseExpr->getSourceRange());
} else {
// We use isTemplateTypeParmType directly here, instead of simply checking
// whether BaseType is dependent, because we want to report an error for
//
// T *t;
// t.foo;
//
//
if (BaseType->isTemplateTypeParmType())
return Owned(new (Context) MemberExpr(BaseExpr, false, 0,
MemberLoc, Context.DependentTy));
if (BaseType->isDependentType()) {
// Require that the base type isn't a pointer type
// (so we'll report an error for)
// T* t;
// t.f;
//
// In Obj-C++, however, the above expression is valid, since it could be
// accessing the 'f' property if T is an Obj-C interface. The extra check
// allows this, while still reporting an error if T is a struct pointer.
const PointerType *PT = BaseType->getAsPointerType();
if (!PT || (getLangOptions().ObjC1 &&
!PT->getPointeeType()->isRecordType()))
return Owned(new (Context) MemberExpr(BaseExpr, false, 0,
MemberLoc, Context.DependentTy));
}
}
// Handle field access to simple records. This also handles access to fields

View File

@ -0,0 +1,14 @@
template<typename T> struct Member0 {
void f(T t) {
t;
t.f;
t->f;
T* tp;
tp.f;
tp->f;
this->f;
this.f; // expected-error{{member reference base type 'struct Member0 *const' is not a structure or union}}
}
};