From f8c5c0d52f8d24f7376852bb7daae9f3c0bc77d1 Mon Sep 17 00:00:00 2001 From: Alexander Shaposhnikov Date: Tue, 11 Jul 2017 00:30:14 +0000 Subject: [PATCH] [analyzer] Start fixing modeling of bool based types This is a follow up for one of the previous diffs https://reviews.llvm.org/D32328. getTypeSize and with getIntWidth are not equivalent for bool (see https://clang.llvm.org/doxygen/ASTContext_8cpp_source.html#l08444), this causes a number of issues (for instance, if APint X representing a bool is created with the wrong bit width then X is not comparable against Min/Max (because of the different bit width), that results in crashes (triggered asserts) inside assume* methods), for examples see the newly added test cases. Test plan: make check-all Differential revision: https://reviews.llvm.org/D35041 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@307604 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Core/PathSensitive/BasicValueFactory.h | 2 +- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp | 7 ++--- test/Analysis/enum.cpp | 30 +++++++++++++++++++ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h index b8ec2aa6ae..4aa87443e4 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h @@ -124,7 +124,7 @@ public: /// Returns the type of the APSInt used to store values of the given QualType. APSIntType getAPSIntType(QualType T) const { assert(T->isIntegralOrEnumerationType() || Loc::isLocType(T)); - return APSIntType(Ctx.getTypeSize(T), + return APSIntType(Ctx.getIntWidth(T), !T->isSignedIntegerOrEnumerationType()); } diff --git a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index 9c28457b21..f09f9696f5 100644 --- a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -71,18 +71,15 @@ SVal SimpleSValBuilder::dispatchCast(SVal Val, QualType CastTy) { } SVal SimpleSValBuilder::evalCastFromNonLoc(NonLoc val, QualType castTy) { - bool isLocType = Loc::isLocType(castTy); - if (val.getAs()) return val; if (Optional LI = val.getAs()) { if (isLocType) return LI->getLoc(); - // FIXME: Correctly support promotions/truncations. - unsigned castSize = Context.getTypeSize(castTy); + unsigned castSize = Context.getIntWidth(castTy); if (castSize == LI->getNumBits()) return val; return makeLocAsInteger(LI->getLoc(), castSize); @@ -173,7 +170,7 @@ SVal SimpleSValBuilder::evalCastFromLoc(Loc val, QualType castTy) { } if (castTy->isIntegralOrEnumerationType()) { - unsigned BitWidth = Context.getTypeSize(castTy); + unsigned BitWidth = Context.getIntWidth(castTy); if (!val.getAs()) return makeLocAsInteger(val, BitWidth); diff --git a/test/Analysis/enum.cpp b/test/Analysis/enum.cpp index b561e65ac8..96408473ce 100644 --- a/test/Analysis/enum.cpp +++ b/test/Analysis/enum.cpp @@ -37,3 +37,33 @@ bool testNoCrashOnSwitchEnumBool(EnumBool E) { } return true; } + +bool testNoCrashOnSwitchEnumBoolConstant() { + EnumBool E = EnumBool::F; + switch (E) { + case EnumBool::F: + return false; + } + return true; +} + +typedef __INTPTR_TYPE__ intptr_t; +bool testNoCrashOnSwitchEnumBoolConstantCastedFromNullptr() { + EnumBool E = static_cast((intptr_t)nullptr); + switch (E) { + case EnumBool::F: + return false; + } + return true; +} + +bool testNoCrashOnSwitchEnumBoolConstantCastedFromPtr() { + int X; + intptr_t P = (intptr_t)&X; + EnumBool E = static_cast(P); + switch (E) { + case EnumBool::F: + return false; + } + return true; +} -- 2.50.1