[clang] 7f0ef7f - Fix profiling of overloaded postincrement / postdecrement.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 11 08:41:34 PDT 2023
Author: Richard Smith
Date: 2023-07-11T08:41:21-07:00
New Revision: 7f0ef7f304b1b91694f14e5c9c10de2aa6f38c95
URL: https://github.com/llvm/llvm-project/commit/7f0ef7f304b1b91694f14e5c9c10de2aa6f38c95
DIFF: https://github.com/llvm/llvm-project/commit/7f0ef7f304b1b91694f14e5c9c10de2aa6f38c95.diff
LOG: Fix profiling of overloaded postincrement / postdecrement.
We were accidentally profiling the fabricated second argument (`0`),
resulting in overloaded dependent `a++` and non-overloaded dependent
`a++` having different hashes.
Added:
clang/test/SemaTemplate/equivalence.cpp
Modified:
clang/lib/AST/StmtProfile.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 307ad4925d36b7..d8a667b2d0fdc4 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -1656,7 +1656,8 @@ void StmtProfiler::VisitRequiresExpr(const RequiresExpr *S) {
static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
UnaryOperatorKind &UnaryOp,
- BinaryOperatorKind &BinaryOp) {
+ BinaryOperatorKind &BinaryOp,
+ unsigned &NumArgs) {
switch (S->getOperator()) {
case OO_None:
case OO_New:
@@ -1669,7 +1670,7 @@ static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
llvm_unreachable("Invalid operator call kind");
case OO_Plus:
- if (S->getNumArgs() == 1) {
+ if (NumArgs == 1) {
UnaryOp = UO_Plus;
return Stmt::UnaryOperatorClass;
}
@@ -1678,7 +1679,7 @@ static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
return Stmt::BinaryOperatorClass;
case OO_Minus:
- if (S->getNumArgs() == 1) {
+ if (NumArgs == 1) {
UnaryOp = UO_Minus;
return Stmt::UnaryOperatorClass;
}
@@ -1687,7 +1688,7 @@ static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
return Stmt::BinaryOperatorClass;
case OO_Star:
- if (S->getNumArgs() == 1) {
+ if (NumArgs == 1) {
UnaryOp = UO_Deref;
return Stmt::UnaryOperatorClass;
}
@@ -1708,7 +1709,7 @@ static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
return Stmt::BinaryOperatorClass;
case OO_Amp:
- if (S->getNumArgs() == 1) {
+ if (NumArgs == 1) {
UnaryOp = UO_AddrOf;
return Stmt::UnaryOperatorClass;
}
@@ -1817,13 +1818,13 @@ static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
return Stmt::BinaryOperatorClass;
case OO_PlusPlus:
- UnaryOp = S->getNumArgs() == 1? UO_PreInc
- : UO_PostInc;
+ UnaryOp = NumArgs == 1 ? UO_PreInc : UO_PostInc;
+ NumArgs = 1;
return Stmt::UnaryOperatorClass;
case OO_MinusMinus:
- UnaryOp = S->getNumArgs() == 1? UO_PreDec
- : UO_PostDec;
+ UnaryOp = NumArgs == 1 ? UO_PreDec : UO_PostDec;
+ NumArgs = 1;
return Stmt::UnaryOperatorClass;
case OO_Comma:
@@ -1869,10 +1870,11 @@ void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
UnaryOperatorKind UnaryOp = UO_Extension;
BinaryOperatorKind BinaryOp = BO_Comma;
- Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp);
+ unsigned NumArgs = S->getNumArgs();
+ Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp, NumArgs);
ID.AddInteger(SC);
- for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
+ for (unsigned I = 0; I != NumArgs; ++I)
Visit(S->getArg(I));
if (SC == Stmt::UnaryOperatorClass)
ID.AddInteger(UnaryOp);
diff --git a/clang/test/SemaTemplate/equivalence.cpp b/clang/test/SemaTemplate/equivalence.cpp
new file mode 100644
index 00000000000000..24cd4054ac3763
--- /dev/null
+++ b/clang/test/SemaTemplate/equivalence.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Ensure we undo the rewrite from `a++` to a binary `a ++ 0` before profiling.
+namespace PostIncDec {
+ // Increment / decrement as UnaryOperator.
+ template<typename T> auto inc(T &a) -> decltype(a++) {} // expected-note {{previous}}
+ template<typename T> auto dec(T &a) -> decltype(a--) {} // expected-note {{previous}}
+
+ struct X {};
+ void operator++(X&, int);
+ void operator--(X&, int);
+ // Increment / decrement as CXXOverloadedCallExpr. These are redefinitions.
+ template<typename T> auto inc(T &a) -> decltype(a++) {} // expected-error {{redefinition}} expected-note {{candidate}}
+ template<typename T> auto dec(T &a) -> decltype(a--) {} // expected-error {{redefinition}} expected-note {{candidate}}
+
+ // These are not ambiguous calls.
+ void f(X x) {
+ // FIXME: Don't produce these follow-on errors.
+ inc(x); // expected-error {{no match}}
+ dec(x); // expected-error {{no match}}
+ }
+}
More information about the cfe-commits
mailing list