diff options
-rw-r--r-- | clang/lib/AST/StmtProfile.cpp | 6 | ||||
-rw-r--r-- | clang/test/SemaTemplate/dependent-type-identity.cpp | 9 |
2 files changed, 15 insertions, 0 deletions
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 9aead7b06bc..cf965aa0284 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -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); diff --git a/clang/test/SemaTemplate/dependent-type-identity.cpp b/clang/test/SemaTemplate/dependent-type-identity.cpp index 6b23a38f848..c826268c864 100644 --- a/clang/test/SemaTemplate/dependent-type-identity.cpp +++ b/clang/test/SemaTemplate/dependent-type-identity.cpp @@ -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 { |