32class DynamicTypeChecker :
public Checker<check::PostStmt<ImplicitCastExpr>> {
33 mutable std::unique_ptr<BugType> BT;
34 void initBugType()
const {
37 new BugType(
this,
"Dynamic and static type mismatch",
"Type Error"));
42 DynamicTypeBugVisitor(
const MemRegion *Reg) : Reg(Reg) {}
44 void Profile(llvm::FoldingSetNodeID &ID)
const override {
71 const Stmt *ReportedNode,
75 llvm::raw_svector_ostream OS(Buf);
76 OS <<
"Object has a dynamic type '";
79 OS <<
"' which is incompatible with static type '";
83 auto R = std::make_unique<PathSensitiveBugReport>(
84 *BT, OS.str(),
C.generateNonFatalErrorNode());
85 R->markInteresting(Reg);
86 R->addVisitor(std::make_unique<DynamicTypeBugVisitor>(Reg));
88 C.emitReport(std::move(R));
101 if (TrackedTypePrev.
isValid() &&
113 llvm::raw_svector_ostream OS(Buf);
116 LangOpts, llvm::Twine());
117 OS <<
"' is inferred from ";
119 if (
const auto *ExplicitCast = dyn_cast<ExplicitCastExpr>(S)) {
120 OS <<
"explicit cast (from '";
125 LangOpts, llvm::Twine());
127 }
else if (
const auto *ImplicitCast = dyn_cast<ImplicitCastExpr>(S)) {
128 OS <<
"implicit cast (from '";
133 LangOpts, llvm::Twine());
136 OS <<
"this context";
142 return std::make_shared<PathDiagnosticEventPiece>(Pos, OS.str(),
true);
150 return Decl->getDefinition();
160 const MemRegion *Region =
C.getSVal(CE).getAsRegion();
176 if (!DynObjCType || !StaticObjCType)
185 DynObjCType = DynObjCType->stripObjCKindOfTypeAndQuals(ASTCtxt);
199 reportTypeError(DynType, StaticType, Region, CE,
C);
206bool ento::shouldRegisterDynamicTypeChecker(
const CheckerManager &mgr) {
static bool hasDefinition(const ObjCObjectPointerType *ObjPtr)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT)
canAssignObjCInterfaces - Return true if the two interface types are compatible for assignment from R...
const LangOptions & getLangOpts() const
CastKind getCastKind() const
Decl - This represents one declaration (or definition), e.g.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Represents an ObjC class declaration.
Represents a pointer to an Objective C object.
bool isSpecialized() const
Whether this type is specialized, meaning that it has type arguments.
const ObjCObjectPointerType * stripObjCKindOfTypeAndQuals(const ASTContext &ctx) const
Strip off the Objective-C "kindof" type and (with it) any protocol qualifiers.
ObjCInterfaceDecl * getInterfaceDecl() const
If this pointer points to an Objective @interface type, gets the declaration for that interface.
A (possibly-)qualified type.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
The collection of all-type qualifiers we support.
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
const T * getAs() const
Member-template getAs<specific type>'.
ASTContext & getASTContext() const
const SourceManager & getSourceManager() const
BugReporterVisitors are used to add custom diagnostics along a path.
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
Stores the currently inferred strictest bound on the runtime type of a region in a given state along ...
bool canBeASubClass() const
Returns false if the type information is precise (the type 'DynTy' is the only type in the lattice),...
QualType getType() const
Returns the currently inferred upper bound on the runtime type.
bool isValid() const
Returns true if the dynamic type info is available.
const ProgramStateRef & getState() const
const Stmt * getStmtForDiagnostics() const
If the node's program point corresponds to a statement, retrieve that statement.
const LocationContext * getLocationContext() const
ExplodedNode * getFirstPred()
MemRegion - The root abstract class for all memory regions.
DynamicTypeInfo getDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR)
Get dynamic type information for the region MR.
std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef