22 using namespace clang;
28 const CheckerBase *Checker;
32 explicit CastToStructVisitor(BugReporter &B,
const CheckerBase *Checker,
34 : BR(B), Checker(Checker), AC(A) {}
35 bool VisitCastExpr(
const CastExpr *CE);
39 bool CastToStructVisitor::VisitCastExpr(
const CastExpr *CE) {
48 if (!ToPTy || !OrigPTy)
64 PathDiagnosticLocation Loc(CE, BR.getSourceManager(), AC);
66 AC->getDecl(), Checker,
"Cast from non-struct type to struct type",
68 "type and accessing a field can lead to memory "
69 "access errors or data corruption.",
73 const auto *
U = dyn_cast<UnaryOperator>(E);
74 if (!
U ||
U->getOpcode() != UO_AddrOf)
79 if (
const auto *SE = dyn_cast<DeclRefExpr>(
U->getSubExpr()))
81 else if (
const auto *SE = dyn_cast<MemberExpr>(
U->getSubExpr()))
82 VD = SE->getMemberDecl();
93 if (ToWidth <= OrigWidth)
96 PathDiagnosticLocation Loc(CE, BR.getSourceManager(), AC);
97 BR.EmitBasicReport(AC->getDecl(), Checker,
"Widening cast to struct type",
99 "Casting data to a larger structure type and accessing "
100 "a field can lead to memory access errors or data "
109 class CastToStructChecker :
public Checker<check::ASTCodeBody> {
111 void checkASTCodeBody(
const Decl *D, AnalysisManager &Mgr,
112 BugReporter &BR)
const {
113 CastToStructVisitor Visitor(BR,
this, Mgr.getAnalysisDeclContext(D));
114 Visitor.TraverseDecl(
const_cast<Decl *
>(D));
119 void ento::registerCastToStructChecker(CheckerManager &mgr) {
120 mgr.registerChecker<CastToStructChecker>();
123 bool ento::shouldRegisterCastToStructChecker(
const CheckerManager &mgr) {