================ @@ -0,0 +1,178 @@ +//=== PolymorphicPtrArithmetic.cpp ------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This checker reports pointer arithmetic operations on arrays of +// polymorphic objects, where the array has the type of its base class. +// Corresponds to the CTR56-CPP. Do not use pointer arithmetic on +// polymorphic objects +// +//===----------------------------------------------------------------------===// + +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h" +#include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" + +using namespace clang; +using namespace ento; + +namespace { +class PolymorphicPtrArithmeticChecker + : public Checker<check::PreStmt<BinaryOperator>, + check::PreStmt<ArraySubscriptExpr>> { + const BugType BT{this, + "Pointer arithmetic on polymorphic objects is undefined"}; + +protected: + class PtrCastVisitor : public BugReporterVisitor { + public: + void Profile(llvm::FoldingSetNodeID &ID) const override { + static int X = 0; + ID.AddPointer(&X); + } + PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, + BugReporterContext &BRC, + PathSensitiveBugReport &BR) override; + }; + + void checkTypedExpr(const Expr *E, CheckerContext &C) const; + +public: + void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const; + void checkPreStmt(const ArraySubscriptExpr *B, CheckerContext &C) const; +}; +} // namespace + +void PolymorphicPtrArithmeticChecker::checkPreStmt(const BinaryOperator *B, + CheckerContext &C) const { + if (!B->isAdditiveOp()) + return; + + bool IsLHSPtr = B->getLHS()->getType()->isAnyPointerType(); + bool IsRHSPtr = B->getRHS()->getType()->isAnyPointerType(); + if (!IsLHSPtr && !IsRHSPtr) + return; + + const Expr *E = IsLHSPtr ? B->getLHS() : B->getRHS(); + + checkTypedExpr(E, C); ---------------- NagyDonat wrote:
if ( ```suggestion if (B->getLHS()->getType()->isAnyPointerType()) checkTypedExpr(B->getLHS(), C); if (B->getRHS()->getType()->isAnyPointerType()) checkTypedExpr(B->getRHS(), C); ``` If the additive operator is a subtraction, then it's possible that both operands are pointers that should be checked. https://github.com/llvm/llvm-project/pull/82977 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits