================ @@ -1051,6 +1052,145 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type, return Builder.CreateSelect(Cmp, Res, ConstantInt::get(ResType, 0, IsSigned)); } +namespace { + +/// \p StructBaseExpr returns the base \p Expr with a structure or union type. +struct StructBaseExpr : public ConstStmtVisitor<StructBaseExpr, const Expr *> { + StructBaseExpr() = default; + + //===--------------------------------------------------------------------===// + // Visitor Methods + //===--------------------------------------------------------------------===// + + const Expr *VisitStmt(const Stmt *S) { return nullptr; } + + const Expr *Visit(const Expr *E) { + QualType Ty = E->getType(); + if (Ty->isStructureType() || Ty->isUnionType()) + return E; + + return ConstStmtVisitor<StructBaseExpr, const Expr *>::Visit(E); + } + + const Expr *VisitDeclRefExpr(const DeclRefExpr *E) { return E; } + + const Expr *VisitMemberExpr(const MemberExpr *E) { + return Visit(E->getBase()); + } + const Expr *VisitArraySubscriptExpr(const ArraySubscriptExpr *E) { + return Visit(E->getBase()); + } + const Expr *VisitCastExpr(const CastExpr *E) { + return Visit(E->getSubExpr()); + } + const Expr *VisitParenExpr(const ParenExpr *E) { + return Visit(E->getSubExpr()); + } + const Expr *VisitUnaryAddrOf(const clang::UnaryOperator *E) { + return Visit(E->getSubExpr()); + } + const Expr *VisitUnaryDeref(const clang::UnaryOperator *E) { + return Visit(E->getSubExpr()); + } ---------------- zygoloid wrote:
Looking through both casts and dereferences seems like it won't be correct: ``` struct A { int ***p; } a; int n = __builtin_dynamic_object_size(***a.p, 0); ``` ... looks like it'll base the result on the size of `A`, which is unrelated. I think you should be more conservative about the kinds of casts you'll walk through here: bitcasts and pointer casts seem potentially OK to step through, but things like lvalue-to-rvalue conversions will be problematic. But looking at what you're doing with this below, I think it might be possible to avoid doing this walk entirely. https://github.com/llvm/llvm-project/pull/80256 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits