[clang] 36cf51d - [clang][bytecode] Classify variable initializer, not the decl (#146338)

via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 30 10:50:51 PDT 2025


Author: Timm Baeder
Date: 2025-06-30T19:50:48+02:00
New Revision: 36cf51d16e02d55217bc4698ca3eb2ecf61ab22c

URL: https://github.com/llvm/llvm-project/commit/36cf51d16e02d55217bc4698ca3eb2ecf61ab22c
DIFF: https://github.com/llvm/llvm-project/commit/36cf51d16e02d55217bc4698ca3eb2ecf61ab22c.diff

LOG: [clang][bytecode] Classify variable initializer, not the decl (#146338)

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
```

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/Compiler.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 81da16e797bce..759d5a64f97be 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -4574,22 +4574,23 @@ VarCreationState Compiler<Emitter>::visitDecl(const VarDecl *VD,
 template <class Emitter>
 bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD,
                                            bool ConstantContext) {
-  std::optional<PrimType> VarT = classify(VD->getType());
 
   // We only create variables if we're evaluating in a constant context.
   // Otherwise, just evaluate the initializer and return it.
   if (!ConstantContext) {
     DeclScope<Emitter> LS(this, VD);
-    if (!this->visit(VD->getAnyInitializer()))
+    const Expr *Init = VD->getInit();
+    if (!this->visit(Init))
       return false;
-    return this->emitRet(VarT.value_or(PT_Ptr), VD) && LS.destroyLocals() &&
-           this->emitCheckAllocations(VD);
+    return this->emitRet(classify(Init).value_or(PT_Ptr), VD) &&
+           LS.destroyLocals() && this->emitCheckAllocations(VD);
   }
 
   LocalScope<Emitter> VDScope(this, VD);
   if (!this->visitVarDecl(VD, /*Toplevel=*/true))
     return false;
 
+  std::optional<PrimType> VarT = classify(VD->getType());
   if (Context::shouldBeGloballyIndexed(VD)) {
     auto GlobalIndex = P.getGlobal(VD);
     assert(GlobalIndex); // visitVarDecl() didn't return false.


        


More information about the cfe-commits mailing list