From 524d5a4f5a15540fbcbd28d4b85fa1ec8481152d Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sat, 16 May 2009 20:31:20 +0000 Subject: [PATCH] Improve checking of member expressions where the base type is a dependent type. llvm-svn: 71956 --- clang/lib/Sema/SemaExpr.cpp | 26 ++++++++++++------- .../SemaTemplate/instantiate-function-1.mm | 14 ++++++++++ 2 files changed, 30 insertions(+), 10 deletions(-) create mode 100644 clang/test/SemaTemplate/instantiate-function-1.mm diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 77902d55130b..6a0253823c02 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -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 diff --git a/clang/test/SemaTemplate/instantiate-function-1.mm b/clang/test/SemaTemplate/instantiate-function-1.mm new file mode 100644 index 000000000000..aef2d9dbb7eb --- /dev/null +++ b/clang/test/SemaTemplate/instantiate-function-1.mm @@ -0,0 +1,14 @@ +template 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}} + } +};