PR19936: Fix a really dumb bug where we would profile dependent operator* expressions incorrectly.
llvm-svn: 210296
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 45e94d3..8d97d71 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -627,11 +627,11 @@
case OO_Star:
if (S->getNumArgs() == 1) {
- UnaryOp = UO_Minus;
+ UnaryOp = UO_Deref;
return Stmt::UnaryOperatorClass;
}
- BinaryOp = BO_Sub;
+ BinaryOp = BO_Mul;
return Stmt::BinaryOperatorClass;
case OO_Slash:
@@ -776,7 +776,7 @@
llvm_unreachable("Invalid overloaded operator expression");
}
-
+
void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
if (S->isTypeDependent()) {
@@ -785,7 +785,7 @@
UnaryOperatorKind UnaryOp = UO_Extension;
BinaryOperatorKind BinaryOp = BO_Comma;
Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp);
-
+
ID.AddInteger(SC);
for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
Visit(S->getArg(I));
@@ -796,10 +796,10 @@
ID.AddInteger(BinaryOp);
else
assert(SC == Stmt::ArraySubscriptExprClass);
-
+
return;
}
-
+
VisitCallExpr(S);
ID.AddInteger(S->getOperator());
}
diff --git a/clang/test/SemaTemplate/dependent-names.cpp b/clang/test/SemaTemplate/dependent-names.cpp
index 5a25030..011e073 100644
--- a/clang/test/SemaTemplate/dependent-names.cpp
+++ b/clang/test/SemaTemplate/dependent-names.cpp
@@ -399,3 +399,18 @@
using size_t = decltype(sizeof(0));
void *operator new(size_t, OperatorNew::X); // expected-note-re {{should be declared prior to the call site{{$}}}}
template void OperatorNew::f(OperatorNew::X); // expected-note {{instantiation of}}
+
+namespace PR19936 {
+ template<typename T> decltype(*T()) f() {} // expected-note {{previous}}
+ template<typename T> decltype(T() * T()) g() {} // expected-note {{previous}}
+
+ // Create some overloaded operators so we build an overload operator call
+ // instead of a builtin operator call for the dependent expression.
+ enum E {};
+ int operator*(E);
+ int operator*(E, E);
+
+ // Check that they still profile the same.
+ template<typename T> decltype(*T()) f() {} // expected-error {{redefinition}}
+ template<typename T> decltype(T() * T()) g() {} // expected-error {{redefinition}}
+}