[clang] [analyzer] Support C++23 static operator calls (PR #84972)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 12 23:45:20 PDT 2024
================
@@ -709,6 +710,60 @@ class CXXInstanceCall : public AnyFunctionCall {
}
};
+/// Represents a static C++ operator call.
+///
+/// "A" in this example.
+/// However, "B" and "C" are represented by SimpleFunctionCall.
+/// \code
+/// struct S {
+/// int pad;
+/// static void operator()(int x, int y);
+/// };
+/// S s{10};
+/// void (*fptr)(int, int) = &S::operator();
+///
+/// s(1, 2); // A
+/// S::operator()(1, 2); // B
+/// fptr(1, 2); // C
+/// \endcode
+class CXXStaticOperatorCall : public SimpleFunctionCall {
+ friend class CallEventManager;
+
+protected:
+ CXXStaticOperatorCall(const CallExpr *CE, ProgramStateRef St,
+ const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef)
+ : SimpleFunctionCall(CE, St, LCtx, ElemRef) {}
+ CXXStaticOperatorCall(const CXXStaticOperatorCall &Other) = default;
+
+ void cloneTo(void *Dest) const override {
+ new (Dest) CXXStaticOperatorCall(*this);
+ }
+
+public:
+ const CXXOperatorCallExpr *getOriginExpr() const override {
+ return cast<CXXOperatorCallExpr>(SimpleFunctionCall::getOriginExpr());
+ }
+
+ unsigned getNumArgs() const override {
+ // Ignore the implicit object parameter.
+ assert(getOriginExpr()->getNumArgs() > 0);
+ return getOriginExpr()->getNumArgs() - 1;
+ }
+
+ const Expr *getArgExpr(unsigned Index) const override {
+ // Ignore the implicit object parameter.
+ return getOriginExpr()->getArg(Index + 1);
+ }
+
+ Kind getKind() const override { return CE_CXXStaticOperator; }
+ StringRef getKindAsString() const override { return "CXXStaticOperatorCall"; }
+
+ static bool classof(const CallEvent *CA) {
+ return CA->getKind() == CE_CXXStaticOperator;
+ }
+};
----------------
tomasz-kaminski-sonarsource wrote:
Could you please add the following function.
I believe we should override first two to match the semantic described in `CallEvent`, because arguments include object argument, that do not have corresponding parameter.
Last is just for consistency.
```
std::optional<unsigned>
getAdjustedParameterIndex(unsigned ASTArgumentIndex) const override {
// For member operator calls argument 0 on the expression corresponds
// to implicit this-parameter on the declaration.
return (ASTArgumentIndex > 0)
? std::optional<unsigned>(ASTArgumentIndex - 1)
: std::nullopt;
}
unsigned getASTArgumentIndex(unsigned CallArgumentIndex) const override {
// For member operator calls argument 0 on the expression corresponds
// to implicit this-parameter on the declaration.
return CallArgumentIndex + 1;
}
OverloadedOperatorKind getOverloadedOperator() const {
return getOriginExpr()->getOperator();
}
```
https://github.com/llvm/llvm-project/pull/84972
More information about the cfe-commits
mailing list