[all-commits] [llvm/llvm-project] 564d69: [Clang][counted_by] Honor counted_by in __bdos on ...
Kees Cook via All-commits
all-commits at lists.llvm.org
Mon Jun 8 17:50:01 PDT 2026
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: 564d69a8dec3183ebd78a779efdd8903bbe89f68
https://github.com/llvm/llvm-project/commit/564d69a8dec3183ebd78a779efdd8903bbe89f68
Author: Kees Cook <kees at kernel.org>
Date: 2026-06-08 (Mon, 08 Jun 2026)
Changed paths:
M clang/include/clang/AST/Expr.h
M clang/lib/AST/ByteCode/InterpBuiltin.cpp
M clang/lib/AST/Expr.cpp
M clang/lib/AST/ExprConstant.cpp
M clang/lib/CodeGen/CGBuiltin.cpp
A clang/test/CodeGen/attr-counted-by-issue200014.c
Log Message:
-----------
[Clang][counted_by] Honor counted_by in __bdos on direct struct access (#201161)
__builtin_dynamic_object_size on a flexible array member must consult
the 'counted_by' attribute even when the containing struct is accessed
directly (a local or global variable) rather than through a pointer
dereference. The pointer-deref form (p->fam) already worked because the
constant evaluator could not determine the LValue for an opaque
parameter and fell through to the counted_by-aware runtime path in
CGBuiltin. The direct form (af.fam, gaf.fam) was being folded by
tryEvaluateBuiltinObjectSize to a layout-derived size (e.g. trailing
struct padding for locals, trailing initializer data for globals)
silently bypassing emitCountedBySize.
Make the AST constant evaluator refuse to fold __bdos on the same
operands that CGBuiltin's __bdos lowering classifies as a counted_by
FAM access. The check runs after the existing negative-offset early
return so that obviously out-of-bounds operands like &p->array[-42]
still fold to 0, preserving the behavior the sanitizer-bounds test in
attr-counted-by.c (test35) relies on.
Rather than duplicate the Expr-walking logic, promote CGBuiltin's
StructFieldAccess visitor into a shared function findStructFieldAccess
declared in clang/AST/Expr.h, with the visitor moved to an
anonymous-namespace implementation in Expr.cpp. Both CGBuiltin's
emitCountedBySize and the new ExprConstant check use it, so they
recognize
exactly the same set of expression shapes.
Note that the helper deliberately treats `&af.fam` (address-of-array)
as *not* a counted_by access. `&af.fam` designates the array object
as a whole and gets the layout-derived size, while `af.fam` (decayed)
and `&af.fam[idx]` designate element-pointers and get the count-based
size. This matches GCC 16's behavior.
The regression test covers the full {local, global, pointer-arg} x
{fam, &fam[idx], &fam} matrix (9 tests) with both -O0 and -O2 RUN
lines, autogenerated via update_cc_test_checks.py. -O0 checks the
frontend output directly: emitCountedBySize's counted_by.gep /
counted_by.load / flexible_array_member_size for the counted_by tests,
and the raw @llvm.objectsize.i64.p0 intrinsic call for the '&fam'
layout tests. -O2 pins down the post-optimization shape (smax(%n, 0)
for the runtime tests, ret i64 <constant> for the layout tests). All
nine tests match GCC 16's __bdos output.
Fixes: #200014
To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications
More information about the All-commits
mailing list