;
34classCastValueChecker :
public Checker<check::DeadSymbols, eval::Call> {
35 enum classCallKind {
Function, Method, InstanceOf };
38std::function<void(
constCastValueChecker *,
const CallEvent&
Call,
61{{CDM::SimpleFunc, {
"llvm",
"cast"}, 1},
62{&CastValueChecker::evalCast, CallKind::Function}},
63{{CDM::SimpleFunc, {
"llvm",
"dyn_cast"}, 1},
64{&CastValueChecker::evalDynCast, CallKind::Function}},
65{{CDM::SimpleFunc, {
"llvm",
"cast_or_null"}, 1},
66{&CastValueChecker::evalCastOrNull, CallKind::Function}},
67{{CDM::SimpleFunc, {
"llvm",
"dyn_cast_or_null"}, 1},
68{&CastValueChecker::evalDynCastOrNull, CallKind::Function}},
69{{CDM::CXXMethod, {
"clang",
"castAs"}, 0},
70{&CastValueChecker::evalCastAs, CallKind::Method}},
71{{CDM::CXXMethod, {
"clang",
"getAs"}, 0},
72{&CastValueChecker::evalGetAs, CallKind::Method}},
73{{CDM::SimpleFunc, {
"llvm",
"isa"}, 1},
74{&CastValueChecker::evalIsa, CallKind::InstanceOf}},
75{{CDM::SimpleFunc, {
"llvm",
"isa_and_nonnull"}, 1},
76{&CastValueChecker::evalIsaAndNonNull, CallKind::InstanceOf}}};
102 returnCastSucceeds ? CastInfo->
fails() : CastInfo->
succeeds();
108 boolCastSucceeds,
boolIsKnownCast) {
109std::string CastToName =
112Object = Object->IgnoreParenImpCasts();
114 return C.getNoteTag(
115[=]() -> std::string {
117llvm::raw_svector_ostream Out(Msg);
122 if(
const auto*DRE = dyn_cast<DeclRefExpr>(Object)) {
123Out <<
'\''<< DRE->getDecl()->getDeclName() <<
'\'';
124}
else if(
const auto*ME = dyn_cast<MemberExpr>(Object)) {
125Out << (IsKnownCast ?
"Field '":
"field '")
126<< ME->getMemberDecl()->getDeclName() <<
'\'';
128Out << (IsKnownCast ?
"The object":
"the object");
131Out <<
' '<< (CastSucceeds ?
"is a":
"is not a") <<
" '"<< CastToName
134 returnstd::string(Out.str());
143Object = Object->IgnoreParenImpCasts();
145 return C.getNoteTag(
146[=]() -> std::string {
148llvm::raw_svector_ostream Out(Msg);
153 if(
const auto*DRE = dyn_cast<DeclRefExpr>(Object)) {
154Out <<
'\''<< DRE->getDecl()->getNameAsString() <<
'\'';
155}
else if(
const auto*ME = dyn_cast<MemberExpr>(Object)) {
156Out << (IsKnownCast ?
"Field '":
"field '")
157<< ME->getMemberDecl()->getNameAsString() <<
'\'';
159Out << (IsKnownCast ?
"The object":
"the object");
164 for(
QualTypeCastToTy: CastToTyVec) {
165std::string CastToName =
166CastToTy->getAsCXXRecordDecl()
167? CastToTy->getAsCXXRecordDecl()->getNameAsString()
168: CastToTy.getAsString();
169Out <<
' '<< ((CastToTyVec.size() == 1) ?
"not":
170(
First?
"neither":
"nor")) <<
" a '"<< CastToName
175 returnstd::string(Out.str());
195llvm_unreachable(
"Must align towards a reference type!");
200 boolIsNonNullReturn,
201 boolIsCheckedCast =
false) {
210 if(
Call.getNumArgs() > 0) {
211Object =
Call.getArgExpr(0);
212CastFromTy =
Call.parameters()[0]->getType();
214Object = cast<CXXInstanceCall>(&
Call)->getCXXThisExpr();
215CastFromTy = Object->getType();
232 boolCastSucceeds = IsCheckedCast || CastFromTy == CastToTy;
235CastSucceeds = IsNonNullReturn && CastInfo->
succeeds();
237CastSucceeds = IsNonNullReturn;
242 C.generateSink(State,
C.getPredecessor());
247 boolIsKnownCast = CastInfo || IsCheckedCast || CastFromTy == CastToTy;
248 if(!IsKnownCast || IsCheckedCast)
252 SVal V= CastSucceeds ?
C.getSValBuilder().evalCast(DV, CastToTy, CastFromTy)
253:
C.getSValBuilder().makeNullWithType(CastToTy);
255State->BindExpr(
Call.getOriginExpr(),
C.getLocationContext(),
V,
false),
256 getNoteTag(
C, CastInfo, CastToTy, Object, CastSucceeds, IsKnownCast));
270 switch(CastToTempArg.
getKind()) {
274CastToTyVec.push_back(CastToTempArg.
getAsType());
278CastToTyVec.push_back(ArgInPack.getAsType());
285MR = State->getSVal(DV.
castAs<
Loc>()).getAsRegion();
288 boolIsAnyKnown =
false;
289 for(
QualTypeCastToTy: CastToTyVec) {
291CastToTy =
C.getASTContext().getPointerType(CastToTy);
302CastSucceeds = IsInstanceOf && CastInfo->
succeeds();
304CastSucceeds = IsInstanceOf || CastFromTy == CastToTy;
307 boolIsKnownCast = CastInfo || CastFromTy == CastToTy;
308IsAnyKnown = IsAnyKnown || IsKnownCast;
317NewState->BindExpr(
Call.getOriginExpr(),
C.getLocationContext(),
318 C.getSValBuilder().makeTruthVal(
true)),
323}
else if(CastInfo && CastInfo->
succeeds()) {
324 C.generateSink(NewState,
C.getPredecessor());
331State->BindExpr(
Call.getOriginExpr(),
C.getLocationContext(),
332 C.getSValBuilder().makeTruthVal(
false)),
344 boolIsCheckedCast =
false) {
346 true, IsCheckedCast);
360 C.addTransition(State->BindExpr(
Call.getOriginExpr(),
361 C.getLocationContext(),
362 C.getSValBuilder().makeNullWithType(
363 Call.getOriginExpr()->getType()),
365 C.getNoteTag(
"Assuming null pointer is passed into cast",
381voidCastValueChecker::evalCastOrNull(
const CallEvent&
Call,
388voidCastValueChecker::evalDynCastOrNull(
const CallEvent&
Call,
403 boolIsCheckedCast =
false) {
405 true, IsCheckedCast);
434std::tie(NonNullState, NullState) =
C.getState()->assume(DV);
442 C.generateSink(NullState,
C.getPredecessor());
446voidCastValueChecker::evalIsaAndNonNull(
const CallEvent&
Call,
450std::tie(NonNullState, NullState) =
C.getState()->assume(DV);
468 const auto*Lookup =
CDM.lookup(
Call);
472 constCastCheck &Check = Lookup->first;
473CallKind
Kind= Lookup->second;
475std::optional<DefinedOrUnknownSVal> DV;
478 caseCallKind::Function: {
492 caseCallKind::InstanceOf: {
501 caseCallKind::Method:
502 const auto*InstanceCall = dyn_cast<CXXInstanceCall>(&
Call);
513Check(
this,
Call, *DV,
C);
517voidCastValueChecker::checkDeadSymbols(
SymbolReaper&SR,
526boolento::shouldRegisterCastValueChecker(
const CheckerManager&mgr) {
static bool isInfeasibleCast(const DynamicCastInfo *CastInfo, bool CastSucceeds)
static void addCastTransition(const CallEvent &Call, DefinedOrUnknownSVal DV, CheckerContext &C, bool IsNonNullParam, bool IsNonNullReturn, bool IsCheckedCast=false)
static const NoteTag * getNoteTag(CheckerContext &C, const DynamicCastInfo *CastInfo, QualType CastToTy, const Expr *Object, bool CastSucceeds, bool IsKnownCast)
static void evalNonNullParamNullReturn(const CallEvent &Call, DefinedOrUnknownSVal DV, CheckerContext &C)
static void addInstanceOfTransition(const CallEvent &Call, DefinedOrUnknownSVal DV, ProgramStateRef State, CheckerContext &C, bool IsInstanceOf)
static void evalZeroParamNonNullReturn(const CallEvent &Call, DefinedOrUnknownSVal DV, CheckerContext &C, bool IsCheckedCast=false)
static QualType alignReferenceTypes(QualType toAlign, QualType alignTowards, ASTContext &ACtx)
static void evalNullParamNullReturn(const CallEvent &Call, DefinedOrUnknownSVal DV, CheckerContext &C)
static void evalZeroParamNullReturn(const CallEvent &Call, DefinedOrUnknownSVal DV, CheckerContext &C)
static void evalNonNullParamNonNullReturn(const CallEvent &Call, DefinedOrUnknownSVal DV, CheckerContext &C, bool IsCheckedCast=false)
Defines the C++ template declaration subclasses.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
This represents one expression.
Represents a function declaration or definition.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
A (possibly-)qualified type.
void addConst()
Add the const type qualifier to this QualType.
bool isConstQualified() const
Determine whether this type is const-qualified.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
Represents a template argument.
QualType getAsType() const
Retrieve the type for a type template argument.
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
@ Pack
The template argument is actually a parameter pack.
@ Type
The template argument is a type.
ArgKind getKind() const
Return the kind of stored template argument.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isRValueReferenceType() const
bool isPointerType() const
bool isReferenceType() const
bool isLValueReferenceType() const
An immutable map from CallDescriptions to arbitrary data.
Represents an abstract call to a function or method along a particular path.
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
MemRegion - The root abstract class for all memory regions.
The tag upon which the TagVisitor reacts.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
const MemRegion * getAsRegion() const
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
A class responsible for cleaning up unused symbols.
const DynamicCastInfo * getDynamicCastInfo(ProgramStateRef State, const MemRegion *MR, QualType CastFromTy, QualType CastToTy)
Get dynamic cast information from CastFromTy to CastToTy of MR.
ProgramStateRef removeDeadCasts(ProgramStateRef State, SymbolReaper &SR)
Removes the dead cast informations from State.
ProgramStateRef setDynamicTypeAndCastInfo(ProgramStateRef State, const MemRegion *MR, QualType CastFromTy, QualType CastToTy, bool IsCastSucceeds)
Set dynamic type and cast information of the region; return the new state.
The JSON file list parser is used to communicate input to InstallAPI.
@ Success
Template argument deduction was successful.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4