]> granicus.if.org Git - clang/commitdiff
Improve checking of member expressions where the base type is a dependent type.
authorAnders Carlsson <andersca@mac.com>
Sat, 16 May 2009 20:31:20 +0000 (20:31 +0000)
committerAnders Carlsson <andersca@mac.com>
Sat, 16 May 2009 20:31:20 +0000 (20:31 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71956 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/SemaTemplate/instantiate-function-1.mm [new file with mode: 0644]

index 77902d55130b09c998c17c6374ed4e2d0cac5799..6a0253823c02b5faa1f6aaa5e7886bd3469b85d0 100644 (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
diff --git a/test/SemaTemplate/instantiate-function-1.mm b/test/SemaTemplate/instantiate-function-1.mm
new file mode 100644 (file)
index 0000000..aef2d9d
--- /dev/null
@@ -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}}
+  }
+};