[clang] [analyzer] Add MemSpace trait to program state (PR #123003)
DonĂ¡t Nagy via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 15 06:00:40 PST 2025
================
@@ -0,0 +1,62 @@
+//===-- MemSpaces.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
+//
+//===----------------------------------------------------------------------===//
+//
+// TODO
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/MemSpaces.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
+#include <cassert>
+
+REGISTER_MAP_WITH_PROGRAMSTATE(MemSpacesMap, const clang::ento::MemRegion *,
+ const clang::ento::MemSpaceRegion *)
+
+namespace clang {
+namespace ento {
+namespace memspace {
+
+ProgramStateRef setMemSpaceTrait(ProgramStateRef State, const MemRegion *MR,
+ const MemSpaceRegion *MS) {
+ // for now, this should only be called to update the trait for mem regions
+ // that have an unknown mem spaces since we assume everywhere else that the
+ // memspace trait is set only for unknown mem spaces (setting this info
+ // otherwise would go unused).
+ assert(isa<UnknownSpaceRegion>(MR->getMemorySpace()));
+
+ // Shouldn't use the memspace trait to associate UnknownSpaceRegion with an
+ // already UnknownSpaceRegion
+ assert(!isa<UnknownSpaceRegion>(MS));
+
+ ProgramStateRef NewState = State->set<MemSpacesMap>(MR, MS);
----------------
NagyDonat wrote:
Your code can bind a memory space trait to any memory region, including regions like `ElementRegion`, `FieldRegion` etc. that are just parts of a bigger region. This could cause ugly inconsistencies, e.g. the analyzer could assume that one field of a `struct` object is on the heap, while another field is on the stack.
To avoid these issues, you should "canonicalize" your regions by using `MR->getBaseRegion()` (which would convert e.g. the region corresponding to `obj.field[5].subfield[2]` to the "base" region of `obj`). Obviously, you should perform this canonicalization both in this setter function and the corresponding getter.
https://github.com/llvm/llvm-project/pull/123003
More information about the cfe-commits
mailing list