[clang] [Clang] Generate the GEP instead of adding AST nodes (PR #73730)
Bill Wendling via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 7 12:22:50 PST 2023
================
@@ -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; }
----------------
bwendling wrote:
No, it'll return the Expr.
https://github.com/llvm/llvm-project/pull/73730
More information about the cfe-commits
mailing list