summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/StaticAnalyzer/Core/Store.cpp26
1 files changed, 20 insertions, 6 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/Store.cpp b/clang/lib/StaticAnalyzer/Core/Store.cpp
index 794fd843647..ac9cb4bc425 100644
--- a/clang/lib/StaticAnalyzer/Core/Store.cpp
+++ b/clang/lib/StaticAnalyzer/Core/Store.cpp
@@ -394,14 +394,28 @@ SVal StoreManager::attemptDownCast(SVal Base, QualType TargetType,
return UnknownVal();
}
+static bool isScalarEnoughToAttemptACast(QualType T) {
+ return T->isIntegralOrEnumerationType() || T->isAnyPointerType() ||
+ T->isReferenceType();
+}
+
/// CastRetrievedVal - Used by subclasses of StoreManager to implement
/// implicit casts that arise from loads from regions that are reinterpreted
/// as another region.
SVal StoreManager::CastRetrievedVal(SVal V, const TypedValueRegion *R,
- QualType castTy) {
- if (castTy.isNull() || V.isUnknownOrUndef())
+ QualType CastTy) {
+ if (CastTy.isNull() || V.isUnknownOrUndef())
return V;
+ QualType OrigTy = R->getValueType();
+
+ if (!isScalarEnoughToAttemptACast(OrigTy) ||
+ !isScalarEnoughToAttemptACast(CastTy)) {
+ if (OrigTy.getUnqualifiedType() == CastTy.getUnqualifiedType())
+ return V;
+ return UnknownVal();
+ }
+
// When retrieving symbolic pointer and expecting a non-void pointer,
// wrap them into element regions of the expected type if necessary.
// SValBuilder::dispatchCast() doesn't do that, but it is necessary to
@@ -410,13 +424,13 @@ SVal StoreManager::CastRetrievedVal(SVal V, const TypedValueRegion *R,
// We might need to do that for non-void pointers as well.
// FIXME: We really need a single good function to perform casts for us
// correctly every time we need it.
- if (castTy->isPointerType() && !castTy->isVoidPointerType())
+ if (CastTy->isPointerType() && !CastTy->isVoidPointerType())
if (const auto *SR = dyn_cast_or_null<SymbolicRegion>(V.getAsRegion()))
if (SR->getSymbol()->getType().getCanonicalType() !=
- castTy.getCanonicalType())
- return loc::MemRegionVal(castRegion(SR, castTy));
+ CastTy.getCanonicalType())
+ return loc::MemRegionVal(castRegion(SR, CastTy));
- return svalBuilder.dispatchCast(V, castTy);
+ return svalBuilder.dispatchCast(V, CastTy);
}
SVal StoreManager::getLValueFieldOrIvar(const Decl *D, SVal Base) {
OpenPOWER on IntegriCloud