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}} + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits