================ @@ -0,0 +1,168 @@ +//=== StoreToImmutableChecker.cpp - Store to immutable memory ---*- 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 StoreToImmutableChecker, a checker that detects writes +// to immutable memory regions. This implements part of SEI CERT Rule ENV30-C. +// +//===----------------------------------------------------------------------===// + +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" + +using namespace clang; +using namespace ento; + +namespace { +class StoreToImmutableChecker : public Checker<check::Bind> { + const BugType BT{this, "Write to immutable memory", "CERT Environment (ENV)"}; + +public: + void checkBind(SVal Loc, SVal Val, const Stmt *S, CheckerContext &C) const; + +private: + bool isInitializationContext(const Stmt *S, CheckerContext &C) const; + bool isEffectivelyConstRegion(const MemRegion *MR, CheckerContext &C) const; +}; +} // end anonymous namespace + +bool StoreToImmutableChecker::isInitializationContext(const Stmt *S, + CheckerContext &C) const { + // Check if this is a DeclStmt (variable declaration) + if (isa<DeclStmt>(S)) + return true; + + // This part is specific for initialization of const lambdas pre-C++17. + // Lets look at the AST of the statement: + // ``` + // const auto lambda = [](){}; + // ``` + // + // The relevant part of the AST for this case prior to C++17 is: + // ... + // `-DeclStmt + // `-VarDecl + // `-ExprWithCleanups + // `-CXXConstructExpr + // ... + // In C++17 and later, the AST is different: + // ... + // `-DeclStmt + // `-VarDecl + // `-ImplicitCastExpr + // `-LambdaExpr + // |-CXXRecordDecl + // `-CXXConstructExpr + // ... + // And even beside this, the statement `S` that is given to the checkBind + // callback is the VarDecl in C++17 and later, and the CXXConstructExpr in + // C++14 and before. So in order to support the C++14 we need the following + // ugly hack to detect whether this construction is used to initialize a + // variable. + // + // FIXME: This should be eliminated once the API of checkBind would allow to + // distinguish between initialization and assignment, because this information + // is already available in the engine, it is just not passed to the checker + // API. ---------------- gamesh411 wrote:
Added this with a sidenote. https://github.com/llvm/llvm-project/pull/150417 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits