From f15acc5f5cb36c60d9c20cf9dc58d0408cec1264 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 5 Jun 2014 22:43:40 +0000 Subject: [PATCH] PR19936: Fix a really dumb bug where we would profile dependent operator* expressions incorrectly. llvm-svn: 210296 --- clang/lib/AST/StmtProfile.cpp | 12 ++++++------ clang/test/SemaTemplate/dependent-names.cpp | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) 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 @@ static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S, 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 @@ static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S, llvm_unreachable("Invalid overloaded operator expression"); } - + void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) { if (S->isTypeDependent()) { @@ -785,7 +785,7 @@ void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) { 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 @@ void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) { 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 @@ namespace OperatorNew { 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 decltype(*T()) f() {} // expected-note {{previous}} + template 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 decltype(*T()) f() {} // expected-error {{redefinition}} + template decltype(T() * T()) g() {} // expected-error {{redefinition}} +} -- 2.7.4