22using namespace ast_matchers;
25static constexpr const char *
const BaseNode =
"BaseNode";
26static constexpr const char *
const DerivedNode =
"DerivedNode";
27static constexpr const char *
const FromCastNode =
"FromCast";
28static constexpr const char *
const ToCastNode =
"ToCast";
29static constexpr const char *
const WarnRecordDecl =
"WarnRecordDecl";
31class MemoryUnsafeCastChecker :
public Checker<check::ASTCodeBody> {
32 BugType BT{
this,
"Unsafe cast",
"WebKit coding guidelines"};
42 const MemoryUnsafeCastChecker *
Checker,
47 assert(CE &&
Base && Derived);
49 std::string Diagnostics;
50 llvm::raw_string_ostream OS(Diagnostics);
51 OS <<
"Unsafe cast from base type '" <<
Base->getNameAsString()
52 <<
"' to derived type '" << Derived->getNameAsString() <<
"'";
55 auto Report = std::make_unique<BasicBugReport>(BT, OS.str(), BSLoc);
56 Report->addRange(CE->getSourceRange());
62 const MemoryUnsafeCastChecker *
Checker,
67 assert(CE && FromCast && ToCast);
69 std::string Diagnostics;
70 llvm::raw_string_ostream OS(Diagnostics);
71 OS <<
"Unsafe cast from type '" << FromCast->getNameAsString()
72 <<
"' to an unrelated type '" << ToCast->getNameAsString() <<
"'";
75 auto Report = std::make_unique<BasicBugReport>(BT, OS.str(), BSLoc);
76 Report->addRange(CE->getSourceRange());
81namespace ast_matchers {
83 return Builder->removeBindings([
this, &
Node](
const BoundNodesMap &
Nodes) {
84 const auto &BN =
Nodes.getNode(this->BindingID);
85 if (
const auto *ND = BN.get<
NamedDecl>()) {
86 return ND->getName() != Node.getString();
98void MemoryUnsafeCastChecker::checkASTCodeBody(
const Decl *
D,
105 auto MatchExprPtr =
allOf(
111 auto MatchExprPtrObjC =
allOf(
116 .bind(DerivedNode)))))));
117 auto MatchExprRefTypeDef =
118 allOf(hasSourceExpression(hasType(hasUnqualifiedDesugaredType(
recordType(
122 .bind(DerivedNode)))))),
128 .bind(WarnRecordDecl);
137 auto MatchExprPtrUnrelatedTypes =
allOf(
142 isSameOrDerivedFrom(equalsBoundNode(FromCastNode)))),
144 isSameOrDerivedFrom(equalsBoundNode(ToCastNode))))))));
145 auto MatchExprPtrObjCUnrelatedTypes =
allOf(
151 ignoringImpCasts(hasType(
153 isSameOrDerivedFrom(equalsBoundNode(FromCastNode)))))))),
154 hasSourceExpression(ignoringImpCasts(hasType(
156 isSameOrDerivedFrom(equalsBoundNode(ToCastNode))))))))))));
157 auto MatchExprRefTypeDefUnrelated =
allOf(
158 hasSourceExpression(hasType(hasUnqualifiedDesugaredType(
recordType(
160 hasType(hasUnqualifiedDesugaredType(
163 hasType(hasUnqualifiedDesugaredType(
165 isSameOrDerivedFrom(equalsBoundNode(FromCastNode)))))))),
166 hasSourceExpression(hasType(hasUnqualifiedDesugaredType(
168 isSameOrDerivedFrom(equalsBoundNode(ToCastNode))))))))))));
170 auto ExplicitCastUnrelated =
172 MatchExprPtrObjCUnrelatedTypes,
173 MatchExprRefTypeDefUnrelated))
174 .bind(WarnRecordDecl);
175 auto CastUnrelated =
stmt(ExplicitCastUnrelated);
178 for (
BoundNodes Match : MatchesUnrelatedTypes)
186bool ento::shouldRegisterMemoryUnsafeCastChecker(
const CheckerManager &mgr) {
BoundNodesTreeBuilder Nodes
#define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param)
AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... } defines a single-parameter function name...
static void emitDiagnostics(const BoundNodes &Nodes, BugReporter &BR, AnalysisDeclContext *ADC, const MemoryUnsafeCastChecker *Checker, const BugType &BT)
static decltype(auto) hasTypePointingTo(DeclarationMatcher DeclM)
static void emitDiagnosticsUnrelated(const BoundNodes &Nodes, BugReporter &BR, AnalysisDeclContext *ADC, const MemoryUnsafeCastChecker *Checker, const BugType &BT)
AnalysisDeclContext contains the context data for the function, method or block under analysis.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Decl - This represents one declaration (or definition), e.g.
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
This represents a decl that may have a name.
StringLiteral - This represents a string literal expression, e.g.
Maps string IDs to AST nodes matched by parts of a matcher.
ASTContext & getASTContext() override
AnalysisDeclContext * getAnalysisDeclContext(const Decl *D)
BugReporter is a utility class for generating PathDiagnostics for analysis.
const SourceManager & getSourceManager()
virtual void emitReport(std::unique_ptr< BugReport > R)
Add the given report to the set of reports tracked by BugReporter.
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
const AstTypeMatcher< ObjCObjectPointerType > objcObjectPointerType
Matches an Objective-C object pointer type, which is different from a pointer type,...
const internal::VariadicOperatorMatcherFunc< 1, 1 > unless
Matches if the provided matcher does not match.
internal::Matcher< Decl > DeclarationMatcher
Types of matchers for the top-level classes in the AST class hierarchy.
const internal::ArgumentAdaptingMatcherFunc< internal::HasDescendantMatcher > hasDescendant
Matches AST nodes that have descendant AST nodes that match the provided matcher.
const AstTypeMatcher< PointerType > pointerType
Matches pointer types, but does not match Objective-C object pointer types.
const internal::ArgumentAdaptingMatcherFunc< internal::ForEachDescendantMatcher > forEachDescendant
Matches AST nodes that have descendant AST nodes that match the provided matcher.
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
const internal::VariadicDynCastAllOfMatcher< Decl, TemplateTypeParmDecl > templateTypeParmDecl
Matches template type parameter declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, ExplicitCastExpr > explicitCastExpr
Matches explicit cast expressions.
const internal::VariadicDynCastAllOfMatcher< Decl, ObjCInterfaceDecl > objcInterfaceDecl
Matches Objective-C interface declarations.
const internal::VariadicOperatorMatcherFunc< 2, std::numeric_limits< unsigned >::max()> allOf
Matches if all given matchers match.
const AstTypeMatcher< RecordType > recordType
Matches record types (e.g.
const internal::VariadicDynCastAllOfMatcher< Decl, CXXRecordDecl > cxxRecordDecl
Matches C++ class declarations.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
internal::PolymorphicMatcher< internal::HasDeclarationMatcher, void(internal::HasDeclarationSupportedTypes), internal::Matcher< Decl > > hasDeclaration(const internal::Matcher< Decl > &InnerMatcher)
Matches a node if the declaration associated with that node matches the given matcher.
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
const internal::VariadicOperatorMatcherFunc< 2, std::numeric_limits< unsigned >::max()> anyOf
Matches if any of the given matchers matches.
const internal::VariadicDynCastAllOfMatcher< Stmt, CXXThisExpr > cxxThisExpr
Matches implicit and explicit this expressions.
bool Cast(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.