[clang] [Clang][Sema] Support 'counted_by' attribute on FAM/pointers in anonymous unions (PR #171996)

Oliver Hunt via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 9 13:30:40 PST 2026


================
@@ -222,3 +222,49 @@ struct on_void_ty {
   // expected-error at +1{{field has incomplete type 'void'}}
   void wrong_ty __counted_by_or_null(count);
 };
+
+//==============================================================================
+// __counted_by_or_null on pointer members in unions
+//==============================================================================
+
+// Pointer in anonymous union with count in parent struct - OK
+struct ptr_in_anon_union_count_in_parent {
+  int count;
+  union {
+    int a;
+    struct size_known *buf __counted_by_or_null(count);
+  };
+};
+
+// Pointer in named union - ERROR
+union ptr_in_named_union {
+  int count;
+  struct size_known *buf __counted_by_or_null(count); // expected-error {{'counted_by_or_null' cannot be applied to a union member}}
+};
+
+// Both pointer and count in same anonymous union - ERROR (they share storage)
+struct ptr_and_count_in_same_anon_union {
+  union {
+    int count;
+    struct size_known *buf __counted_by_or_null(count); // expected-error {{'counted_by_or_null' cannot be applied to a union member}}
+  };
+};
+
+// Count in anonymous union, pointer in parent struct - ERROR (count in union)
+struct count_in_anon_union_ptr_in_parent {
+  union {
+    int count;
+    int x;
+  };
+  struct size_known *buf __counted_by_or_null(count); // expected-error {{'counted_by_or_null' argument cannot refer to a union member}}
+};
+
+// Count in anonymous union, but hidden by struct - ERROR (count in union)
+struct count_in_deep_anon_union {
+  union {
+    struct {
+      int count;
+    };
+  };
+  struct size_known *buf __counted_by_or_null(count); // expected-error {{'counted_by_or_null' argument cannot refer to a union member}}
+};
----------------
ojhunt wrote:

The problem I have isn't specifically the intersecting storage, it's that it becomes possible to mutate the count without doing so observably - this applies to structs inside a union but I think we generally assume (for usability not an actual expectation that no one does this) that people are interacting with the struct type only.

e.g

```cpp
struct foo {
  union {
    int count;
    int somethingElse;
  };
  struct bar *buf __counted_by(count);
};

void funk() {
   foo f;
   f.count1 = 10;
   f.buf1 = calloc(10, sizeof(struct bar))
   f.somethingElse = 15; // We don't see that this has made an incorrect change to the reported size of buf
}
```



https://github.com/llvm/llvm-project/pull/171996


More information about the cfe-commits mailing list