r179081 - [analyzer] Replace isIntegerType() with isIntegerOrEnumerationType().
Jordan Rose
jordan_rose at apple.com
Mon Apr 8 19:30:34 PDT 2013
Author: jrose
Date: Mon Apr 8 21:30:33 2013
New Revision: 179081
URL: http://llvm.org/viewvc/llvm-project?rev=179081&view=rev
Log:
[analyzer] Replace isIntegerType() with isIntegerOrEnumerationType().
Previously, the analyzer used isIntegerType() everywhere, which uses the C
definition of "integer". The C++ predicate with the same behavior is
isIntegerOrUnscopedEnumerationType().
However, the analyzer is /really/ using this to ask if it's some sort of
"integrally representable" type, i.e. it should include C++11 scoped
enumerations as well. hasIntegerRepresentation() sounds like the right
predicate, but that includes vectors, which the analyzer represents by its
elements.
This commit audits all uses of isIntegerType() and replaces them with the
general isIntegerOrEnumerationType(), except in some specific cases where
it makes sense to exclude scoped enumerations, or any enumerations. These
cases now use isIntegerOrUnscopedEnumerationType() and getAs<BuiltinType>()
plus BuiltinType::isInteger().
isIntegerType() is hereby banned in the analyzer - lib/StaticAnalysis and
include/clang/StaticAnalysis. :-)
Fixes real assertion failures. PR15703 / <rdar://problem/12350701>
Added:
cfe/trunk/test/Analysis/enum.cpp
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp
cfe/trunk/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
cfe/trunk/lib/StaticAnalyzer/Core/SymbolManager.cpp
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h?rev=179081&r1=179080&r2=179081&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h Mon Apr 8 21:30:33 2013
@@ -93,7 +93,7 @@ public:
/// Returns the type of the APSInt used to store values of the given QualType.
APSIntType getAPSIntType(QualType T) const {
- assert(T->isIntegerType() || Loc::isLocType(T));
+ assert(T->isIntegralOrEnumerationType() || Loc::isLocType(T));
return APSIntType(Ctx.getTypeSize(T),
!T->isSignedIntegerOrEnumerationType());
}
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h?rev=179081&r1=179080&r2=179081&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h Mon Apr 8 21:30:33 2013
@@ -711,7 +711,8 @@ ProgramState::getSValAsScalarOrLoc(const
const LocationContext *LCtx) const {
if (const Expr *Ex = dyn_cast<Expr>(S)) {
QualType T = Ex->getType();
- if (Ex->isGLValue() || Loc::isLocType(T) || T->isIntegerType())
+ if (Ex->isGLValue() || Loc::isLocType(T) ||
+ T->isIntegralOrEnumerationType())
return getSVal(S, LCtx);
}
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h?rev=179081&r1=179080&r2=179081&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h Mon Apr 8 21:30:33 2013
@@ -78,7 +78,8 @@ public:
// FIXME: Remove the second disjunct when we support symbolic
// truncation/extension.
return (Context.getCanonicalType(Ty1) == Context.getCanonicalType(Ty2) ||
- (Ty1->isIntegerType() && Ty2->isIntegerType()));
+ (Ty1->isIntegralOrEnumerationType() &&
+ Ty2->isIntegralOrEnumerationType()));
}
SVal evalCast(SVal val, QualType castTy, QualType originalType);
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp?rev=179081&r1=179080&r2=179081&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp Mon Apr 8 21:30:33 2013
@@ -388,7 +388,7 @@ void CFNumberCreateChecker::checkPreStmt
// FIXME: If the pointee isn't an integer type, should we flag a warning?
// People can do weird stuff with pointers.
- if (!T->isIntegerType())
+ if (!T->isIntegralOrEnumerationType())
return;
uint64_t SourceSize = Ctx.getTypeSize(T);
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp?rev=179081&r1=179080&r2=179081&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp Mon Apr 8 21:30:33 2013
@@ -345,7 +345,7 @@ void WalkAST::checkCall_getpw(const Call
return;
// Verify the first argument type is integer.
- if (!FPT->getArgType(0)->isIntegerType())
+ if (!FPT->getArgType(0)->isIntegralOrUnscopedEnumerationType())
return;
// Verify the second argument type is char*.
@@ -602,7 +602,7 @@ void WalkAST::checkCall_rand(const CallE
if (!PT)
return;
- if (! PT->getPointeeType()->isIntegerType())
+ if (! PT->getPointeeType()->isIntegralOrUnscopedEnumerationType())
return;
}
else if (FTP->getNumArgs() != 0)
@@ -725,7 +725,7 @@ void WalkAST::checkUncheckedReturnValue(
// The arguments must be integers.
for (unsigned i = 0; i < FTP->getNumArgs(); i++)
- if (! FTP->getArgType(i)->isIntegerType())
+ if (! FTP->getArgType(i)->isIntegralOrUnscopedEnumerationType())
return;
// Issue a warning.
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp?rev=179081&r1=179080&r2=179081&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp Mon Apr 8 21:30:33 2013
@@ -188,7 +188,7 @@ public:
for (CallExpr::const_arg_iterator ai = i->AllocCall->arg_begin(),
ae = i->AllocCall->arg_end(); ai != ae; ++ai) {
- if (!(*ai)->getType()->isIntegerType())
+ if (!(*ai)->getType()->isIntegralOrUnscopedEnumerationType())
continue;
SizeofFinder SFinder;
Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp?rev=179081&r1=179080&r2=179081&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Mon Apr 8 21:30:33 2013
@@ -1351,7 +1351,7 @@ ConditionBRVisitor::VisitConditionVariab
Out << (tookTrue ? "not nil" : "nil");
else if (Ty->isBooleanType())
Out << (tookTrue ? "true" : "false");
- else if (Ty->isIntegerType())
+ else if (Ty->isIntegralOrEnumerationType())
Out << (tookTrue ? "non-zero" : "zero");
else
return 0;
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=179081&r1=179080&r2=179081&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Mon Apr 8 21:30:33 2013
@@ -106,7 +106,8 @@ ProgramStateRef ExprEngine::getInitialSt
const ParmVarDecl *PD = FD->getParamDecl(0);
QualType T = PD->getType();
- if (!T->isIntegerType())
+ const BuiltinType *BT = dyn_cast<BuiltinType>(T);
+ if (!BT || !BT->isInteger())
break;
const MemRegion *R = state->getRegion(PD, InitLoc);
@@ -1235,7 +1236,7 @@ static SVal RecoverCastedSymbol(ProgramS
while (const CastExpr *CE = dyn_cast<CastExpr>(Ex)) {
QualType T = CE->getType();
- if (!T->isIntegerType())
+ if (!T->isIntegralOrEnumerationType())
return UnknownVal();
uint64_t newBits = Ctx.getTypeSize(T);
@@ -1250,7 +1251,8 @@ static SVal RecoverCastedSymbol(ProgramS
// We reached a non-cast. Is it a symbolic value?
QualType T = Ex->getType();
- if (!bitsInit || !T->isIntegerType() || Ctx.getTypeSize(T) > bits)
+ if (!bitsInit || !T->isIntegralOrEnumerationType() ||
+ Ctx.getTypeSize(T) > bits)
return UnknownVal();
return state->getSVal(Ex, LCtx);
@@ -1342,7 +1344,7 @@ void ExprEngine::processBranch(const Stm
if (X.isUnknownOrUndef()) {
// Give it a chance to recover from unknown.
if (const Expr *Ex = dyn_cast<Expr>(Condition)) {
- if (Ex->getType()->isIntegerType()) {
+ if (Ex->getType()->isIntegralOrEnumerationType()) {
// Try to recover some path-sensitivity. Right now casts of symbolic
// integers that promote their values are currently not tracked well.
// If 'Condition' is such an expression, try and recover the
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp?rev=179081&r1=179080&r2=179081&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp Mon Apr 8 21:30:33 2013
@@ -68,12 +68,14 @@ void ExprEngine::VisitBinaryOperator(con
// SymSymExpr.
unsigned Count = currBldrCtx->blockCount();
if (LeftV.getAs<Loc>() &&
- RHS->getType()->isIntegerType() && RightV.isUnknown()) {
+ RHS->getType()->isIntegralOrEnumerationType() &&
+ RightV.isUnknown()) {
RightV = svalBuilder.conjureSymbolVal(RHS, LCtx, RHS->getType(),
Count);
}
if (RightV.getAs<Loc>() &&
- LHS->getType()->isIntegerType() && LeftV.isUnknown()) {
+ LHS->getType()->isIntegralOrEnumerationType() &&
+ LeftV.isUnknown()) {
LeftV = svalBuilder.conjureSymbolVal(LHS, LCtx, LHS->getType(),
Count);
}
@@ -662,8 +664,9 @@ VisitOffsetOfExpr(const OffsetOfExpr *OO
APSInt IV;
if (OOE->EvaluateAsInt(IV, getContext())) {
assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType()));
- assert(OOE->getType()->isIntegerType());
- assert(IV.isSigned() == OOE->getType()->isSignedIntegerOrEnumerationType());
+ assert(OOE->getType()->isBuiltinType());
+ assert(OOE->getType()->getAs<BuiltinType>()->isInteger());
+ assert(IV.isSigned() == OOE->getType()->isSignedIntegerType());
SVal X = svalBuilder.makeIntVal(IV);
B.generateNode(OOE, Pred,
Pred->getState()->BindExpr(OOE, Pred->getLocationContext(),
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp?rev=179081&r1=179080&r2=179081&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp Mon Apr 8 21:30:33 2013
@@ -270,7 +270,7 @@ SVal ProgramState::getSValAsScalarOrLoc(
if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
QualType T = TR->getValueType();
- if (Loc::isLocType(T) || T->isIntegerType())
+ if (Loc::isLocType(T) || T->isIntegralOrEnumerationType())
return getSVal(R);
}
Modified: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp?rev=179081&r1=179080&r2=179081&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp Mon Apr 8 21:30:33 2013
@@ -1907,7 +1907,7 @@ RegionStoreManager::setImplicitDefaultVa
if (Loc::isLocType(T))
V = svalBuilder.makeNull();
- else if (T->isIntegerType())
+ else if (T->isIntegralOrEnumerationType())
V = svalBuilder.makeZeroVal(T);
else if (T->isStructureOrClassType() || T->isArrayType()) {
// Set the default value to a zero constant when it is a structure
Modified: cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp?rev=179081&r1=179080&r2=179081&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp Mon Apr 8 21:30:33 2013
@@ -33,7 +33,7 @@ DefinedOrUnknownSVal SValBuilder::makeZe
if (Loc::isLocType(type))
return makeNull();
- if (type->isIntegerType())
+ if (type->isIntegralOrEnumerationType())
return makeIntVal(0, type);
// FIXME: Handle floats.
@@ -327,11 +327,11 @@ SVal SValBuilder::evalCast(SVal val, Qua
return val;
// Check for casts from pointers to integers.
- if (castTy->isIntegerType() && Loc::isLocType(originalTy))
+ if (castTy->isIntegralOrEnumerationType() && Loc::isLocType(originalTy))
return evalCastFromLoc(val.castAs<Loc>(), castTy);
// Check for casts from integers to pointers.
- if (Loc::isLocType(castTy) && originalTy->isIntegerType()) {
+ if (Loc::isLocType(castTy) && originalTy->isIntegralOrEnumerationType()) {
if (Optional<nonloc::LocAsInteger> LV = val.getAs<nonloc::LocAsInteger>()) {
if (const MemRegion *R = LV->getLoc().getAsRegion()) {
StoreManager &storeMgr = StateMgr.getStoreManager();
@@ -361,7 +361,7 @@ SVal SValBuilder::evalCast(SVal val, Qua
// Are we casting from an array to an integer? If so, cast the decayed
// pointer value to an integer.
- assert(castTy->isIntegerType());
+ assert(castTy->isIntegralOrEnumerationType());
// FIXME: Keep these here for now in case we decide soon that we
// need the original decayed type.
@@ -373,7 +373,7 @@ SVal SValBuilder::evalCast(SVal val, Qua
// Check for casts from a region to a specific type.
if (const MemRegion *R = val.getAsRegion()) {
// Handle other casts of locations to integers.
- if (castTy->isIntegerType())
+ if (castTy->isIntegralOrEnumerationType())
return evalCastFromLoc(loc::MemRegionVal(R), castTy);
// FIXME: We should handle the case where we strip off view layers to get
Modified: cfe/trunk/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp?rev=179081&r1=179080&r2=179081&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp Mon Apr 8 21:30:33 2013
@@ -137,7 +137,7 @@ SimpleConstraintManager::assumeAuxForSym
QualType T = Sym->getType();
// None of the constraint solvers currently support non-integer types.
- if (!T->isIntegerType())
+ if (!T->isIntegralOrEnumerationType())
return State;
const llvm::APSInt &zero = BVF.getValue(0, T);
Modified: cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp?rev=179081&r1=179080&r2=179081&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp Mon Apr 8 21:30:33 2013
@@ -109,7 +109,7 @@ SVal SimpleSValBuilder::evalCastFromNonL
// Only handle casts from integers to integers - if val is an integer constant
// being cast to a non integer type, produce unknown.
- if (!isLocType && !castTy->isIntegerType())
+ if (!isLocType && !castTy->isIntegralOrEnumerationType())
return UnknownVal();
llvm::APSInt i = val.castAs<nonloc::ConcreteInt>().getValue();
@@ -137,7 +137,7 @@ SVal SimpleSValBuilder::evalCastFromLoc(
if (castTy->isUnionType())
return UnknownVal();
- if (castTy->isIntegerType()) {
+ if (castTy->isIntegralOrEnumerationType()) {
unsigned BitWidth = Context.getTypeSize(castTy);
if (!val.getAs<loc::ConcreteInt>())
Modified: cfe/trunk/lib/StaticAnalyzer/Core/SymbolManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/SymbolManager.cpp?rev=179081&r1=179080&r2=179081&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/SymbolManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/SymbolManager.cpp Mon Apr 8 21:30:33 2013
@@ -340,8 +340,8 @@ bool SymbolManager::canSymbolicate(QualT
if (Loc::isLocType(T))
return true;
- if (T->isIntegerType())
- return T->isScalarType();
+ if (T->isIntegralOrEnumerationType())
+ return true;
if (T->isRecordType() && !T->isUnionType())
return true;
Added: cfe/trunk/test/Analysis/enum.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/enum.cpp?rev=179081&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/enum.cpp (added)
+++ cfe/trunk/test/Analysis/enum.cpp Mon Apr 8 21:30:33 2013
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=debug.ExprInspection %s
+
+void clang_analyzer_eval(bool);
+
+enum class Foo {
+ Zero
+};
+
+bool pr15703(int x) {
+ return Foo::Zero == (Foo)x; // don't crash
+}
+
+void testCasting(int i) {
+ Foo f = static_cast<Foo>(i);
+ int j = static_cast<int>(f);
+ if (i == 0)
+ {
+ clang_analyzer_eval(f == Foo::Zero); // expected-warning{{TRUE}}
+ clang_analyzer_eval(j == 0); // expected-warning{{TRUE}}
+ }
+ else
+ {
+ clang_analyzer_eval(f == Foo::Zero); // expected-warning{{FALSE}}
+ clang_analyzer_eval(j == 0); // expected-warning{{FALSE}}
+ }
+}
More information about the cfe-commits
mailing list