================ @@ -994,31 +1010,55 @@ class MemberExprBaseVisitor // } Expr *Visit(Expr *E) { - return StmtVisitor<MemberExprBaseVisitor, Expr *>::Visit(E); + return StmtVisitor<StructAccessBase, Expr *>::Visit(E); } - Expr *VisitCastExpr(CastExpr *E) { - return IsExpectedRecordDecl(E) ? E : Visit(E->getSubExpr()); - } - Expr *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { - return IsExpectedRecordDecl(E) ? E : nullptr; - } + // These are the types we expect to return (in order of most to least + // likely): + // + // 1. DeclRefExpr - This is the expression for the base of the structure. + // It's exactly what we want to build an access to the \p counted_by + // field. + // 2. MemberExpr - This is the expression that has the same \p RecordDecl + // as the flexble array member's lexical enclosing \p RecordDecl. This + // allows us to catch things like: "p->p->array" + // 3. CompoundLiteralExpr - This is for people who create something + // heretical like (struct foo has a flexible array member): + // + // (struct foo){ 1, 2 }.blah[idx]; Expr *VisitDeclRefExpr(DeclRefExpr *E) { return IsExpectedRecordDecl(E) ? E : nullptr; } Expr *VisitMemberExpr(MemberExpr *E) { + if (IsExpectedRecordDecl(E) && E->isArrow()) + return E; Expr *Res = Visit(E->getBase()); return !Res && IsExpectedRecordDecl(E) ? E : Res; } - Expr *VisitParenExpr(ParenExpr *E) { - return IsExpectedRecordDecl(E) ? E : Visit(E->getSubExpr()); + Expr *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { + return IsExpectedRecordDecl(E) ? E : nullptr; } + // "Pass This On" --The Knife Expr *VisitArraySubscriptExpr(ArraySubscriptExpr *E) { + if (IsExpectedRecordDecl(E)) + return E; return Visit(E->getBase()); } - Expr *VisitImplicitCastExpr(CastExpr *E) { return Visit(E->getSubExpr()); } - Expr *VisitUnaryOperator(UnaryOperator *E) { return Visit(E->getSubExpr()); } + Expr *VisitCastExpr(CastExpr *E) { return Visit(E->getSubExpr()); } + Expr *VisitImplicitCastExpr(ImplicitCastExpr *E) { + return Visit(E->getSubExpr()); + } + Expr *VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } + Expr *VisitUnaryAddrOf(UnaryOperator *E) { return Visit(E->getSubExpr()); } + Expr *VisitUnaryDeref(UnaryOperator *E) { return Visit(E->getSubExpr()); } + + // Invalid operations. Pointer arithmetic may lead to security violations. + Expr *VisitBinaryOperator(BinaryOperator *E) { return nullptr; } + Expr *VisitUnaryPostDec(UnaryOperator *E) { return nullptr; } + Expr *VisitUnaryPostInc(UnaryOperator *E) { return nullptr; } + Expr *VisitUnaryPreDec(UnaryOperator *E) { return nullptr; } + Expr *VisitUnaryPreInc(UnaryOperator *E) { return nullptr; } ---------------- efriedma-quic wrote:
Can we add a VisitStmt or whatever it's called to change that? https://github.com/llvm/llvm-project/pull/73730 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits