aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/MemRegion.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/MemRegion.cpp55
1 files changed, 35 insertions, 20 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
index 81c11099e93f..0c126a632f74 100644
--- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -35,7 +35,6 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
@@ -51,6 +50,7 @@
#include <cstdint>
#include <functional>
#include <iterator>
+#include <optional>
#include <string>
#include <tuple>
#include <utility>
@@ -790,18 +790,30 @@ DefinedOrUnknownSVal MemRegionManager::getStaticSize(const MemRegion *MR,
return true;
if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
+ using FAMKind = LangOptions::StrictFlexArraysLevelKind;
+ const FAMKind StrictFlexArraysLevel =
+ Ctx.getLangOpts().getStrictFlexArraysLevel();
+ const AnalyzerOptions &Opts = SVB.getAnalyzerOptions();
const llvm::APInt &Size = CAT->getSize();
- if (Size.isZero())
- return true;
-
- if (getContext().getLangOpts().StrictFlexArrays >= 2)
- return false;
- const AnalyzerOptions &Opts = SVB.getAnalyzerOptions();
- // FIXME: this option is probably redundant with -fstrict-flex-arrays=1.
- if (Opts.ShouldConsiderSingleElementArraysAsFlexibleArrayMembers &&
- Size.isOne())
+ if (StrictFlexArraysLevel <= FAMKind::ZeroOrIncomplete && Size.isZero())
return true;
+
+ // The "-fstrict-flex-arrays" should have precedence over
+ // consider-single-element-arrays-as-flexible-array-members
+ // analyzer-config when checking single element arrays.
+ if (StrictFlexArraysLevel == FAMKind::Default) {
+ // FIXME: After clang-17 released, we should remove this branch.
+ if (Opts.ShouldConsiderSingleElementArraysAsFlexibleArrayMembers &&
+ Size.isOne())
+ return true;
+ } else {
+ // -fstrict-flex-arrays was specified, since it's not the default, so
+ // ignore analyzer-config.
+ if (StrictFlexArraysLevel <= FAMKind::OneZeroOrIncomplete &&
+ Size.isOne())
+ return true;
+ }
}
return false;
};
@@ -1029,7 +1041,7 @@ const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
T = getContext().VoidTy;
if (!T->getAs<FunctionType>()) {
FunctionProtoType::ExtProtoInfo Ext;
- T = getContext().getFunctionType(T, None, Ext);
+ T = getContext().getFunctionType(T, std::nullopt, Ext);
}
T = getContext().getBlockPointerType(T);
@@ -1076,14 +1088,18 @@ MemRegionManager::getBlockDataRegion(const BlockCodeRegion *BC,
sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
}
else {
- if (LC) {
+ bool IsArcManagedBlock = Ctx.getLangOpts().ObjCAutoRefCount;
+
+ // ARC managed blocks can be initialized on stack or directly in heap
+ // depending on the implementations. So we initialize them with
+ // UnknownRegion.
+ if (!IsArcManagedBlock && LC) {
// FIXME: Once we implement scope handling, we want the parent region
// to be the scope.
const StackFrameContext *STC = LC->getStackFrame();
assert(STC);
sReg = getStackLocalsRegion(STC);
- }
- else {
+ } else {
// We allow 'LC' to be NULL for cases where want BlockDataRegions
// without context-sensitivity.
sReg = getUnknownRegion();
@@ -1286,8 +1302,8 @@ bool MemRegion::hasGlobalsOrParametersStorage() const {
return isa<StackArgumentsSpaceRegion, GlobalsSpaceRegion>(getMemorySpace());
}
-// getBaseRegion strips away all elements and fields, and get the base region
-// of them.
+// Strips away all elements and fields.
+// Returns the base region of them.
const MemRegion *MemRegion::getBaseRegion() const {
const MemRegion *R = this;
while (true) {
@@ -1307,8 +1323,7 @@ const MemRegion *MemRegion::getBaseRegion() const {
return R;
}
-// getgetMostDerivedObjectRegion gets the region of the root class of a C++
-// class hierarchy.
+// Returns the region of the root class of a C++ class hierarchy.
const MemRegion *MemRegion::getMostDerivedObjectRegion() const {
const MemRegion *R = this;
while (const auto *BR = dyn_cast<CXXBaseObjectRegion>(R))
@@ -1482,7 +1497,7 @@ static RegionOffset calculateOffset(const MemRegion *R) {
// If our base region is symbolic, we don't know what type it really is.
// Pretend the type of the symbol is the true dynamic type.
// (This will at least be self-consistent for the life of the symbol.)
- Ty = SR->getSymbol()->getType()->getPointeeType();
+ Ty = SR->getPointeeStaticType();
RootIsSymbolic = true;
}
@@ -1539,7 +1554,7 @@ static RegionOffset calculateOffset(const MemRegion *R) {
}
SVal Index = ER->getIndex();
- if (Optional<nonloc::ConcreteInt> CI =
+ if (std::optional<nonloc::ConcreteInt> CI =
Index.getAs<nonloc::ConcreteInt>()) {
// Don't bother calculating precise offsets if we already have a
// symbolic offset somewhere in the chain.