Remember to decay arrays to pointers before checking whether the
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 9 May 2019 22:22:48 +0000 (22:22 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 9 May 2019 22:22:48 +0000 (22:22 +0000)
left-hand side of an -> operator is a pointer to class type.

llvm-svn: 360387

clang/lib/Sema/SemaExprCXX.cpp
clang/test/Parser/cxx-class.cpp

index 6af59d5..683fc5b 100644 (file)
@@ -6790,9 +6790,12 @@ ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base,
       FirstIteration = false;
     }
 
-    if (OpKind == tok::arrow &&
-        (BaseType->isPointerType() || BaseType->isObjCObjectPointerType()))
-      BaseType = BaseType->getPointeeType();
+    if (OpKind == tok::arrow) {
+      if (BaseType->isPointerType())
+        BaseType = BaseType->getPointeeType();
+      else if (auto *AT = Context.getAsArrayType(BaseType))
+        BaseType = AT->getElementType();
+    }
   }
 
   // Objective-C properties allow "." access on Objective-C pointer types,
index fe9c1ac..e672c45 100644 (file)
@@ -283,6 +283,19 @@ struct C {} decltype(D())::c; // expected-error {{'decltype' cannot be used to n
 #endif
 }
 
+namespace ArrayMemberAccess {
+  struct A {
+    int x;
+    template<typename T> int f() const;
+  };
+  void f(const A (&a)[]) {
+    // OK: not a template-id.
+    bool cond = a->x < 10 && a->x > 0;
+    // OK: a template-id.
+    a->f<int>();
+  }
+}
+
 // PR11109 must appear at the end of the source file
 class pr11109r3 { // expected-note{{to match this '{'}}
   public // expected-error{{expected ':'}} expected-error{{expected '}'}} expected-error{{expected ';' after class}}