[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