Safeguard
Developer Tools•

Clang's bounds safety extension: what it is and where it stands

The fbounds-safety proposal adds pointer bounds annotations to C so out-of-bounds access traps. What the annotations mean and what the docs say on status.

Safeguard Security Team
4 min read

The fbounds-safety extension is a proposed addition to C in Clang that attaches bounds to pointers so out-of-bounds accesses become deterministic traps instead of undefined behavior. The Clang page, when reviewed for this post, describes it as a design document not yet available to users, so check the current status before planning around it.

The idea

You annotate pointers with how many elements or bytes they cover. The compiler inserts bounds checks on dereference, and rejects code where it cannot verify the access at compile time or run time. Local pointer variables are implicitly wide pointers that carry their bounds, so they usually need no annotation.

The main annotations

  • counted_by(N). The pointer addresses N elements.
  • sized_by(N). The pointer addresses N bytes, useful for incomplete or sizeless types.
  • ended_by(P). The range ends at pointer P.
  • single. The pointer refers to a single object or null, so arithmetic on it is a compile time error.
  • null_terminated. For sentinel terminated data such as C strings.
  • unsafe_indexable. Behaves like a plain C pointer, as an escape for code outside the model.

The first group keeps the ABI unchanged. Wide pointer forms change layout and break ABI. The doc puts both approaches on the table, so decide early which interfaces must stay stable.

What it does not cover

The page says it handles bounds safety only. It does not guard other memory safety properties, and secondary problems such as type confusion can still slip through. It leans on run time checks, which can add code size in unoptimized builds, and some adoption mistakes only surface at run time.

Practical reading for a C team

Even without the compiler feature, the annotations teach a good habit: every pointer parameter should have an owner of its length. Many C code bases can record that today through a struct that carries pointer and length together, or through a span type in C++.

  1. Find the functions that take a pointer and a separate length.
  2. List callers where the two can disagree.
  3. Add tests with a sanitizer around those calls.
  4. When a compiler supports the extension, annotate the same functions first.

Why annotations beat comments

A C function that takes a pointer and a length relies on a convention nobody checks. A comment says the buffer holds count elements, but the compiler cannot see it. An annotation makes the relationship machine readable, so the compiler can check each access against it and flag a caller that passes a mismatched pair.

Annotating also forces design decisions that were implicit. Who owns the length, the caller or the callee? Can the pointer be null? Is the data terminated by a sentinel or sized by a count? Writing the answer down surfaces inconsistent assumptions between modules, which is where many overflows hide.

Planning for status changes

The status text on the Clang page may change after this review, so check it before committing. If the feature is not available in your compiler, you can still do the preparation work: list the pointer and length pairs, give each one a documented owner, and add a regression test for each boundary. That work pays off whichever tool you adopt.

Try it yourself

Click through it at your own pace, or open it full screen. Look at how a code scan points at the line behind a finding.

Quick check

Does it fix use after free?

No. It addresses out-of-bounds access only. Temporal bugs need other tools such as ownership rules, tagging or sanitizers.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.