104 Commits

Author SHA1 Message Date
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
722d6b55ed
[clang][bytecode] Only check expr in CheckThis() if we have to (#141951)
Pre C++11, we dont't need to get the value of IsImplicit.
2025-05-29 17:17:59 +02:00
Timm Baeder
4efe7a590d
[clang][bytecode] Simplify diagnoseUnknownDecl if we're not diagnosing (#141910)
See the added comment.

This improves compile times a bit:

https://llvm-compile-time-tracker.com/compare.php?from=ac62f73f19ae9fb415d3fc423949b8d7543e8717&to=0d6cf47197a4ee11cdd1ee4a48ea38a2907c3d45&stat=instructions:u
2025-05-29 13:02:50 +02:00
Timm Baeder
857ffa1915
[clang][bytecode] Recursively start lifetimes as well (#141742)
The constructor starts the lifetime of all the subobjects.
2025-05-28 16:16:00 +02:00
Timm Baeder
294643e4bd
[clang][bytecode] Check lifetime of all ptr bases in placement-new (#141272)
placement-new'ing an object with a dead base object is not allowed, so
we need to check all the pointer bases.
2025-05-24 14:17:26 +02:00
Timm Baeder
319feac43d
[clang][bytecode] Fix AccessKinds in placement new CheckStore() call (#141123)
CheckStore is for assignments, but we're constructing something here, so
pass AK_Construct instead. We already diagnosed the test case, but as an
assignment.
2025-05-23 13:00:57 +02:00
Timm Baeder
32805964fc
[clang][bytecode] Diagnose placement-new'ing to a temporary (#141099)
... that's been created in a different evaluation.
2025-05-23 08:17:22 +02:00
Timm Baeder
d45f1d0827
[clang][bytecode] Fix self-init diagnostics in C++23 (#141044) 2025-05-22 14:26:52 +02:00
Timm Baeder
7cfeedf64a
[clang][bytecode] Change diagnostics for self-initialization (#141006)
Change the diagnostics when reading from the variable we're currently
initializing do be the same as the one the current interpreter emits.
2025-05-22 10:31:39 +02:00
Timm Baeder
572add0601
[clang][bytecode] Diagnose failed constexpr assertions differently (#140000)
Adjust to the new way the ast walker is doing it.
2025-05-19 13:29:09 +02:00
Timm Baeder
9a26dff748
[clang][bytecode] Check dtor calls for one-past-end pointers (#140047) 2025-05-15 15:43:07 +02:00
Timm Baeder
b26adacc85
[clang][bytecode] Check destructors for temporaries (#140039)
Also, increase the EvalID in isPotentialConstantExpr(), since this is
its own evaluation.
2025-05-15 14:34:35 +02:00
Timm Baeder
c14acb7442
[clang][bytecode] Save Immediate bit in Function (#139671)
Otherwise, we have to look at the FunctionDecl at every function call.
2025-05-13 12:56:08 +02:00
Timm Baeder
98763433e6
[clang][bytecode] Optimize enum value range checks (#139672)
Only do the work if we really have to.
2025-05-13 10:55:24 +02:00
Timm Baeder
98d68e49f7
[clang][bytecode][NFC] Remove unused function (#139355) 2025-05-10 07:57:44 +02:00
Timm Baeder
d6f1de3107
[clang][bytecode] Bail out on invalid function declarations (#138503) 2025-05-05 16:24:53 +02:00
Timm Baeder
c51be1be3a
[clang][bytecode] Fix checking for integer overflow (#137962)
We need to evaluate both the True/False expressions of a conditional
operator as well as the LHS/RHS of a binary operator in more cases.
2025-05-01 07:35:33 +02:00
Timm Baeder
f8724bd873
[clang][bytecode] Check live-ness when calling dtors (#137645)
We can't call a destructor on a dead pointer.
2025-04-28 17:47:30 +02:00
Timm Baeder
959905a5ad
[clang][bytecode] Don't create Function instances for builtins (#137618)
Now that we don't use them anymore in InterpBuiltin.cpp and we don't
create frames for them anymore anyway, just don't create Function
instances.
2025-04-28 14:08:42 +02:00
Timm Baeder
e086d7b146
[clang][bytecode] Don't create function frames for builtin calls (#137607)
They don't have local variables etc. so don't create frames for them.
2025-04-28 13:11:15 +02:00
Timm Baeder
60b3a5b7e7
[clang][bytecode] Fix two small builtin_constant_p cases (#137587)
Only accept string literals if we're pointing to the first index and do
accept complex literals.
2025-04-28 09:21:49 +02:00
Timm Baeder
e045d55dd5
[clang][bytecode] Check for global decls in destructors (#137525)
Destructors can't be called on global variables.
2025-04-27 20:02:58 +02:00
Timm Baeder
ef87c3421c
[clang][bytecode] Check for dummy pointers when calling pseudo dtors (#137437) 2025-04-26 05:47:54 +02:00
Timm Baeder
211b51e471
[clang][bytecode] Propagate IsVolatile bit to subobjects (#137293)
For
```c++
  struct S {
    constexpr S(int=0) : i(1) {}
    int i;
  };
  constexpr volatile S vs;
```

reading from `vs.i` is not allowed, even though `i` is not volatile
qualified. Propagate the IsVolatile bit down the hierarchy, so we know
reading from `vs.i` is a volatile read.
2025-04-25 11:23:34 +02:00
Timm Baeder
5eca2ddeba
[clang][bytecode] Don't diagnose const extern reads in CPCE mode (#137285)
They might become constexpr later.
2025-04-25 08:54:34 +02:00
Timm Baeder
3b58a60086
[clang][bytecode] Allow forming pointers to fields of extern globals (#137211)
This should be fine as long as we're not reading from it.

Note that this regresses
CXX/special/class.init/class.inhctor.init/p1.cpp, which used to work
fine with the bytecode interpreter.

That's because this code now fails:

```c++
  struct Param;
  struct A {
    constexpr A(Param);
    int a;
  };

  struct B : A { B(); using A::A; int b = 2; };
  struct Wrap1 : B { constexpr Wrap1(); };
  struct Wrap2 : Wrap1 {};
  extern const Wrap2 b;

  struct Param {
    constexpr Param(int c) : n(4 * b.a + b.b + c) {}
    int n;
  };
```
and reports that the Param() constructor is never a valid constant
expression. But that's true and the current interpeter should report
that as well. It also fails when calling at compile time.
2025-04-25 07:43:33 +02:00
Timm Baeder
1b6cbaa7b6
[clang][bytecode] Refine diagnostics for volatile reads (#136857)
Differentiate between a volarile read via a lvalue-to-rvalue cast of a
volatile qualified subexpression and a read from a pointer with a
volatile base object.
2025-04-23 18:52:35 +02:00
Timm Baeder
c5d59723cb
[clang][bytecode] Reject constexpr-unknown values in CheckStore (#136279) 2025-04-18 12:48:16 +02:00
Timm Baeder
05eafd9f2b
[clang][bytecode] Explicitly mark constexpr-unknown variables as such (#135806)
Instead of trying to figure out what's constexpr-unknown later on.
2025-04-16 09:00:52 +02:00
Timm Baeder
974bda8f61
[clang][bytecode] Reject constexpr-unknown pointers from Inc ops (#135548)
We used to accept c++ as a known value here, causing wrong codegen.
2025-04-13 18:57:55 +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
Oliver Hunt
1cd59264aa
[RFC] Initial implementation of P2719 (#113510)
This is a basic implementation of P2719: "Type-aware allocation and
deallocation functions" described at http://wg21.link/P2719

The proposal includes some more details but the basic change in
functionality is the addition of support for an additional implicit
parameter in operators `new` and `delete` to act as a type tag. Tag is
of type `std::type_identity<T>` where T is the concrete type being
allocated. So for example, a custom type specific allocator for `int`
say can be provided by the declaration of

  void *operator new(std::type_identity<int>, size_t, std::align_val_t);
  void  operator delete(std::type_identity<int>, void*, size_t, std::align_val_t);

However this becomes more powerful by specifying templated declarations,
for example

template <typename T> void *operator new(std::type_identity<T>, size_t, std::align_val_t);
template <typename T> void operator delete(std::type_identity<T>, void*, size_t, std::align_val_t););

Where the operators being resolved will be the concrete type being
operated over (NB. A completely unconstrained global definition as above
is not recommended as it triggers many problems similar to a general
override of the global operators).

These type aware operators can be declared as either free functions or
in class, and can be specified with or without the other implicit
parameters, with overload resolution performed according to the existing
standard parameter prioritisation, only with type parameterised
operators having higher precedence than non-type aware operators. The
only exception is destroying_delete which for reasons discussed in the
paper we do not support type-aware variants by default.
2025-04-10 17:13:10 -07: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
11dd7d98a6
[clang][bytecode] Reject constexpr-unknown values from comparisons (#133701) 2025-03-31 18:53:01 +02:00
Timm Baeder
cb7b10c66e
[clang][bytecode] Fail on mutable reads from revisited variables (#133064)
When revisiting a variable, we do that by simply calling visitDecl() for
it, which means it will end up with the same EvalID as the rest of the
evaluation - but this way we end up allowing reads from mutable
variables. Disallow that.
2025-03-26 12:29:31 +01:00
Timm Baeder
849e5ea94f
[clang][bytecode] Add Descriptor::getDataType() (#132681)
This returns the type of data in the Block, which might be different
than the type of the expression or declaration we created the block for.
This lets us remove some special cases from CheckNewDeleteForms() and
CheckNewTypeMismatch().
2025-03-24 09:47:52 +01:00
Timm Baeder
49f06075a6
[clang][bytecode] Fix union copy/move operator active check (#132238)
Don't call CheckActive for copy/move operators. They will activate the
union member.
2025-03-20 19:08:55 +01:00
Timm Baeder
2f808dd070
[clang][bytecode] Compile most recent function decl (#131730)
We used to always do this because all calls went through the code path
that calls getMostRecentDecl(). Do it now, too.
2025-03-18 07:29:38 +01:00
Timm Baeder
ca1bde0b91
[clang][bytecode] Check dtor instance pointers for active-ness (#128732)
And diagnose if we're trying to destroy an inactive member of a union.
2025-03-17 19:01:35 +01:00
Timm Baeder
83356f3b62
[clang][bytecode] Compile functions lazily (#131596)
Create the Function* handles for all functions we see, but delay the
actual compilation until we really call the function. This speeds up
compile times with the new interpreter a bit.
2025-03-17 15:58:35 +01:00
Timm Baeder
d08cf7900d
[clang][bytecode] Implement __builtin_constant_p (#130143)
Use the regular code paths for interpreting.

Add new instructions: `StartSpeculation` will reset the diagnostics
pointers to `nullptr`, which will keep us from reporting any diagnostics
during speculation. `EndSpeculation` will undo this.

The rest depends on what `Emitter` we use.

For `EvalEmitter`, we have no bytecode, so we implement `speculate()` by
simply visiting the first argument of `__builtin_constant_p`. If the
evaluation fails, we push a `0` on the stack, otherwise a `1`.

For `ByteCodeEmitter`, add another instrucion called `BCP`, that
interprets all the instructions following it until the next
`EndSpeculation` instruction. If any of those instructions fails, we
jump to the `EndLabel`, which brings us right before the
`EndSpeculation`. We then push the result on the stack.
2025-03-08 06:06:14 +01:00
Timm Baeder
bdbc434498
[clang][bytecode] Ignore function calls with depth > 0... (#129887)
... when checking for a potential constant expression. This is also what
the current interpreter does.
2025-03-05 16:21:03 +01:00
Timm Baeder
aeca2aa193
[clang][bytecode] Fix CallPtr return type check (#129722)
CallExpr::getType() isn't enough here in some cases, we need to use
CallExpr::getCallReturnType().
2025-03-04 17:14:13 +01:00
Timm Baeder
1d8eb436ca
[clang][bytecode] Diagnose member calls on inactive union fields (#129709)
Unless the function is a constructor, which is allowed to do this since
it will activate the member.
2025-03-04 16:14:47 +01:00
Timm Baeder
82d111e820
[clang][bytecode][NFC] Minor cleanups (#129553)
Pull local variables in to the closest scope, remove some unnecessary
calls to getLocation() and remove an outdated comment.
2025-03-04 06:17:07 +01:00
Timm Baeder
96336acb48
[clang][bytecode] Tighten double-destroy check (#129528)
The instance pointer of the current function being the same as the one
we're destroying is only relevant if said function is also a destructor.
2025-03-03 16:26:56 +01:00
Timm Baeder
dff2ca424c
[clang][bytecode] Add special case for anonymous unions (#128681)
This fixes the expected output to match the one of the current
interpreter.
2025-02-25 12:46:06 +01:00
Timm Baeder
8102fec00b
[clang][bytecode] Reject calls to pure virtual functions (#128412) 2025-02-23 11:44:37 +01:00
Timm Baeder
c38befd94f
[clang][bytecode] Fix delete[] dtor order (#128411)
As always, call array dtors in reverse order.
2025-02-23 11:32:35 +01:00
Timm Baeder
6db96c9ecc
[clang][bytecode] Always reject ctors of invalid parent decls (#128295)
The copy constructor of an invalid declaration might still be perfectly
valid, but we still need to reject it.
2025-02-22 22:04:44 +01:00