[clang] [clang][analyzer] Add StoreToImmutable checker (PR #150417)
Endre Fülöp via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 24 16:54:44 PDT 2025
================
@@ -0,0 +1,146 @@
+//=== StoreToImmutableChecker.cpp - Store to immutable memory checker -*- 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 isConstVariable(const MemRegion *MR, CheckerContext &C) const;
+ bool isConstQualifiedType(const MemRegion *MR, CheckerContext &C) const;
+};
+} // end anonymous namespace
+
+bool StoreToImmutableChecker::isConstVariable(const MemRegion *MR,
+ CheckerContext &C) const {
----------------
gamesh411 wrote:
As you suspected, no hits for ParamVarRegion or StringRegion.
ParamVarRegion may not even be possible to encounter in this context (just a guess), and I am not sure where is binding to a String region occurs. I will remove these two cases for now.
```
38| |bool StoreToImmutableChecker::isConstVariable(const MemRegion *MR,
39| 21| CheckerContext &C) const {
40| | // Check if the region is in the global immutable space
41| 21| const MemSpaceRegion *MS = MR->getMemorySpace(C.getState());
42| 21| if (isa<GlobalImmutableSpaceRegion>(MS))
43| 3| return true;
44| |
45| | // Check if this is a VarRegion with a const-qualified type
46| 18| if (const VarRegion *VR = dyn_cast<VarRegion>(MR)) {
47| 8| const VarDecl *VD = VR->getDecl();
48| 8| if (VD && VD->getType().isConstQualified())
49| 2| return true;
50| 8| }
51| |
52| | // Check if this is a ParamVarRegion with a const-qualified type
53| 16| if (const ParamVarRegion *PVR = dyn_cast<ParamVarRegion>(MR)) {
54| 0| const ParmVarDecl *PVD = PVR->getDecl();
55| 0| if (PVD && PVD->getType().isConstQualified())
56| 0| return true;
57| 0| }
58| |
59| | // Check if this is a FieldRegion with a const-qualified type
60| 16| if (const FieldRegion *FR = dyn_cast<FieldRegion>(MR)) {
61| 5| const FieldDecl *FD = FR->getDecl();
62| 5| if (FD && FD->getType().isConstQualified())
63| 4| return true;
64| 5| }
65| |
66| | // Check if this is a StringRegion (string literals are const)
67| 12| if (isa<StringRegion>(MR))
68| 0| return true;
69| |
70| | // Check if this is a SymbolicRegion with a const-qualified pointee type
71| 12| if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR)) {
72| 3| QualType PointeeType = SR->getPointeeStaticType();
73| 3| if (PointeeType.isConstQualified())
74| 3| return true;
75| 3| }
76| |
77| | // Check if this is an ElementRegion accessing a const array
78| 9| if (const ElementRegion *ER = dyn_cast<ElementRegion>(MR)) {
79| 2| return isConstQualifiedType(ER->getSuperRegion(), C);
80| 2| }
81| |
82| 7| return false;
83| 9|}
```
https://github.com/llvm/llvm-project/pull/150417
More information about the cfe-commits
mailing list