68 Commits

Author SHA1 Message Date
Timm Baeder
36cb9894b3
[clang][bytecode] Only reject function types in Pointer::toRValue() (#180722)
No test because I'm not sure how to reproduce this, but this patch fixes
`CodeGen/ptrauth-qualifier-function.c`.

For function pointer types and function reference types, we use
`Pointer`s these days, so we _can_ return them.
2026-02-10 13:11:45 +01:00
Timm Baeder
3230de5e65
[clang][bytecode] Fix assertion failure when returning function type (#180681)
... as an rvalue. Which can't work, so reject.
2026-02-10 10:54:45 +01:00
Timm Baeder
87e38d3b97
[clang][bytecode][NFC] Add Pointer::canDeref (#179618) 2026-02-04 09:18:23 +01:00
puneeth_aditya_5656
85c5029917
[clang][bytecode] Fix crash when dereferencing cast to larger type (#179030)
## Summary
When dereferencing a pointer that was `reinterpret_cast` to a larger
type (e.g. `*(int**)""`), the bytecode interpreter would crash with an
assertion failure because it tried to read more bytes than the
allocation contained.

## Changes
- Add a size check in `Pointer::toRValue()` before calling `deref<T>()`
to ensure the allocation is large enough
- If the allocation is too small, return `std::nullopt` to gracefully
fail the constant evaluation instead of crashing
- Add regression test

Fixes #179015
2026-02-04 07:48:18 +01:00
Timm Baeder
cf19b6cdf0
[clang][bytecode] Relax assertions in Pointer::{begin,end}Lifetime (#177906)
We could get here for array roots, for which the assertion doesn't
necessarily hold.
2026-01-26 14:12:10 +01:00
Timm Baeder
ab366170db
[clang][bytecode] Add lifetime information for primitive array elements (#173333)
Double the allocated size of the `InitMap` and use the second half for
lifetime information.
2026-01-21 09:41:35 +01:00
Timm Baeder
ff94a19f5c
[clang][bytecode] Fix APValues for arrays in dynamic allocations (#175176)
getType() returns just int for those instead of an array type, so the
previous condition resulted in the array index missing in the APValue's
LValuePath.
2026-01-09 16:37:48 +01:00
Timm Baeder
e16860be5e
[clang][bytecode] Remove unnecessary null check (#174368)
A null Pointee shouldn't happen anymore.
2026-01-05 10:48:27 +01:00
Timm Baeder
4ecca392d2
[clang][bytecode] Use record layout in Pointer::computeOffsetForComparison() (#172322)
Our internal representation for records does not include things like
alignment of the fields or padding bits, so we can't only rely on those
values, not even for just comparing two pointers.

Try to look up the offsets from the `ASTRecordLayout` instead.

Fixes https://github.com/llvm/llvm-project/issues/172165

---------

Co-authored-by: Shafik Yaghmour <shafik.yaghmour@intel.com>
2025-12-24 08:16:01 +01:00
Timm Baeder
2093d2eea1
[clang][bytecode] Refactor InitMapPtr (#172665)
As mentioned a few times in the past, the previous handling using a
`optional<pair<bool, std::shared_ptr<>>>` was confusing and nobody ever
remembered what the optional being unset meant or what the bool stood
for.

Add an `InitMapPtr` struct that wraps a `uintptr_t` that either holds a
pointer to a valid `InitMap` instance _or_ one of two special values.
The struct has meaningful accessors for the various special cases that
were confusing before.
2025-12-18 10:16:55 +01:00
Timm Baeder
db557bee1e
[clang][bytecode][NFC] Add Block::getBlockDesc<T>() (#172218)
Which returns the block-level descriptor. This way we don't have to do
the reinterpret_cast dance everywhere.
2025-12-15 09:21:41 +01:00
Timm Bäder
773a6a9cc8 Revert "[clang][bytecode] Allocate InitMaps via Program/InterpState allocators (#170272)"
This reverts commit 8fe38c4c9c71c7a86ecdba476ee5bae4c02c0dfe.

This breaks the clang-armv7-2stage build bot:
https://lab.llvm.org/buildbot/#/builders/79/builds/2531
2025-12-09 06:19:09 +01:00
Timm Baeder
8fe38c4c9c
[clang][bytecode] Allocate InitMaps via Program/InterpState allocators (#170272)
Save them as a pointer intead of using a shared_ptr. This we we can use
the pointer integer value to differentiate the "no initmap yet" and "all
values initialzed" cases.

This regresses one test case in const-eval.c, but as it turns out, that
only worked coincidentally before.
2025-12-06 06:37:45 +01:00
Timm Baeder
bd95a74a2c
[clang][bytecode] Check for invalid record decls in IntPointer::atOffset (#169786)
We can't access the RecordLayout of an invalid decl, so return failure
if that happens.

Fixes https://github.com/llvm/llvm-project/issues/167076
2025-11-27 13:06:15 +01:00
Timm Baeder
dc3ae608e9
[clang][bytecode] Adjust pointers when moving them (#168053)
When calling Block::movePointersTo(), the two blocks might have
different metadata sizes, which causes the final pointer to be incorrect
and point to garbage. Adjust the pointer base and offset accordingly.

Fixes https://github.com/llvm/llvm-project/issues/168018
2025-11-14 15:30:07 +01:00
Matheus Izvekov
b516dcc998
[clang] NFC: rename TagType::getOriginalDecl back to getDecl (#163271)
This rename was made as part of
https://github.com/llvm/llvm-project/pull/147835 in order to ease
rebasing the PR, and give a nice window for other patches to get rebased
as well.

It has been a while already, so lets go ahead and rename it back.
2025-10-15 16:11:17 -03:00
Timm Baeder
23473247c2
[clang][bytecode][NFC] Use switches for pointer type distinction (#160879)
In the important places. They are all fully covered switch statements so
we know where to add code when adding a new pointer type.
2025-09-26 16:59:16 +02:00
Timm Baeder
2155f17d39
[clang][bytecode] Optimize InitElem{,Pop} (#159084)
Try harder to avoid creating a new `Pointer` for the element.
2025-09-17 09:27:07 +02:00
Eli Friedman
c62284c43d
[clang] Followup for constexpr-unknown potential constant expressions. (#151053)
6a60f18997d62b0e2842a921fcb6beb3e52ed823 fixed the primary issue of
dereferences, but there are some expressions that depend on the identity
of the pointed-to object without actually accessing it. Handle those
cases.

Also, while I'm here, fix a crash in interpreter mode comparing typeid
to nullptr.
2025-09-02 12:20:13 -07:00
Timm Baeder
839916c8c9
[clang][bytecode] Speed up EvaluationResult::CheckArrayInitialized() (#155756)
For large primitive arrays, avoid creating a new `Pointer` for every
element (via `Pointer::isElementInitialized()`) or avoid iterating over
the array altogether (via `Pointer::allElementsInitialized()`).
2025-08-28 09:14:22 +02:00
Matheus Izvekov
88438ba1f3
[clang] AST: fix getAs canonicalization of leaf types (#155028) 2025-08-27 06:20:14 -03:00
Timm Baeder
fadd87ed9f
[clang][bytecode] Check that a ltor cast to a complex value is possible (#155152)
When we get to this point, the pointer might _not_ be backed by a
primitive array, so the later code will fail.

Fixes #155144
2025-08-26 05:38:25 +02:00
Timm Baeder
a23f737d37
[clang][bytecode][NFC] Move local into closest scope (#154969) 2025-08-22 17:52:39 +02:00
Timm Baeder
e16ced3ef4
[clang][bytecode] Diagnose one-past-end reads from global arrays (#154484)
Fixes #154312
2025-08-20 10:34:44 +02:00
Timm Baeder
a9de444aa1
[clang][bytecode][NFC] Use an anonymous union in Pointer (#154405)
So we can save ourselves writing PointeeStorage all the time.
2025-08-20 09:23:19 +02:00
Timm Baeder
32ba045bea
[clang][bytecode] Fix comparing pointers to union members (#154342)
If one of them is a one-past-end pointer.
2025-08-20 07:09:20 +02:00
Timm Baeder
25c137e43b
[clang][bytecode] Save a per-block dynamic allocation ID (#154094)
This fixes an old todo item about wrong allocation counting and some
diagnostic differences.
2025-08-19 06:52:21 +02:00
Matheus Izvekov
91cdd35008
[clang] Improve nested name specifier AST representation (#147835)
This is a major change on how we represent nested name qualifications in
the AST.

* The nested name specifier itself and how it's stored is changed. The
prefixes for types are handled within the type hierarchy, which makes
canonicalization for them super cheap, no memory allocation required.
Also translating a type into nested name specifier form becomes a no-op.
An identifier is stored as a DependentNameType. The nested name
specifier gains a lightweight handle class, to be used instead of
passing around pointers, which is similar to what is implemented for
TemplateName. There is still one free bit available, and this handle can
be used within a PointerUnion and PointerIntPair, which should keep
bit-packing aficionados happy.
* The ElaboratedType node is removed, all type nodes in which it could
previously apply to can now store the elaborated keyword and name
qualifier, tail allocating when present.
* TagTypes can now point to the exact declaration found when producing
these, as opposed to the previous situation of there only existing one
TagType per entity. This increases the amount of type sugar retained,
and can have several applications, for example in tracking module
ownership, and other tools which care about source file origins, such as
IWYU. These TagTypes are lazily allocated, in order to limit the
increase in AST size.

This patch offers a great performance benefit.

It greatly improves compilation time for
[stdexec](https://github.com/NVIDIA/stdexec). For one datapoint, for
`test_on2.cpp` in that project, which is the slowest compiling test,
this patch improves `-c` compilation time by about 7.2%, with the
`-fsyntax-only` improvement being at ~12%.

This has great results on compile-time-tracker as well:

![image](https://github.com/user-attachments/assets/700dce98-2cab-4aa8-97d1-b038c0bee831)

This patch also further enables other optimziations in the future, and
will reduce the performance impact of template specialization resugaring
when that lands.

It has some other miscelaneous drive-by fixes.

About the review: Yes the patch is huge, sorry about that. Part of the
reason is that I started by the nested name specifier part, before the
ElaboratedType part, but that had a huge performance downside, as
ElaboratedType is a big performance hog. I didn't have the steam to go
back and change the patch after the fact.

There is also a lot of internal API changes, and it made sense to remove
ElaboratedType in one go, versus removing it from one type at a time, as
that would present much more churn to the users. Also, the nested name
specifier having a different API avoids missing changes related to how
prefixes work now, which could make existing code compile but not work.

How to review: The important changes are all in
`clang/include/clang/AST` and `clang/lib/AST`, with also important
changes in `clang/lib/Sema/TreeTransform.h`.

The rest and bulk of the changes are mostly consequences of the changes
in API.

PS: TagType::getDecl is renamed to `getOriginalDecl` in this patch, just
for easier to rebasing. I plan to rename it back after this lands.

Fixes #136624
Fixes https://github.com/llvm/llvm-project/issues/43179
Fixes https://github.com/llvm/llvm-project/issues/68670
Fixes https://github.com/llvm/llvm-project/issues/92757
2025-08-09 05:06:53 -03:00
Timm Baeder
fb49c6784a
[clang][bytecode] Move Pointer::{Prev,Next} into BlockPointer (#151097)
They are only relevant for block pointers.
2025-07-30 10:17:21 +02:00
Timm Baeder
4a44a85c89
[clang][bytecode] Add Pointer::initializeAllElements() (#151151)
To initialize all elements of a primitive array at once. This saves us
from creating the InitMap just to destroy it again after all elements
have been initialized.
2025-07-29 19:30:01 +02:00
Timm Baeder
904de95e71
[clang][bytecode][NFC] Fix a few clang-tidy complaints (#150940) 2025-07-28 15:57:49 +02:00
Timm Baeder
e39ee62c5b
[clang][bytecode] Use OptPrimType instead of std::optional<PrimType> (#149812)
We use this construct a lot. Use something similar to clang's
UnsignedOrNone.

This results in some slighy compile time improvements:
https://llvm-compile-time-tracker.com/compare.php?from=17a4b0399d161a3b89d8f0ce82add1638f23f5d4&to=a251d81ecd0ed45dd190462663155fdb303ef04d&stat=instructions:u
2025-07-21 17:16:13 +02:00
Timm Baeder
5b0935f1f0
[clang][bytecode] Reintroduce Pointer::elem() (#149693)
As a way of writing atIndex(I).deref<T>(), which creates an intermediate
Pointer, which in turn adds (and removes) that pointer from the pointer
list of the Block. This way we can avoid that.
2025-07-20 10:59:50 +02:00
Timm Baeder
17d3029331
[clang][bytecode] Make union activation more granular (#148835)
Only activate things if the syntactical structure suggests so. This adds
a bunch of new opcodes to control whether to activate in stores, etc.

Fixes #134789
2025-07-16 09:03:33 +02:00
Timm Baeder
130e6121f5
[clang][bytecode][NFC] Move Pointer::StorageKind above the union (#147942)
This is easier to read in debuggers and more common.
2025-07-10 15:05:28 +02:00
Timm Baeder
36dd61f12a
[clang][bytecode] Fix activating nested unions (#147338)
When activating the new pointer, we need to de-activate pointers of all
parent unions, not just the topmost one.
2025-07-08 07:45:17 +02:00
Timm Baeder
1828381ed2
[clang][bytecode] Fix APValue generation for RValueReferenceType (#147207)
We need to ignore the lvalue path, just like we do for lvalue reference
types.
2025-07-06 21:12:18 +02:00
Timm Baeder
db4e927f9f
[clang][bytecode] Misc union fixes (#146824)
First, don't forget to also activate fields which are bitfields on
assignment.

Second, when deactivating fields, recurse into records.
2025-07-06 14:55:29 +02:00
Timm Baeder
fb2c7610e8
[clang][bytecode] Fix comparing pointers pointing to base classes (#146285)
In the attached test case, one pointer points to the `Derived` class and
one to `Base`, but they should compare equal. They didn't because those
two bases are saved at different offsets in the block. Use
`computeOffsetForComparison` not just for unions and fix it to work in
the more general cases.
2025-07-05 19:42:50 +02:00
Timm Baeder
1fe993c251
[clang][bytecode] Allocate operator new data as array (#146471)
Even if we only allocate one element, we still need to allocate it as a
single-element array. This matches what the current interpreter does.
2025-07-01 15:45:50 +02:00
Timm Baeder
c445ca5412
[clang][bytecode] Remove incorrect assertion (#145341)
P.block() will assert that P is a block pointer, which it doesn't have
to be here.
2025-06-23 19:11:01 +02:00
Timm Baeder
2e70da3fba
[clang][bytecode] Partially address string literal uniqueness (#142555)
This still leaves the case of the

constexpr auto b3 = name1() == name1();

test from cxx20.cpp broken.
2025-06-03 16:26:31 +02:00
Timm Baeder
9ae7aa79b1
[clang][bytecode] Diagnose comparing pointers to fields... (#137159)
... with different access specifiers.
2025-04-24 17:04:36 +02:00
Timm Baeder
6196b4ee8c
[clang][bytecode] Don't set OnePastEnd bit for array elements (#136422)
If we refer to arr[N], don't set the OnePastEnd bit of the APValue,
since that is already encoded in the array index.
2025-04-19 16:48:49 +02:00
Timm Baeder
38ca73db22
[clang][bytecode] Give typeinfo APValues an LValuePath (#135948)
That's what the current interpreter does as well.
2025-04-16 13:37:03 +02:00
Timm Baeder
2d63faead4
[clang][bytecode][NFC] Remove PT_FnPtr (#135947)
We don't need this anymore since we don't return it from classify()
anymore.
2025-04-16 13:21:25 +02:00
Timm Baeder
fafeaab6d9
[clang][bytecode] Misc TypeidPointer fixes (#135322)
Fix comparing type id pointers, add mor info when print()ing them, use
the most derived type in GetTypeidPtr() and the canonically unqualified
type when we know the type statically.
2025-04-11 10:35:28 +02:00
Timm Baeder
02f923f8e4
[clang][bytecode] Classify function pointers as PT_Ptr (#135026)
The Pointer class already has the capability to be a function pointer,
but we still classifed function pointers as PT_FnPtr/FunctionPointer.
This means when converting from a Pointer to a FunctionPointer, we lost
the information of what the original Pointer pointed to.
2025-04-10 06:40:54 +02:00
Timm Baeder
7267dbfe10
[clang][bytecode] Fix comparing the addresses of union members (#133852)
Union members get the same address, so we can't just use
`Pointer::getByteOffset()`.
2025-04-01 09:00:46 +02:00
Timm Baeder
a29b0d74a1
[clang][bytecode] Fix base cast of nullptr without descriptor (#132909)
The missing descriptor should only happen if the pointer is null
pointer.
2025-03-25 11:37:03 +01:00