Commit Graph

118 Commits

Author SHA1 Message Date
Timm Bäder
8e69052b0e [clang][Interp] Handle ArrayTypeTraitExprs 2024-03-16 12:46:28 +01:00
Timm Bäder
719e077a56 [clang][Interp] Handle PackIndexExprs 2024-03-15 10:04:23 +01:00
Timm Bäder
d02d8df0cd [clang][Interp] Implement _Complex negation
Factor complex unary operations into their own function.
2024-03-12 05:34:57 +01:00
Timm Bäder
8aed911fe9 [clang][Interp] Implement complex comparisons 2024-03-07 17:04:05 +01:00
Timm Bäder
49c399c2d1 [clang][Interp] Toplevel destructors may fail
We used to run them, but not check if they failed. If they do,
the expression is invalid, even if we already have a result.

I do have a suspicion that we need to manually call destroyLocals()
in more places (everywhere basically?), but I'll wait with that
until I have a reproducer at hand.
2024-02-28 09:48:27 +01:00
Timm Bäder
b70f42a430 [clang][Interp] Handle PseudoObjectExprs
Evaluate all the semantic expressions.
2024-02-27 17:11:19 +01:00
Timm Bäder
70e61f5bbb [clang][Interp][NFC] Rename InitPtr{,Pop} to FinishInit{,Pop}
The old name clashes with the Init opcode.
2024-02-27 16:14:37 +01:00
Timm Bäder
91ebd010aa [clang][Interp] Remove dereference()
This function tried to be smart about the dereferenced value,
but it ended up hurting more than it helped. At least in the current
state, where we still try get the correct output.

