aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/Compiler.cpp
AgeCommit message (Collapse)AuthorFilesLines
48 hours[clang][bytecode] Activate primitive fields before initializing them (#149963)Timm Baeder1-39/+50
The initializer itself might need the field to be active.
2 days[clang][bytecode] Only implicitly start lifetime of ↵Timm Baeder1-1/+8
trivially-default-constructible union members (#149835) See https://github.com/llvm/llvm-project/commit/faee39baa87e43f4b746dd77e479268391163658
4 days[clang][bytecode] Use OptPrimType instead of std::optional<PrimType> (#149812)Timm Baeder1-60/+59
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
5 days[clang][bytecode] Diagnose dereferencing a null pointer (#149330)Timm Baeder1-0/+3
6 days[clang][bytecode] Use bytecode interpreter in isPotentialConstantExprU… ↵Timm Baeder1-0/+5
(#149462) …nevaluated Fake a function call to the given function and evaluate the given expression as if it was part of that function call. Fixes #149383
9 days[clang][bytecode] Make union activation more granular (#148835)Timm Baeder1-49/+141
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
14 days[clang][bytecode] Check lambda captures before binding decls (#148130)Timm Baeder1-12/+20
If the given decls is a lambda capture (but also a BindingDecl), handle it as a lambda capture instead of a BindingDecl.
2025-07-09[clang][bytecode] Devirtualize calls during con- and destruction (#147685)Timm Baeder1-3/+36
When compiliung compiling a ctor or dtor, we need to devirtualize the virtual function calls so we always call the implementation of the current class.
2025-07-08[clang][bytecode] Don't crash on erroneous switch conditions (#147533)Timm Baeder1-0/+3
Not attaching a test since I've only seen this when compiling a large c++26 test case as c++17.
2025-07-08[clang][bytecode] Create a temporary for discarded CXXBindTemporaryExprs ↵Timm Baeder1-1/+14
(#147303) So we run the destructor.
2025-07-06[clang][bytecode] Fix visiting for-range loop variable (#147188)Timm Baeder1-2/+1
Make sure we're properly registering DecompositionDecls.
2025-07-04[clang][bytecode] Fix copy constructors for empty unions (#147050)Timm Baeder1-0/+2
Nothing to do in that case.
2025-07-01[Clang][Bytecode] Implement P1061 structured binding pack (#146474)Yanzuo Liu1-1/+1
Other part of this feature was implemented by #121417.
2025-06-30[clang][bytecode] Classify variable initializer, not the decl (#146338)Timm Baeder1-4/+5
I'm not attaching a test case because I wasn't able to reproduce. The backtrace looks as follows: ``` frame #10: 0x00007fffdedf0b0d libclang-cpp.so.21.0git`clang::interp::Context::evaluateAsInitializer(this=0x00007c6f839f62f0, Parent=0x00007bff7f3820e0, VD=0x00007bff77ce24b0, Result=0x00007bff7165cd78) at Context.cpp:123:16 frame #11: 0x00007fffde7bcc2f libclang-cpp.so.21.0git`clang::Expr::EvaluateAsInitializer(this=0x00007bff77ce3078, Value=0x00007bff7165cd78, Ctx=0x00007e9f839f8200, VD=0x00007bff77ce24b0, Notes=0x00007bff7f0d1620, IsConstantInitialization=false) const at ExprConstant.cpp:17096:20 frame #12: 0x00007fffdde7ca84 libclang-cpp.so.21.0git`clang::VarDecl::evaluateValueImpl(this=0x00007bff77ce24b0, Notes=0x00007bff7f0d1620, IsConstantInitialization=false) const at Decl.cpp:2607:23 frame #13: 0x00007fffdde7a4a2 libclang-cpp.so.21.0git`clang::VarDecl::evaluateValue(this=0x00007bff77ce24b0) const at Decl.cpp:2583:10 frame #14: 0x00007fffdde7a0d7 libclang-cpp.so.21.0git`clang::VarDecl::hasInitWithSideEffects(this=0x00007bff77ce24b0) const at Decl.cpp:2458:39 frame #15: 0x00007fffe8c2e77b libclang-cpp.so.21.0git`clang::ASTDeclWriter::VisitVarDecl(this=0x00007bff7f381b50, D=0x00007bff77ce24b0) at ASTWriterDecl.cpp:1308:27 frame #16: 0x00007fffe8c58bf8 libclang-cpp.so.21.0git`clang::declvisitor::Base<std::add_pointer, clang::ASTDeclWriter, void>::Visit(this=0x00007bff7f381b50, D=0x00007bff77ce24b0) at DeclNodes.inc:296:1 frame #17: 0x00007fffe8c1ad7e libclang-cpp.so.21.0git`clang::ASTDeclWriter::Visit(this=0x00007bff7f381b50, D=0x00007bff77ce24b0) at ASTWriterDecl.cpp:460:31 frame #18: 0x00007fffe8c4f5ae libclang-cpp.so.21.0git`clang::ASTWriter::WriteDecl(this=0x00007e0f83dd8608, Context=0x00007e9f839f8200, D=0x00007bff77ce24b0) at ASTWriterDecl.cpp:3060:5 frame #19: 0x00007fffe8a908a7 libclang-cpp.so.21.0git`clang::ASTWriter::WriteDeclAndTypes(this=0x00007e0f83dd8608, Context=0x00007e9f839f8200) at ASTWriter.cpp:6243:9 frame #20: 0x00007fffe8a805f5 libclang-cpp.so.21.0git`clang::ASTWriter::WriteASTCore(this=0x00007e0f83dd8608, SemaPtr=0x00007e8f83cd3200, isysroot=(Data = "", Length = 0), WritingModule=0x00007e0f83d5bc18) at ASTWriter.cpp:6083:5 frame #21: 0x00007fffe8a7cfa2 libclang-cpp.so.21.0git`clang::ASTWriter::WriteAST(this=0x00007e0f83dd8608, Subject=PointerUnion<clang::Sema *, clang::Preprocessor *> @ 0x00007bff7f18e640, OutputFile=(Data = "/home/tbaeder/code/llvm-project/build/runtimes/runtimes-bins/libcxx/test/libcxx/clang_modules_include.gen.py/Output/complex.h.compile.pass.cpp.dir/t.tmp/1WNKSCAH8NSAM/std-PE20VSNDCJ1A.pcm", Length = 187), WritingModule=0x00007e0f83d5bc18, isysroot=(Data = "", Length = 0), ShouldCacheASTInMemory=true) at ASTWriter.cpp:5434:32 frame #22: 0x00007fffe8cd2168 libclang-cpp.so.21.0git`clang::PCHGenerator::HandleTranslationUnit(this=0x00007e0f83dd8500, Ctx=0x00007e9f839f8200) at GeneratePCH.cpp:86:30 frame #23: 0x00007fffe9595e11 libclang-cpp.so.21.0git`clang::MultiplexConsumer::HandleTranslationUnit(this=0x00007c5f83a00300, Ctx=0x00007e9f839f8200) at MultiplexConsumer.cpp:339:15 frame #24: 0x00007fffdc94121d libclang-cpp.so.21.0git`clang::ParseAST(S=0x00007e8f83cd3200, PrintStats=false, SkipFunctionBodies=false) at ParseAST.cpp:183:13 frame #25: 0x00007fffe9480085 libclang-cpp.so.21.0git`clang::ASTFrontendAction::ExecuteAction(this=0x00007bff7efb9020) at FrontendAction.cpp:1339:3 frame #26: 0x00007fffe947e650 libclang-cpp.so.21.0git`clang::FrontendAction::Execute(this=0x00007bff7efb9020) at FrontendAction.cpp:1221:3 frame #27: 0x00007fffe915a163 libclang-cpp.so.21.0git`clang::CompilerInstance::ExecuteAction(this=0x00007d2f839ef000, Act=0x00007bff7efb9020) at CompilerInstance.cpp:1055:33 frame #28: 0x00007fffe9175bbf libclang-cpp.so.21.0git`clang::CompilerInstance::compileModule(clang::SourceLocation, llvm::StringRef, llvm::StringRef, clang::CompilerInstance&)::$_0::operator()(this=0x00007bff805225e0) const at CompilerInstance.cpp:1291:18 [...] frame #39: 0x00007fffa3ab2a35 libLLVM.so.21.0git`void* llvm::thread::ThreadProxy<std::tuple<void (*)(void*), (anonymous namespace)::RunSafelyOnThreadInfo*>>(Ptr=0x00007c1f839e4330) at thread.h:58:5 frame #40: 0x000000000039933b clang++`asan_thread_start(void*) + 155 frame #41: 0x00007fff84a7dfa8 libc.so.6`start_thread + 952 frame #42: 0x00007fff84b01fcc libc.so.6`__clone3 + 44 ``` where we encounter this declaration: ``` VarDecl 0x7bff790764b0 </[...]test-suite-install/include/c++/v1/__condition_variable/condition_variable.h:49:3, col:53> col:8 in std.condition_variable.condition_variable hidden referenced __result_max '_Rep' cinit `-CallExpr 0x7bff79077078 <col:23, col:53> 'type':'long long' `-ImplicitCastExpr 0x7bff79077058 <col:23, col:49> 'type (*)() noexcept' <FunctionToPointerDecay> `-DeclRefExpr 0x7bff79076670 <col:23, col:49> 'type () noexcept' lvalue CXXMethod 0x7bff791df1f8 'max' 'type () noexcept' `-NestedNameSpecifier TypeSpec 'numeric_limits<__ns_rep>':'std::numeric_limits<long long>' ``` which looks fine at first, but the declaration type does not: ``` TemplateTypeParmType 0x7bff79074dd0 '_Rep' dependent depth 0 index 0 `-TemplateTypeParm 0x7bff79074d70 '_Rep' ``` we cannot classify this, so we later run into an assertion because we assume `PT_Ptr` while the value on the stack is of type `classify(long long)`. Work around this by only looking at the initializer type in that case. For the record, the command line that crashed could be extracted from `ninja check-cxx` and was: ``` /home/tbaeder/code/llvm-project/build/bin/clang++ /home/tbaeder/code/llvm-project/build/runtimes/runtimes-bins/libcxx/test/libcxx/clang_modules_include.gen.py/complex.h.compile.pass.cpp -pthread --target=x86_64-redhat-linux -nostdinc++ -I /home/tbaeder/code/llvm-project/build/runtimes/runtimes-bins/libcxx/test-suite-install/include/x86_64-redhat-linux/c++/v1 -I /home/tbaeder/code/llvm-project/build/runtimes/runtimes-bins/libcxx/test-suite-install/include/c++/v1 -I /home/tbaeder/code/llvm-project/libcxx/test/support -std=c++26 -Werror -Wall -Wctad-maybe-unsupported -Wextra -Wshadow -Wundef -Wunused-template -Wno-unused-command-line-argument -Wno-attributes -Wno-pessimizing-move -Wno-noexcept-type -Wno-atomic-alignment -Wno-reserved-module-identifier -Wdeprecated-copy -Wdeprecated-copy-dtor -Wshift-negative-value -Wno-user-defined-literals -Wno-tautological-compare -Wsign-compare -Wunused-variable -Wunused-parameter -Wunreachable-code -Wno-unused-local-typedef -Wno-local-type-template-args -Wno-c++11-extensions -Wno-unknown-pragmas -Wno-pass-failed -Wno-mismatched-new-delete -Wno-redundant-move -Wno-self-move -Wno-nullability-completeness -D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -D_LIBCPP_ENABLE_EXPERIMENTAL -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE -Werror=thread-safety -Wuser-defined-warnings -fmodules -fcxx-modules -fmodules-cache-path=/home/tbaeder/code/llvm-project/build/runtimes/runtimes-bins/libcxx/test/libcxx/clang_modules_include.gen.py/Output/complex.h.compile.pass.cpp.dir/t.tmp -fsyntax-only ```
2025-06-23[NFC][Clang][AST] Drop `llvm::` in front of `ArrayRef`/`MutableArrayRef` ↵Rahul Joshi1-2/+1
(#145207)
2025-06-20Reapply "Reapply "[clang][bytecode] Allocate IntegralAP and Floating … ↵Timm Baeder1-50/+63
(#145014) …types usi… (#144676)" This reverts commit 68471d29eed2c49f9b439e505b3f24d387d54f97. IntegralAP contains a union: union { uint64_t *Memory = nullptr; uint64_t Val; }; On 64bit systems, both Memory and Val have the same size. However, on 32 bit system, Val is 64bit and Memory only 32bit. Which means the default initializer for Memory will only zero half of Val. We fixed this by zero-initializing Val explicitly in the IntegralAP(unsigned BitWidth) constructor. See also the discussion in https://github.com/llvm/llvm-project/pull/144246
2025-06-18Revert "Reapply "[clang][bytecode] Allocate IntegralAP and Floating types ↵Timm Bäder1-63/+49
usi… (#144676)" This reverts commit 7c15edb306932e41c159f3d69c161ed0d89d47b7. This still breaks clang-armv8-quick: https://lab.llvm.org/buildbot/#/builders/154/builds/17587
2025-06-18Reapply "[clang][bytecode] Allocate IntegralAP and Floating types usi… ↵Timm Baeder1-49/+63
(#144676) …ng an allocator (#144246)" This reverts commit 57828fec760f086b334ce0cb1c465fc559dcaea4.
2025-06-17Revert "[clang][bytecode] Allocate IntegralAP and Floating types using an ↵Timm Bäder1-63/+49
allocator (#144246)" This reverts commit c66be289901b3f035187d391e80e3610d7d6232e. This breaks the armv8-quick builder: https://lab.llvm.org/buildbot/#/builders/154/builds/17549
2025-06-17[clang][bytecode] Allocate IntegralAP and Floating types using an allocator ↵Timm Baeder1-49/+63
(#144246) Both `APInt` and `APFloat` will heap-allocate memory themselves using the system allocator when the size of their data exceeds 64 bits. This is why clang has `APNumericStorage`, which allocates its memory using an allocator (via `ASTContext`) instead. Calling `getValue()` on an ast node like that will then create a new `APInt`/`APFloat` , which will copy the data (in the `APFloat` case, we even copy it twice). That's sad but whatever. In the bytecode interpreter, we have a similar problem. Large integers and floating-point values are placement-new allocated into the `InterpStack` (or into the bytecode, which is a `vector<std::byte>`). When we then later interrupt interpretation, we don't run the destructor for all items on the stack, which means we leak the memory the `APInt`/`APFloat` (which backs the `IntegralAP`/`Floating` the interpreter uses). Fix this by using an approach similar to the one used in the AST. Add an allocator to `InterpState`, which is used for temporaries and local values. Those values will be freed at the end of interpretation. For global variables, we need to promote the values to global lifetime, which we do via `InitGlobal` and `FinishInitGlobal` ops. Interestingly, this results in a slight _improvement_ in compile times: https://llvm-compile-time-tracker.com/compare.php?from=6bfcdda9b1ddf0900f82f7e30cb5e3253a791d50&to=88d1d899127b408f0fb0f385c2c58e6283195049&stat=instructions:u (but don't ask me why). Fixes https://github.com/llvm/llvm-project/issues/139012
2025-06-15[clang][bytecode] Avoid revisiting decomposition decl in visitDeclRef (#144226)Sirui Mu1-4/+0
This simple patch removes the code to revisit `DecompositionDecl` in `visitDeclRef`. The revisit will try to emit the initializer of the `DecompositionDecl`, which could result in evaluation errors if the `DecompositionDecl` is not within a constexpr context.
2025-05-24[clang][bytecode] Check lifetime of all ptr bases in placement-new (#141272)Timm Baeder1-2/+3
placement-new'ing an object with a dead base object is not allowed, so we need to check all the pointer bases.
2025-05-20[clang][bytecode] Check downcasts for the correct type (#140689)Timm Baeder1-3/+6
In multiple inheritance/diamond scenarios, we might arrive at the wrong type.
2025-05-19[clang][bytecode][NFC] Simplify VisitCompoundLiteralExpr (#140547)Timm Baeder1-23/+13
2025-05-19[clang][bytecode] Add a scope to function calls (#140441)Timm Baeder1-47/+70
We need a place to destroy the temporaries created for call arguments.
2025-05-16[clang][bytecode] Explicitly start variable lifetimes via placement new ↵Timm Baeder1-0/+4
(#140221) placement new /std::construct{,_at} can resurrect a variable after it's destructor has been called.
2025-05-15[clang][bytecode] Fix discarded LValueToRValueBitCasts (#140034)Timm Baeder1-4/+5
We handle discarding fine, but we used to ignore all discarded cast expressions. Handle bitcasts differently.
2025-05-14[clang] Save ShuffleVectorExpr args as ConstantExpr (#139709)Timm Baeder1-1/+1
The passed indices have to be constant integers anyway, which we verify before creating the ShuffleVectorExpr. Use the value we create there and save the indices using a ConstantExpr instead. This way, we don't have to evaluate the args every time we call getShuffleMaskIdx().
2025-05-14[clang][bytecode][NFC] Avoid an implicit integer conversion (#139845)Timm Baeder1-1/+1
getCharByteWidth() returns an unsigned.
2025-05-14[clang][bytecode] Use IsNonNull op in visitBool() (#139846)Timm Baeder1-5/+2
We don't need to emit the nullptr and compare to it anymore.
2025-05-13[clang][bytecode] Get BuiltinID from the direct callee (#139675)Timm Baeder1-3/+6
getBuiltinCallee() just checks the direct callee for its builtin id anyway, so let's do this ourselves.
2025-05-13[clang][bytecode] Avoid classifying in visitArrayElemInit() (#139674)Timm Baeder1-10/+12
We usually call this more than once, but the type of the initializer never changes. Let's classify only once and pass that to visitArrayElemInit().
2025-05-09[clang][bytecode] Slightly optimize integral casts of literals (#138879)Timm Baeder1-46/+61
We often see initializers like unsigned a = 10; which take an integer literal and immediately cast it to another type. Recognize this pattern and omit the cast, simply emitting the value as a different type directly. This reduces the instruction count by up to 0.13%: http://llvm-compile-time-tracker.com/compare.php?from=303436c6d16518b35288d63a859506ffcc1681e4&to=648f5202f906d1606390b2d1081e4502dc74acc2&stat=instructions:u
2025-05-08[clang][ExprConstant] Bail out on invalid lambda capture inits (#138832)Timm Baeder1-3/+2
Fixes https://github.com/llvm/llvm-project/issues/138824
2025-05-01[clang][bytecode] Fix checking for integer overflow (#137962)Timm Baeder1-4/+17
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-04-29[clang][bytecode] Check array sizes against step limit (#137679)Timm Baeder1-4/+7
2025-04-28[clang][bytecode] Don't create Function instances for builtins (#137618)Timm Baeder1-5/+1
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[clang][bytecode] Don't create function frames for builtin calls (#137607)Timm Baeder1-1/+1
They don't have local variables etc. so don't create frames for them.
2025-04-27[clang][bytecode] Don't ignore discarded ArraySubScriptExprs (#137526)Timm Baeder1-4/+5
We need to evaluate them since the index might be out of bounds.
2025-04-26[clang][bytecode] Diagnose dynamic_cast before C++20 (#137442)Timm Baeder1-0/+11
Emit a CCE diagnostic.
2025-04-25[clang][bytecode] Diagnose pseudo dtor calls before C++20 (#137303)Timm Baeder1-0/+2
2025-04-25[clang][bytecode] Propagate IsVolatile bit to subobjects (#137293)Timm Baeder1-10/+7
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-23[clang][bytecode] Refine diagnostics for volatile reads (#136857)Timm Baeder1-0/+3
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-22[clang][bytecode] Allow reinterpret casts from/to the same pointer type ↵Timm Baeder1-0/+2
(#136692)
2025-04-17[clang][bytecode] Reject assignments in C (#136126)Timm Baeder1-1/+5
Similar to what the current interpreter does.
2025-04-17[clang][bytecode] Enter a non-constant context when revisiting (#136104)Timm Baeder1-0/+5
Otherwise, things like __builtin_is_constant_evaluated() return the wrong value.
2025-04-16[clang][bytecode][NFC] Remove PT_FnPtr (#135947)Timm Baeder1-9/+6
We don't need this anymore since we don't return it from classify() anymore.
2025-04-16[clang][bytecode] Explicitly mark constexpr-unknown variables as such (#135806)Timm Baeder1-8/+16
Instead of trying to figure out what's constexpr-unknown later on.
2025-04-13[clang][bytecode] Fix an inconsistency with loop condition jumps (#135530)Timm Baeder1-24/+24
When emitting the jump for e.g. a for loop condition, we used to jump out of the CondScope, leaving the scope initialized, because we skipped the corresponding Destroy opcode. If that loop was in a loop itself, that outer loop could then iterate once more, leading to us initializing a scope that was still initialized. Fix this by also destroying the scope after the EndLabel.
2025-04-11[clang][bytecode] Misc TypeidPointer fixes (#135322)Timm Baeder1-3/+10
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.