[clang] [llvm] [Clang] Correct __builtin_dynamic_object_size for subobject types (PR #83204)
Bill Wendling via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 11 14:04:41 PDT 2024
================
@@ -1052,11 +1053,143 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type,
return Builder.CreateSelect(Cmp, Res, ConstantInt::get(ResType, 0, IsSigned));
}
+namespace {
+
+/// SubobjectFinder - A simple visitor to find the "sub-object" pointed to by a
+/// __builtin_dynamic_object_size call. Information gathered from the
+/// sub-object is used by the back-end to determine the correct size when the
+/// 'TYPE' of the __bdos call has the least significant bit set (i.e. asking
+/// for the sub-object size).
+///
+/// The expectation is that we'll eventually hit one of three expression types:
+///
+/// 1. DeclRefExpr - This is the expression for the base of the structure.
+/// 2. MemberExpr - This is the field in the structure.
+/// 3. CompoundLiteralExpr - This is for people who create something
+/// heretical like (struct foo has a flexible array member):
+///
+/// (struct foo){ 1, 2 }.blah[idx];
+///
+/// All other expressions can be correctly handled with the current code.
+struct SubobjectFinder
+ : public ConstStmtVisitor<SubobjectFinder, const Expr *> {
+ SubobjectFinder() = default;
+
+ //===--------------------------------------------------------------------===//
+ // Visitor Methods
+ //===--------------------------------------------------------------------===//
+
+ const Expr *VisitStmt(const Stmt *S) { return nullptr; }
+
+ const Expr *VisitDeclRefExpr(const DeclRefExpr *E) { return E; }
+ const Expr *VisitMemberExpr(const MemberExpr *E) { return E; }
+ const Expr *VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
+ return E;
+ }
+
+ const Expr *VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
+ return Visit(E->getBase());
+ }
+ const Expr *VisitCastExpr(const CastExpr *E) {
----------------
bwendling wrote:
It seems to. See https://godbolt.org/z/4xaY4191o for an example (the `&((char *)&var.z.a)[argc]` example looks through them.
https://github.com/llvm/llvm-project/pull/83204
More information about the cfe-commits
mailing list