I might add something similar back later.
2024-02-21 15:25:55 +01:00
Timm Baeder
9fa18f6598 [clang][Interp] Handle complex values in visitBool() (#79452)
In C++, we get a ComplexToBool cast, but we might not in C.
2024-02-20 10:27:41 +01:00
Timm Bäder
48439bd7a7 [clang][Interp] Handle rewritten binary operators
Just delegate to the syntactic form.
2024-02-19 13:05:56 +01:00
Timm Bäder
fcf3ca9a5e [clang][Interp][NFC] Split emitRecordDestruction
into a general part and a record part. This will be needed in future
patches.
2024-02-19 09:23:31 +01:00
Timm Bäder
bb60c066a2 [clang][Interp] Handle Requires- and ConceptSpecializationExprs
Just emit their satisfaction state, which is what the current
interpreter does as well.
2024-02-13 15:01:17 +01:00
Timm Bäder
9b718c0d5d [clang][Interp] Handle CXXUuidofExprs
Allocate storage and initialize it with the given APValue contents.
2024-02-13 13:41:06 +01:00
Timm Bäder
9e73656af5 [clang][Interp] Support ExpressionTraitExprs
Just push a constant bool value.
2024-02-09 10:23:54 +01:00
Timm Bäder
06774d6bbf [clang][Interp] Handle CXXInheritedCtorInitExprs
We need to forward all arguments of the current function and
call the ctor function.
2024-02-08 15:36:07 +01:00
Timm Bäder
5e8626c920 [clang][Interp] Handle ObjCBoolLiteralExprs
Emit them just like the others, but these are integer typed.
2024-02-05 18:21:30 +01:00
Timm Bäder
58ceefe09c [clang][Interp] Support ChooseExprs 2024-02-02 08:20:52 +01:00
Timm Bäder
48f8b74c35 [clang][Interp] Support GenericSelectionExprs
Just delegate to the resulting expression.
2024-02-01 08:15:11 +01:00
Timm Bäder
fa98e2861d [clang][Interp][NFC] Remove unused RecordScope 2024-02-01 08:03:49 +01:00
Timm Baeder
6ff431b01e [clang][Interp] Handle imaginary literals (#79130)
Initialize the first element to 0 and the second element to the value of
the subexpression.
2024-02-01 07:13:10 +01:00
Timm Baeder
47df391296 [clang][Interp] Handle std::move etc. builtins (#70772) 2024-01-31 15:57:23 +01:00
Timm Baeder
5bb99edcb6 [clang][Interp] Add inline descriptor to global variables (#72892)
Some time ago, I did a similar patch for local variables.

Initializing global variables can fail as well:
```c++
constexpr int a = 1/0;
static_assert(a == 0);
```
... would succeed in the new interpreter, because we never saved the
fact that `a` has not been successfully initialized.
2024-01-31 08:03:37 +01:00
Timm Bäder
499507fdec [clang][Interp][NFC] Remove unused function 2024-01-27 09:06:03 +01:00
isuckatcs
c177507bd2 [clang][Interp] Cleaning up FIXMEs added during ArrayInitLoopExpr implementation. (#70053)
This patch removes the two `FIXME`s that were added with patches related
to the expression mentioned in the title.
2024-01-26 17:19:11 +01:00
Timm Bäder
dee02ee9f8 [clang][Interp][NFC] Complex elements can only be primitives
So, return a PrimType directly from classifyComplexElementType().
2024-01-24 12:56:16 +01:00
Timm Baeder
4e7cf1b1ed [clang][Interp] Add an EvaluationResult class (#71315)
Add an `EvaluationResult` class. This contains the result either as a
`Pointer` or as a `APValue`.

This way, we can inspect the result of the evaluation and diagnose
problems with it (e.g. uninitialized fields in global initializers or
pointers pointing to things they shouldn't point to).
2024-01-19 10:08:03 +01:00
Timm Baeder
18d0a7e4c0 [clang][Interp] Implement ComplexToReal casts (#77294)
Add a new emitComplexReal() helper function and use that for the new
casts as well as the old __real implementation.
2024-01-18 13:55:04 +01:00
Timm Bäder
d16cf470ac [clang][Interp] Start implementing binary operators for complex types
Differential Revision: https://reviews.llvm.org/D155572
2023-12-14 15:33:52 +01:00
Timm Bäder
497480b38a [clang][Interp] IntegralComplexToBoolean casts
Differential Revision: https://reviews.llvm.org/D148426
2023-12-14 13:11:00 +01:00
Timm Bäder
4a8b43ba3b [clang][Interp][NFC] Factor array element init into its own function 2023-11-20 13:00:57 +01:00
Timm Baeder
410f130bb9 [clang][Interp] Fix classify for glvalues of function type (#72269)
This can't be tested right now but will show up once we use the new
interpreter in evaluateAsConstantExpression() as well.

Pulled out from https://github.com/llvm/llvm-project/pull/70763
2023-11-14 19:40:59 +01:00
Timm Baeder
216dfd5ff0 [clang][Interp] Fix stack peek offset for This ptr (#70663)
`Function::getArgSize()` include both the instance and the RVO pointer,
so we need to subtract here.
2023-11-14 16:22:22 +01:00
Timm Baeder
190b9179a5 [clang][Interp] Handle SizeOfPackExprs (#71929) 2023-11-12 05:34:16 +01:00
Timm Bäder
311f725d9a [clang][Interp] Create only globals when initializing a global variable
For this code:

struct O {
  int &&j;
};

O o1(0);

The generated AST for the initializer of o1 is:

VarDecl 0x62100006ab08 <array.cpp:119:3, col:9> col:5 o1 'O':'O' parenlistinit
`-ExprWithCleanups 0x62100006b250 <col:7, col:9> 'O':'O'
  `-CXXParenListInitExpr 0x62100006b210 <col:7, col:9> 'O':'O'
    `-MaterializeTemporaryExpr 0x62100006b1f0 <col:8> 'int' xvalue
      `-IntegerLiteral 0x62100006abd0 <col:8> 'int' 0

Before this patch, we create a local temporary variable for the
MaterializeTemporaryExpr and destroy it again when destroying the
EvalEmitter we create to interpret the initializer. However, since
O::j is a reference, this reference now points to a local variable
that doesn't exist anymore.

Differential Revision: https://reviews.llvm.org/D156453
2023-10-19 14:50:17 +02:00
Timm Bäder
80737d2ddf [clang][Interp][NFC] Pass PrimType to visitZeroInitializer()
This fixes an old FIXME comment. Almost all callers already classify()
the type anyway, so just pass the result of that
to visitZeroInitializer().
2023-10-14 18:43:00 +02:00
Timm Baeder
12107386ca [clang][Interp] Handle CXXScalarValueInitExprs (#67147)
Handle those by just zero-initializing the result.
2023-10-10 12:45:09 +02:00
Timm Bäder
87461d6696 [clang][Interp] Implement __builtin_offsetof
Differential Revision: https://reviews.llvm.org/D156400
2023-09-11 12:03:47 +02:00
Timm Bäder
3276ac86aa [clang][Interp][NFC] Remove unused function prototype
This was causing warnings in MSVC.
2023-09-08 16:40:10 +02:00
Timm Bäder
92ac46e703 [clang][Interp] Handle CXXParenListInitExprs
Differential Revision: https://reviews.llvm.org/D156047
2023-09-06 15:26:54 +02:00
Timm Bäder
b93d2d37e7 [clang][Interp] Handle SourceLocExprs
Differential Revision: https://reviews.llvm.org/D155627
2023-09-06 14:45:49 +02:00
Timm Bäder
adb1fb40e8 [clang][Interp] Handle mixed floating/integral compound assign operators
Differential Revision: https://reviews.llvm.org/D157596
2023-09-05 12:10:00 +02:00
Timm Bäder
6d79f985b5 [clang][Interp] Implement zero-init of record types
Differential Revision: https://reviews.llvm.org/D154189
2023-09-05 11:20:35 +02:00
Timm Bäder
12a789710e [clang][Interp] BaseToDerived casts
We can implement these similarly to DerivedToBase casts. We just have to
walk the class hierarchy, sum the base offsets and subtract it from the
current base offset of the pointer.

Differential Revision: https://reviews.llvm.org/D149133
2023-09-05 10:53:54 +02:00
Timm Bäder
6dfe55569d [clang][Interp] Rework initializers
Before this patch, we had visitRecordInitializer() and
visitArrayInitializer(), which were different from the regular visit()
in that they expected a pointer on the top of the stack, which they
initialized. For example, visitArrayInitializer handled InitListExprs by
looping over the members and initializing the elements of that pointer.

However, this had a few corner cases and problems. For example, in
visitLambdaExpr() (a lambda is always of record type), it was not clear
whether we should always create a new local variable to save the lambda
to, or not. This is why https://reviews.llvm.org/D153616 changed
things around.

This patch changes the visiting functions to:

 - visit(): Always leaves a new value on the stack. If the expression
   can be mapped to a primitive type, it's just visited and the value is
   put on the stack. If it's of composite type, this function will
   create a local variable for the expression value and call
   visitInitializer(). The pointer to the local variable will stay on
   the stack.

 - visitInitializer(): Visits the given expression, assuming there is a
   pointer on top of the stack that will be initialized by it.

 - discard(): Visit the expression for side-effects, but don't leave a
   value on the stack.

It also adds an additional Initializing flag to differentiate between the initializing and non-initializing case.

Differential Revision: https://reviews.llvm.org/D156027
2023-08-20 13:33:08 +02:00
Timm Bäder
c4becd50ad [clang][Interp] Support __null
Differential Revision: https://reviews.llvm.org/D155552
2023-08-17 10:28:37 +02:00
Timm Bäder
378fcbf20f [clang][Interp] Handle CXXNoexceptExprs
Differential Revision: https://reviews.llvm.org/D155707
2023-07-26 12:23:54 +02:00
Timm Bäder
8c0246c7f5 [clang][Interp] Reject reinterpret_casts
Add a new InvalidCast op for this purpose and emit a diagnostic.

Differential Revision: https://reviews.llvm.org/D153276
2023-07-26 09:56:29 +02:00
Timm Bäder
7d876c62a3 [clang][Interp] Add 'Invalid' opcode and use it for throw stmts
We will use this opcode for conditionally executed statements that are
invalid in a constant expression.

Differential Revision: https://reviews.llvm.org/D150364
2023-07-26 08:59:53 +02:00
Timm Bäder
e45d199768 [clang][Interp] Handle CXXTemporaryObjectExprs
This is a CXXConstructExpr, so create a local temporary variable and
initialize it.

Differential Revision: https://reviews.llvm.org/D147591
2023-07-26 07:36:26 +02:00
Timm Bäder
254ad7dd41 [clang][Interp][NFC] Move isGloballyIndexed() to Context
And use it in Program as well, to make a similar decision.
2023-07-09 16:27:49 +02:00