29 using namespace clang;
33 class DynamicTypeChecker :
public Checker<check::PostStmt<ImplicitCastExpr>> {
34 mutable std::unique_ptr<BugType> BT;
35 void initBugType()
const {
38 new BugType(
this,
"Dynamic and static type mismatch",
"Type Error"));
41 class DynamicTypeBugVisitor
44 DynamicTypeBugVisitor(
const MemRegion *Reg) : Reg(Reg) {}
46 void Profile(llvm::FoldingSetNodeID &
ID)
const override {
52 std::shared_ptr<PathDiagnosticPiece> VisitNode(
const ExplodedNode *N,
71 void DynamicTypeChecker::reportTypeError(
QualType DynamicType,
74 const Stmt *ReportedNode,
78 llvm::raw_svector_ostream OS(Buf);
79 OS <<
"Object has a dynamic type '";
82 OS <<
"' which is incompatible with static type '";
86 std::unique_ptr<BugReport> R(
88 R->markInteresting(Reg);
89 R->addVisitor(llvm::make_unique<DynamicTypeBugVisitor>(Reg));
94 std::shared_ptr<PathDiagnosticPiece>
95 DynamicTypeChecker::DynamicTypeBugVisitor::VisitNode(
const ExplodedNode *N,
107 if (TrackedTypePrev.
isValid() &&
119 llvm::raw_svector_ostream OS(Buf);
122 LangOpts, llvm::Twine());
123 OS <<
"' is inferred from ";
125 if (
const auto *ExplicitCast = dyn_cast<ExplicitCastExpr>(S)) {
126 OS <<
"explicit cast (from '";
131 LangOpts, llvm::Twine());
133 }
else if (
const auto *ImplicitCast = dyn_cast<ImplicitCastExpr>(S)) {
134 OS <<
"implicit cast (from '";
139 LangOpts, llvm::Twine());
142 OS <<
"this context";
148 return std::make_shared<PathDiagnosticEventPiece>(Pos, OS.str(),
true,
183 if (!DynObjCType || !StaticObjCType)
192 DynObjCType = DynObjCType->stripObjCKindOfTypeAndQuals(ASTCtxt);
206 reportTypeError(DynType, StaticType, Region, CE, C);
A (possibly-)qualified type.
MemRegion - The root abstract class for all memory regions.
ASTContext & getASTContext()
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Stmt - This represents one statement.
Decl - This represents one declaration (or definition), e.g.
const ProgramStateRef & getState() const
const T * getAs() const
Member-template getAs<specific type>'.
SVal getSVal(const Stmt *S) const
Get the value of arbitrary expressions at this point in the path.
The collection of all-type qualifiers we support.
bool isValid() const
Return false if no dynamic type info is available.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
This class provides a convenience implementation for clone() using the Curiously-Recurring Template P...
bool isSpecialized() const
Whether this type is specialized, meaning that it has type arguments.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
const ObjCObjectPointerType * stripObjCKindOfTypeAndQuals(const ASTContext &ctx) const
Strip off the Objective-C "kindof" type and (with it) any protocol qualifiers.
const LocationContext * getLocationContext() const
QualType getType() const
Returns the currently inferred upper bound on the runtime type.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Represents an ObjC class declaration.
bool canBeASubClass() const
Returns false if the type information is precise (the type T is the only type in the lattice)...
Stores the currently inferred strictest bound on the runtime type of a region in a given state along ...
static bool hasDefinition(const ObjCObjectPointerType *ObjPtr)
ExplodedNode * generateNonFatalErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
static const Stmt * getStmt(const ExplodedNode *N)
Given an exploded node, retrieve the statement that should be used for the diagnostic location...
CHECKER * registerChecker()
Used to register checkers.
CastKind getCastKind() const
const MemRegion * getAsRegion() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Dataflow Directional Tag Classes.
ASTContext & getASTContext()
DynamicTypeInfo getDynamicTypeInfo(ProgramStateRef State, const MemRegion *Reg)
Get dynamic type information for a region.
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
Represents a pointer to an Objective C object.
ObjCInterfaceDecl * getInterfaceDecl() const
If this pointer points to an Objective @interface type, gets the declaration for that interface...
const ProgramStateRef & getState() const
bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT)
canAssignObjCInterfaces - Return true if the two interface types are compatible for assignment from R...
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
This class provides an interface through which checkers can create individual bug reports...
const LangOptions & getLangOpts() const
SourceManager & getSourceManager()
const LangOptions & getLangOpts() const