summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2019-08-23 03:24:04 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2019-08-23 03:24:04 +0000
commit85f7294e5af0cb7ea8e2d0469b96d0369627c48c (patch)
tree660d5bfec2c4faa55fa34797a9547b871dbb80ab /clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
parent62a76d0ae349f53d4ebd911412591ec1bb74f4e7 (diff)
downloadbcm5719-llvm-85f7294e5af0cb7ea8e2d0469b96d0369627c48c.tar.gz
bcm5719-llvm-85f7294e5af0cb7ea8e2d0469b96d0369627c48c.zip
[analyzer] CastValueChecker: Correctly model results of based-to-derived casts.
Our SVal hierarchy doesn't allow modeling pointer casts as no-op. The pointer type is instead encoded into the pointer object. Defer to our usual pointer casting facility, SValBuilder::evalBinOp(). Fixes a crash. llvm-svn: 369729
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp36
1 files changed, 27 insertions, 9 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
index a0cebd6ab85..cc1c9a66b90 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
@@ -138,6 +138,20 @@ static const NoteTag *getNoteTag(CheckerContext &C,
// Main logic to evaluate a cast.
//===----------------------------------------------------------------------===//
+static QualType alignReferenceTypes(QualType toAlign, QualType alignTowards,
+ ASTContext &ACtx) {
+ if (alignTowards->isLValueReferenceType() &&
+ alignTowards.isConstQualified()) {
+ toAlign.addConst();
+ return ACtx.getLValueReferenceType(toAlign);
+ } else if (alignTowards->isLValueReferenceType())
+ return ACtx.getLValueReferenceType(toAlign);
+ else if (alignTowards->isRValueReferenceType())
+ return ACtx.getRValueReferenceType(toAlign);
+
+ llvm_unreachable("Must align towards a reference type!");
+}
+
static void addCastTransition(const CallEvent &Call, DefinedOrUnknownSVal DV,
CheckerContext &C, bool IsNonNullParam,
bool IsNonNullReturn,
@@ -156,6 +170,15 @@ static void addCastTransition(const CallEvent &Call, DefinedOrUnknownSVal DV,
} else {
Object = cast<CXXInstanceCall>(&Call)->getCXXThisExpr();
CastFromTy = Object->getType();
+ if (CastToTy->isPointerType()) {
+ if (!CastFromTy->isPointerType())
+ return;
+ } else {
+ if (!CastFromTy->isReferenceType())
+ return;
+
+ CastFromTy = alignReferenceTypes(CastFromTy, CastToTy, C.getASTContext());
+ }
}
const MemRegion *MR = DV.getAsRegion();
@@ -183,7 +206,8 @@ static void addCastTransition(const CallEvent &Call, DefinedOrUnknownSVal DV,
State = setDynamicTypeAndCastInfo(State, MR, CastFromTy, CastToTy,
CastSucceeds);
- SVal V = CastSucceeds ? DV : C.getSValBuilder().makeNull();
+ SVal V = CastSucceeds ? C.getSValBuilder().evalCast(DV, CastToTy, CastFromTy)
+ : C.getSValBuilder().makeNull();
C.addTransition(
State->BindExpr(Call.getOriginExpr(), C.getLocationContext(), V, false),
getNoteTag(C, CastInfo, CastToTy, Object, CastSucceeds, IsKnownCast));
@@ -198,14 +222,8 @@ static void addInstanceOfTransition(const CallEvent &Call,
QualType CastToTy = FD->getTemplateSpecializationArgs()->get(0).getAsType();
if (CastFromTy->isPointerType())
CastToTy = C.getASTContext().getPointerType(CastToTy);
- else if (CastFromTy->isLValueReferenceType() &&
- CastFromTy.isConstQualified()) {
- CastToTy.addConst();
- CastToTy = C.getASTContext().getLValueReferenceType(CastToTy);
- } else if (CastFromTy->isLValueReferenceType())
- CastToTy = C.getASTContext().getLValueReferenceType(CastToTy);
- else if (CastFromTy->isRValueReferenceType())
- CastToTy = C.getASTContext().getRValueReferenceType(CastToTy);
+ else if (CastFromTy->isReferenceType())
+ CastToTy = alignReferenceTypes(CastToTy, CastFromTy, C.getASTContext());
else
return;
OpenPOWER on IntegriCloud