[libc-commits] [libc] [libc] Make cpp::byte alias-safe (PR #194171)
Mikhail R. Gadelha via libc-commits
libc-commits at lists.llvm.org
Fri May 1 08:17:48 PDT 2026
mikhailramalho wrote:
Hey folks, indeed, [basic.lval]/11.3 names `std::byte` alongside `char`/`unsigned char`, and clang checks if the identifier is `byte` and that the enum is declared in the `std` namespace. in `clang/lib/AST/Type.cpp`, `Type::isStdByteType()`:
```
bool Type::isStdByteType() const {
if (const auto *ET = getAsCanonical<EnumType>()) {
const auto *ED = ET->getDecl();
IdentifierInfo *II = ED->getIdentifier();
if (II && II->isStr("byte") && ED->isInStdNamespace())
return true;
}
return false;
}
```
So I don't think we can assume `cpp::byte` will be treated like `std::byte`, from `clang/lib/CodeGen/CodeGenTBAA.cpp:227`:
```
// C++1z [basic.lval]p10: "If a program attempts to access the stored value of
// an object through a glvalue of other than one of the following types the
// behavior is undefined: [...] a char, unsigned char, or std::byte type."
if (Ty->isStdByteType())
return getChar();
```
I've updated the PR to `unsigned char` instead of `cpp::byte` in `ArrayGenericSize`, but maybe the solution is to stop using `cpp::byte` or make `cpp::byte` an alias for `unsigned char` (I know that's what the previous revision did, but given the TBAA situation, it may be worth revisiting).
It's worth mentioning that I think the same UB likely exists in:
- `lsearch.cpp` and `lfind.cpp` walk caller-supplied void* arrays via cpp::byte* exactly like qsort did
- Ptr/CPtr in memory_utils/utils.h are typedef'd as cpp::byte* and used by every inline mem* primitive to read and write arbitrary object representations
- block.h / freelist_heap.h cast Block* and user-allocated storage to cpp::byte* before doing pointer arithmetic and reads.
I don't have a failing test for them, but I believe they are UB as well.
WDYT?
https://github.com/llvm/llvm-project/pull/194171
More information about the libc-commits
mailing list