123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- //==- CheckSizeofPointer.cpp - Check for sizeof on pointers ------*- 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 file defines a check for unintended use of sizeof() on pointer
- // expressions.
- //
- //===----------------------------------------------------------------------===//
- #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
- #include "clang/AST/StmtVisitor.h"
- #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
- #include "clang/StaticAnalyzer/Core/Checker.h"
- #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
- using namespace clang;
- using namespace ento;
- namespace {
- class WalkAST : public StmtVisitor<WalkAST> {
- BugReporter &BR;
- const CheckerBase *Checker;
- AnalysisDeclContext* AC;
- public:
- WalkAST(BugReporter &br, const CheckerBase *checker, AnalysisDeclContext *ac)
- : BR(br), Checker(checker), AC(ac) {}
- void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
- void VisitStmt(Stmt *S) { VisitChildren(S); }
- void VisitChildren(Stmt *S);
- };
- }
- void WalkAST::VisitChildren(Stmt *S) {
- for (Stmt *Child : S->children())
- if (Child)
- Visit(Child);
- }
- // CWE-467: Use of sizeof() on a Pointer Type
- void WalkAST::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
- if (E->getKind() != UETT_SizeOf)
- return;
- // If an explicit type is used in the code, usually the coder knows what they are
- // doing.
- if (E->isArgumentType())
- return;
- QualType T = E->getTypeOfArgument();
- if (T->isPointerType()) {
- // Many false positives have the form 'sizeof *p'. This is reasonable
- // because people know what they are doing when they intentionally
- // dereference the pointer.
- Expr *ArgEx = E->getArgumentExpr();
- if (!isa<DeclRefExpr>(ArgEx->IgnoreParens()))
- return;
- PathDiagnosticLocation ELoc =
- PathDiagnosticLocation::createBegin(E, BR.getSourceManager(), AC);
- BR.EmitBasicReport(AC->getDecl(), Checker,
- "Potential unintended use of sizeof() on pointer type",
- categories::LogicError,
- "The code calls sizeof() on a pointer type. "
- "This can produce an unexpected result.",
- ELoc, ArgEx->getSourceRange());
- }
- }
- //===----------------------------------------------------------------------===//
- // SizeofPointerChecker
- //===----------------------------------------------------------------------===//
- namespace {
- class SizeofPointerChecker : public Checker<check::ASTCodeBody> {
- public:
- void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
- BugReporter &BR) const {
- WalkAST walker(BR, this, mgr.getAnalysisDeclContext(D));
- walker.Visit(D->getBody());
- }
- };
- }
- void ento::registerSizeofPointerChecker(CheckerManager &mgr) {
- mgr.registerChecker<SizeofPointerChecker>();
- }
- bool ento::shouldRegisterSizeofPointerChecker(const CheckerManager &mgr) {
- return true;
- }
|