summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/AST/StmtProfile.cpp6
-rw-r--r--clang/test/SemaTemplate/dependent-type-identity.cpp9
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 {
OpenPOWER on IntegriCloud