@@ -48,40 +48,40 @@ QualType getOverflowBuiltinResultType(const CallEvent &Call, CheckerContext &C,
48
48
unsigned BI) {
49
49
assert (Call.getNumArgs () == 3 );
50
50
51
- ASTContext &Ast = C.getASTContext ();
51
+ ASTContext &ACtx = C.getASTContext ();
52
52
53
53
switch (BI) {
54
54
case Builtin::BI__builtin_smul_overflow:
55
55
case Builtin::BI__builtin_ssub_overflow:
56
56
case Builtin::BI__builtin_sadd_overflow:
57
- return Ast .IntTy ;
57
+ return ACtx .IntTy ;
58
58
case Builtin::BI__builtin_smull_overflow:
59
59
case Builtin::BI__builtin_ssubl_overflow:
60
60
case Builtin::BI__builtin_saddl_overflow:
61
- return Ast .LongTy ;
61
+ return ACtx .LongTy ;
62
62
case Builtin::BI__builtin_smulll_overflow:
63
63
case Builtin::BI__builtin_ssubll_overflow:
64
64
case Builtin::BI__builtin_saddll_overflow:
65
- return Ast .LongLongTy ;
65
+ return ACtx .LongLongTy ;
66
66
case Builtin::BI__builtin_umul_overflow:
67
67
case Builtin::BI__builtin_usub_overflow:
68
68
case Builtin::BI__builtin_uadd_overflow:
69
- return Ast .UnsignedIntTy ;
69
+ return ACtx .UnsignedIntTy ;
70
70
case Builtin::BI__builtin_umull_overflow:
71
71
case Builtin::BI__builtin_usubl_overflow:
72
72
case Builtin::BI__builtin_uaddl_overflow:
73
- return Ast .UnsignedLongTy ;
73
+ return ACtx .UnsignedLongTy ;
74
74
case Builtin::BI__builtin_umulll_overflow:
75
75
case Builtin::BI__builtin_usubll_overflow:
76
76
case Builtin::BI__builtin_uaddll_overflow:
77
- return Ast .UnsignedLongLongTy ;
77
+ return ACtx .UnsignedLongLongTy ;
78
78
case Builtin::BI__builtin_mul_overflow:
79
79
case Builtin::BI__builtin_sub_overflow:
80
80
case Builtin::BI__builtin_add_overflow:
81
81
return getOverflowBuiltinResultType (Call);
82
82
default :
83
83
assert (false && " Unknown overflow builtin" );
84
- return Ast .IntTy ;
84
+ return ACtx .IntTy ;
85
85
}
86
86
}
87
87
@@ -117,28 +117,21 @@ BuiltinFunctionChecker::checkOverflow(CheckerContext &C, SVal RetVal,
117
117
QualType Res) const {
118
118
ProgramStateRef State = C.getState ();
119
119
SValBuilder &SVB = C.getSValBuilder ();
120
- auto SvalToBool = [&](SVal val) {
121
- return State->isNonNull (val).isConstrainedTrue ();
122
- };
123
120
ASTContext &ACtx = C.getASTContext ();
124
121
125
122
assert (Res->isIntegerType ());
126
123
127
124
unsigned BitWidth = ACtx.getIntWidth (Res);
128
- SVal MinType = nonloc::ConcreteInt (
129
- llvm::APSInt::getMinValue (BitWidth, Res->isUnsignedIntegerType ()));
130
- SVal MaxType = nonloc::ConcreteInt (
131
- llvm::APSInt::getMaxValue (BitWidth, Res->isUnsignedIntegerType ()));
125
+ auto MinVal = llvm::APSInt::getMinValue (BitWidth, Res->isUnsignedIntegerType ());
126
+ auto MaxVal = llvm::APSInt::getMaxValue (BitWidth, Res->isUnsignedIntegerType ());
132
127
133
- bool IsGreaterMax =
134
- SvalToBool (SVB.evalBinOp (State, BO_GT, RetVal, MaxType, Res));
135
- bool IsLessMin =
136
- SvalToBool (SVB.evalBinOp (State, BO_LT, RetVal, MinType, Res));
128
+ SVal IsLeMax = SVB.evalBinOp (State, BO_LE, RetVal, nonloc::ConcreteInt (MaxVal), Res);
129
+ SVal IsGeMin = SVB.evalBinOp (State, BO_GE, RetVal, nonloc::ConcreteInt (MinVal), Res);
137
130
138
- bool IsLeMax = SvalToBool (SVB. evalBinOp (State, BO_LE, RetVal, MaxType, Res ));
139
- bool IsGeMin = SvalToBool (SVB. evalBinOp (State, BO_GE, RetVal, MinType, Res ));
131
+ auto [MayNotOverflow, MayOverflow] = State-> assume (IsLeMax. castAs <DefinedOrUnknownSVal>( ));
132
+ auto [MayNotUnderflow, MayUnderflow] = State-> assume (IsGeMin. castAs <DefinedOrUnknownSVal>( ));
140
133
141
- return {IsGreaterMax || IsLessMin, IsLeMax && IsGeMin };
134
+ return {MayOverflow || MayUnderflow, MayNotOverflow && MayNotUnderflow };
142
135
}
143
136
144
137
void BuiltinFunctionChecker::handleOverflowBuiltin (const CallEvent &Call,
0 commit comments