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.


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to