alexshap updated this revision to Diff 105524. alexshap added a comment. Add a test where evalCastFromLoc is called and the line unsigned BitWidth = Context.getIntWidth(castTy); is hit. I am planning to update this patch once again with a proper test where the path inside evalCastFromNonLoc is executed (need a bit more time)
Repository: rL LLVM https://reviews.llvm.org/D35041 Files: include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp test/Analysis/enum.cpp Index: test/Analysis/enum.cpp =================================================================== --- test/Analysis/enum.cpp +++ test/Analysis/enum.cpp @@ -37,3 +37,22 @@ } return true; } + +bool testNoCrashOnSwitchEnumBoolConstant() { + EnumBool E = EnumBool::F; + switch (E) { + case EnumBool::F: + return false; + } + return true; +} + +typedef __INTPTR_TYPE__ intptr_t; +bool testNoCrashOnSwitchEnumBoolConstantCastedFromPointer() { + EnumBool E = static_cast<EnumBool>((intptr_t)nullptr); + switch (E) { + case EnumBool::F: + return false; + } + return true; +} Index: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp =================================================================== --- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -71,18 +71,15 @@ } SVal SimpleSValBuilder::evalCastFromNonLoc(NonLoc val, QualType castTy) { - bool isLocType = Loc::isLocType(castTy); - if (val.getAs<nonloc::PointerToMember>()) return val; if (Optional<nonloc::LocAsInteger> LI = val.getAs<nonloc::LocAsInteger>()) { 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 @@ } if (castTy->isIntegralOrEnumerationType()) { - unsigned BitWidth = Context.getTypeSize(castTy); + unsigned BitWidth = Context.getIntWidth(castTy); if (!val.getAs<loc::ConcreteInt>()) return makeLocAsInteger(val, BitWidth); Index: include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h @@ -124,7 +124,7 @@ /// 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()); }
Index: test/Analysis/enum.cpp =================================================================== --- test/Analysis/enum.cpp +++ test/Analysis/enum.cpp @@ -37,3 +37,22 @@ } return true; } + +bool testNoCrashOnSwitchEnumBoolConstant() { + EnumBool E = EnumBool::F; + switch (E) { + case EnumBool::F: + return false; + } + return true; +} + +typedef __INTPTR_TYPE__ intptr_t; +bool testNoCrashOnSwitchEnumBoolConstantCastedFromPointer() { + EnumBool E = static_cast<EnumBool>((intptr_t)nullptr); + switch (E) { + case EnumBool::F: + return false; + } + return true; +} Index: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp =================================================================== --- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -71,18 +71,15 @@ } SVal SimpleSValBuilder::evalCastFromNonLoc(NonLoc val, QualType castTy) { - bool isLocType = Loc::isLocType(castTy); - if (val.getAs<nonloc::PointerToMember>()) return val; if (Optional<nonloc::LocAsInteger> LI = val.getAs<nonloc::LocAsInteger>()) { 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 @@ } if (castTy->isIntegralOrEnumerationType()) { - unsigned BitWidth = Context.getTypeSize(castTy); + unsigned BitWidth = Context.getIntWidth(castTy); if (!val.getAs<loc::ConcreteInt>()) return makeLocAsInteger(val, BitWidth); Index: include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h @@ -124,7 +124,7 @@ /// 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()); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits