]> granicus.if.org Git - clang/commitdiff
Fix crash if StmtProfile finds a type-dependent member access for which we have
authorRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 24 Oct 2016 18:47:04 +0000 (18:47 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 24 Oct 2016 18:47:04 +0000 (18:47 +0000)
resolved the -> to a call to a specific operator-> function. The particular
test case added here is actually being mishandled: the implicit member access
should not be type-dependent (because it's accessing a non-type-dependent
member of the current instantiation), but calls to a type-dependent operator->
that is a member of the current instantiation would be liable to hit the same
codepath.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@284999 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/StmtProfile.cpp
test/SemaTemplate/dependent-type-identity.cpp

index 9aead7b06bc3241752039eee89c7554ac73767da..cf965aa0284528924298a7d3012035c0a5b3f3ca 100644 (file)
@@ -1190,6 +1190,12 @@ void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
   if (S->isTypeDependent()) {
     // Type-dependent operator calls are profiled like their underlying
     // syntactic operator.
+    //
+    // An operator call to operator-> is always implicit, so just skip it. The
+    // enclosing MemberExpr will profile the actual member access.
+    if (S->getOperator() == OO_Arrow)
+      return Visit(S->getArg(0));
+
     UnaryOperatorKind UnaryOp = UO_Extension;
     BinaryOperatorKind BinaryOp = BO_Comma;
     Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp);
index 6b23a38f84863ddbb8792b3d531ae6a6628d6ba5..c826268c864c4ef76db7e969f49d766814467678 100644 (file)
@@ -80,11 +80,20 @@ namespace PR6851 {
     S< S<w>::cond && 1 > foo();
   };
 
+  struct Arrow { Arrow *operator->(); int n; };
+  template<typename T> struct M {
+    Arrow a;
+    auto f() -> M<decltype(a->n)>;
+  };
+
   struct Alien;
   bool operator&&(const Alien&, const Alien&);
 
   template <bool w>
   S< S<w>::cond && 1 > N::foo() { }
+
+  template<typename T>
+  auto M<T>::f() -> M<decltype(a->n)> {}
 }
 
 namespace PR7460 {