Skip to content

[RFC][C++20][Modules] Fix crash when function and lambda inside loaded from different modules #104512

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

dmpolukhin
Copy link
Contributor

@dmpolukhin dmpolukhin commented Aug 15, 2024

Summary:
Because AST loading code is lazy and happens in unpredictable order it could happen that function and lambda inside function can be loaded from different modules. In this case, captured DeclRefExpr won’t match the corresponding VarDecl inside function. In AST it looks like this:

FunctionDecl 0x555564f4aff0 <Conv.h:33:1, line:41:1> line:33:35 imported in ./thrift_cpp2_base.h hidden tryTo 'Expected<Tgt, const char *> ()' inline
|-also in ./folly-conv.h
`-CompoundStmt 0x555564f7cfc8 <col:43, line:41:1>
  |-DeclStmt 0x555564f7ced8 <line:34:3, col:17>
  | `-VarDecl 0x555564f7cef8 <col:3, col:16> col:7 imported in ./thrift_cpp2_base.h hidden referenced result 'Tgt' cinit
  |   `-IntegerLiteral 0x555564f7d080 <col:16> 'int' 0
  |-CallExpr 0x555564f7cea8 <line:39:3, col:76> '<dependent type>'
  | |-UnresolvedLookupExpr 0x555564f7bea0 <col:3, col:19> '<overloaded function type>' lvalue (no ADL) = 'then_' 0x555564f7bef0
  | |-CXXTemporaryObjectExpr 0x555564f7bcb0 <col:25, col:45> 'Expected<bool, int>':'folly::Expected<bool, int>' 'void () noexcept' zeroing
  | `-LambdaExpr 0x555564f7bc88 <col:48, col:75> '(lambda at Conv.h:39:48)'
  |   |-CXXRecordDecl 0x555564f76b88 <col:48> col:48 imported in ./folly-conv.h hidden implicit <undeserialized declarations> class definition
  |   | |-also in ./thrift_cpp2_base.h
  |   | `-DefinitionData lambda empty standard_layout trivially_copyable literal can_const_default_init
  |   |   |-DefaultConstructor defaulted_is_constexpr
  |   |   |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
  |   |   |-MoveConstructor exists simple trivial needs_implicit
  |   |   |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
  |   |   |-MoveAssignment
  |   |   `-Destructor simple irrelevant trivial constexpr needs_implicit
  |   `-CompoundStmt 0x555564f7d1a8 <col:58, col:75>
  |     `-ReturnStmt 0x555564f7d198 <col:60, col:67>
  |       `-DeclRefExpr 0x555564f7d0a0 <col:67> 'Tgt' lvalue Var 0x555564f7d0c8 'result' 'Tgt' refers_to_enclosing_variable_or_capture
  `-ReturnStmt 0x555564f7bc78 <line:40:3, col:11>
    `-InitListExpr 0x555564f7bc38 <col:10, col:11> 'void'

This diff changes AST deserialization to load lambdas inside canonical function declaration earlier right after the function to make sure that they loaded from the same module.

Test Plan: check-clang

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:modules C++20 modules and Clang Header Modules labels Aug 15, 2024
@llvmbot
Copy link
Member

llvmbot commented Aug 15, 2024

@llvm/pr-subscribers-clang-modules

@llvm/pr-subscribers-clang

Author: Dmitry Polukhin (dmpolukhin)

Changes

Summary:
Because AST loading code is lazy and happens in unpredictable order it could happen that function and lambda inside function can be loaded from different modules. In this case, captured DeclRefExpr won’t match the corresponding VarDecl inside function. In AST it looks like this:

FunctionDecl 0x555564f4aff0 &lt;Conv.h:33:1, line:41:1&gt; line:33:35 imported in ./thrift_cpp2_base.h hidden tryTo 'Expected&lt;Tgt, const char *&gt; ()' inline
|-also in ./folly-conv.h
`-CompoundStmt 0x555564f7cfc8 &lt;col:43, line:41:1&gt;
  |-DeclStmt 0x555564f7ced8 &lt;line:34:3, col:17&gt;
  | `-VarDecl 0x555564f7cef8 &lt;col:3, col:16&gt; col:7 imported in ./thrift_cpp2_base.h hidden referenced result 'Tgt' cinit
  |   `-IntegerLiteral 0x555564f7d080 &lt;col:16&gt; 'int' 0
  |-CallExpr 0x555564f7cea8 &lt;line:39:3, col:76&gt; '&lt;dependent type&gt;'
  | |-UnresolvedLookupExpr 0x555564f7bea0 &lt;col:3, col:19&gt; '&lt;overloaded function type&gt;' lvalue (no ADL) = 'then_' 0x555564f7bef0
  | |-CXXTemporaryObjectExpr 0x555564f7bcb0 &lt;col:25, col:45&gt; 'Expected&lt;bool, int&gt;':'folly::Expected&lt;bool, int&gt;' 'void () noexcept' zeroing
  | `-LambdaExpr 0x555564f7bc88 &lt;col:48, col:75&gt; '(lambda at Conv.h:39:48)'
  |   |-CXXRecordDecl 0x555564f76b88 &lt;col:48&gt; col:48 imported in ./folly-conv.h hidden implicit &lt;undeserialized declarations&gt; class definition
  |   | |-also in ./thrift_cpp2_base.h
  |   | `-DefinitionData lambda empty standard_layout trivially_copyable literal can_const_default_init
  |   |   |-DefaultConstructor defaulted_is_constexpr
  |   |   |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
  |   |   |-MoveConstructor exists simple trivial needs_implicit
  |   |   |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
  |   |   |-MoveAssignment
  |   |   `-Destructor simple irrelevant trivial constexpr needs_implicit
  |   `-CompoundStmt 0x555564f7d1a8 &lt;col:58, col:75&gt;
  |     `-ReturnStmt 0x555564f7d198 &lt;col:60, col:67&gt;
  |       `-DeclRefExpr 0x555564f7d0a0 &lt;col:67&gt; 'Tgt' lvalue Var 0x555564f7d0c8 'result' 'Tgt' refers_to_enclosing_variable_or_capture
  `-ReturnStmt 0x555564f7bc78 &lt;line:40:3, col:11&gt;
    `-InitListExpr 0x555564f7bc38 &lt;col:10, col:11&gt; 'void'

I’m not sure that it is the right fix for the problem so any ideas how to fix it better are very appreciated.

Test Plan: check-clang


Full diff: https://github.com/llvm/llvm-project/pull/104512.diff

3 Files Affected:

  • (modified) clang/lib/Sema/SemaTemplateInstantiate.cpp (+5)
  • (modified) clang/lib/Serialization/ASTReaderDecl.cpp (+7)
  • (added) clang/test/Headers/crash-instantiated-in-scope-cxx-modules.cpp (+76)
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 9a6cd2cd0ab751..f784de3a20acf2 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -4363,6 +4363,11 @@ LocalInstantiationScope::findInstantiationOf(const Decl *D) {
       // a previous declaration.
       if (const TagDecl *Tag = dyn_cast<TagDecl>(CheckD))
         CheckD = Tag->getPreviousDecl();
+      else if (const VarDecl *VD = dyn_cast<VarDecl>(CheckD))
+        // Check re-declaration chain for variable to deduplicate variables
+        // that might be captured inside lambdas. Function and lambda class
+        // inside can be loaded from different modules.
+        CheckD = VD->getPreviousDecl();
       else
         CheckD = nullptr;
     } while (CheckD);
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index c118f3818467d9..bd46ac3f29af56 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -3286,6 +3286,13 @@ DeclContext *ASTDeclReader::getPrimaryContextForMerging(ASTReader &Reader,
   if (auto *TU = dyn_cast<TranslationUnitDecl>(DC))
     return TU->getPrimaryContext();
 
+  // Merge VarDecls inside functions to deduplicate variables that might be
+  // captured inside lambdas. Function and lambda class inside can be loaded
+  // from different modules.
+  if (auto *FD = dyn_cast<FunctionDecl>(DC))
+    if (FD->getOwningModule())
+      return FD->getCanonicalDecl();
+
   return nullptr;
 }
 
diff --git a/clang/test/Headers/crash-instantiated-in-scope-cxx-modules.cpp b/clang/test/Headers/crash-instantiated-in-scope-cxx-modules.cpp
new file mode 100644
index 00000000000000..80844a58ad825a
--- /dev/null
+++ b/clang/test/Headers/crash-instantiated-in-scope-cxx-modules.cpp
@@ -0,0 +1,76 @@
+// RUN: rm -fR %t
+// RUN: split-file %s %t
+// RUN: cd %t
+// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header -Werror=uninitialized folly-conv.h
+// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header -Werror=uninitialized thrift_cpp2_base.h
+// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header -Werror=uninitialized -fmodule-file=folly-conv.pcm -fmodule-file=thrift_cpp2_base.pcm logger_base.h
+
+//--- Conv.h
+#pragma once
+
+template <typename _Tp, typename _Up = _Tp&&>
+_Up __declval(int);
+
+template <typename _Tp>
+auto declval() noexcept -> decltype(__declval<_Tp>(0));
+
+namespace folly {
+
+template <class Value, class Error>
+struct Expected {
+  template <class Yes>
+  auto thenOrThrow() -> decltype(declval<Value&>()) {
+    return 1;
+  }
+};
+
+struct ExpectedHelper {
+  template <class Error, class T>
+  static constexpr Expected<T, Error> return_(T) {
+    return Expected<T, Error>();
+  }
+
+  template <class This, class Fn, class E = int, class T = ExpectedHelper>
+  static auto then_(This&&, Fn&&)
+      -> decltype(T::template return_<E>((declval<Fn>()(true), 0))) {
+    return Expected<int, int>();
+  }
+};
+
+template <class Tgt>
+inline Expected<Tgt, const char*> tryTo() {
+  Tgt result = 0;
+  // In build with asserts:
+  // clang/lib/Sema/SemaTemplateInstantiate.cpp: llvm::PointerUnion<Decl *, LocalInstantiationScope::DeclArgumentPack *> *clang::LocalInstantiationScope::findInstantiationOf(const Decl *): Assertion `isa<LabelDecl>(D) && "declaration not instantiated in this scope"' failed.
+  // In release build compilation error on the line below inside lambda:
+  // error: variable 'result' is uninitialized when used here [-Werror,-Wuninitialized]
+  ExpectedHelper::then_(Expected<bool, int>(), [&](bool) { return result; });
+  return {};
+}
+
+} // namespace folly
+
+inline void bar() {
+  folly::tryTo<int>();
+}
+// expected-no-diagnostics
+
+//--- folly-conv.h
+#pragma once
+#include "Conv.h"
+// expected-no-diagnostics
+
+//--- thrift_cpp2_base.h
+#pragma once
+#include "Conv.h"
+// expected-no-diagnostics
+
+//--- logger_base.h
+#pragma once
+import "folly-conv.h";
+import "thrift_cpp2_base.h";
+
+inline void foo() {
+  folly::tryTo<unsigned>();
+}
+// expected-no-diagnostics

Copy link
Member

@ChuanqiXu9 ChuanqiXu9 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel the change is somewhat odd to me. Since the description is about the lambda but the change is about VarDecls. I feel there is a mismatch and I feel this may not solve the underlying problem fundamentally. I feel it'll be better to make it more straight forward. e.g., load the context when loading the lambda (or only make it if there is captures.)

@dmpolukhin
Copy link
Contributor Author

I feel the change is somewhat odd to me. Since the description is about the lambda but the change is about VarDecls. I feel there is a mismatch and I feel this may not solve the underlying problem fundamentally. I feel it'll be better to make it more straight forward. e.g., load the context when loading the lambda (or only make it if there is captures.)

It was my initial approach to make sure that clang loads function and its lambdas from the same module. But I haven't found examples in clang how to make that canonical decls for two related things are always loaded from the same module. Clang starts loading function tryTo from thrift_cpp2_base.h module it follow links and via declval function specialization it discovers the lambda from folly-conv.h module that becomes canonical so by the time when it recursively returns to the lambda inside thrift_cpp2_base.h it just merged it to already known decl from folly-conv.h. I don't know how to make sure that deserialization won't intermix. As far as I understand code, clang solves this issue by merging identical decls so I implemented merging for VarDecls that cause this issue. But if there is a way to synchronize loading for a function and it's lambda, it should be more reliable but I failed to find the way. Help with solving this issue is very appreciated, clang seems to have other issues with merging lambdas too but I was not able to create small reproducers in other cases yet.

@ChuanqiXu9
Copy link
Member

Here is another example that merging lambdas are problematic: #102721. Although I think we need to solve the problems separately. They are different problems.

I feel the change is somewhat odd to me. Since the description is about the lambda but the change is about VarDecls. I feel there is a mismatch and I feel this may not solve the underlying problem fundamentally. I feel it'll be better to make it more straight forward. e.g., load the context when loading the lambda (or only make it if there is captures.)

It was my initial approach to make sure that clang loads function and its lambdas from the same module. But I haven't found examples in clang how to make that canonical decls for two related things are always loaded from the same module. Clang starts loading function tryTo from thrift_cpp2_base.h module it follow links and via declval function specialization it discovers the lambda from folly-conv.h module that becomes canonical so by the time when it recursively returns to the lambda inside thrift_cpp2_base.h it just merged it to already known decl from folly-conv.h. I don't know how to make sure that deserialization won't intermix. As far as I understand code, clang solves this issue by merging identical decls so I implemented merging for VarDecls that cause this issue. But if there is a way to synchronize loading for a function and it's lambda, it should be more reliable but I failed to find the way. Help with solving this issue is very appreciated, clang seems to have other issues with merging lambdas too but I was not able to create small reproducers in other cases yet.

But the current patch still smells bad. Let's try to find a cleaner way to proceed. IIUC, the key of the current problem is that, the CXXRecordDecl of the lambda are assigned to the wrong FunctionDecl as the DeclContext? Or the LambdaExpr appears in the wrong FunctionDecl?

@dmpolukhin dmpolukhin marked this pull request as draft August 20, 2024 07:03
Copy link

github-actions bot commented Aug 20, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@dmpolukhin
Copy link
Contributor Author

Here is another example that merging lambdas are problematic: #102721. Although I think we need to solve the problems separately. They are different problems.

Thank you for the reference, we need this fix too.

But the current patch still smells bad. Let's try to find a cleaner way to proceed. IIUC, the key of the current problem is that, the CXXRecordDecl of the lambda are assigned to the wrong FunctionDecl as the DeclContext? Or the LambdaExpr appears in the wrong FunctionDecl?

Yeah, I agree. Problem with current code is not wrong assignment (everything match respectively) but which decl becomes canonical. Function decl from module A became canonical but for lambda canonical decl is chosen from module B. It happens because of the order of loading template specialization. Lookup by name makes canonical decl for function tryTo from module thrift_cpp2_base.pcm (last module loaded). RedeclarableTemplateDecl::loadLazySpecializationsImpl gets the most recent decl from module thrift_cpp2_base.pcm but it loads specialization in direct order so specialization from the first module folly-conv.pcm are loaded before specialization from thrift_cpp2_base.pcm and thus via dependencies lambda from the wrong module became canonical. In the last version I changed order of specialization loading to match order of lookup by name. I'm not sure that it will solve all cases when canonical decl for lambda can be chosen from another module but it seems that it reduces such probability substantially because now it match the most frequent case lookup by name. I'm still testing my changes on bigger codebase but so far it seems that it doesn't regress anything and solves my test case.

It doesn't completely solve the issue because it might be other code paths that result making canonical decl in different order. Alternative solution is abandon lazy loading for function and load its internal lambda right after making any function canonical. I think it will negatively affect performance because more things will be loaded that can be avoided with current approach. WDYT?

@dmpolukhin dmpolukhin marked this pull request as ready for review August 20, 2024 11:52
@ChuanqiXu9
Copy link
Member

Thanks. So the problem is that, when we load a function Decl as a canonical decl, we may not load its corresponding lambda as the canonical decl in the context. Right?

And I still think the current solution doesn't handle the problem directly and I still feel it is somewhat tricky. Especially I had a patch to change the order of loading specializations (#83237).

And I am still slightly unclear about how we load the wrong lambda first. I mean, do we load the wrong lambda by loading the body of the wrong function? If yes, can we try to load the body of the canonical decl before loading the body of the function?

Another idea is what you described to load the body of the canonical decl eagerly. And it looks indeed not good. But we can do some pruning for it. e.g., we can record if its body contains a lambda and if its lambda has a capture to its local variables.

The first suggestion looks better if it is doable. The second one may be simpler and more stable but not the best for the performance.

@dmpolukhin
Copy link
Contributor Author

dmpolukhin commented Aug 21, 2024

And I am still slightly unclear about how we load the wrong lambda first.

Here is stack trace how decl from wrong module becomes canonical.

Full stack trace
frame #0: 0x000055555e651e29 clang`clang::ASTDeclReader::VisitCXXRecordDeclImpl(this=0x00007ffffffe0b70, D=0x0000555564f74508) at ASTReaderDecl.cpp:2244:17
frame #1: 0x000055555e699ff1 clang`clang::ASTDeclReader::VisitCXXRecordDecl(this=0x00007ffffffe0b70, D=0x0000555564f74508) at ASTReaderDecl.cpp:346:49
frame #2: 0x000055555e67c3c1 clang`clang::declvisitor::Base<std::add_pointer, clang::ASTDeclReader, void>::Visit(this=0x00007ffffffe0b70, D=0x0000555564f74508) at DeclNodes.inc:414:1
frame #3: 0x000055555e6466d4 clang`clang::ASTDeclReader::Visit(this=0x00007ffffffe0b70, D=0x0000555564f74508) at ASTReaderDecl.cpp:542:37
frame #4: 0x000055555e67b76f clang`clang::ASTReader::ReadDeclRecord(clang::GlobalDeclID)::$_2::operator()(this=0x00007ffffffe0720) const at ASTReaderDecl.cpp:4154:51
frame #5: 0x000055555e67b745 clang`void llvm::function_ref<void ()>::callback_fn<clang::ASTReader::ReadDeclRecord(clang::GlobalDeclID)::$_2>(callable=140737488226080) at STLFunctionalExtras.h:45:12
frame #6: 0x000055555b9904a9 clang`llvm::function_ref<void ()>::operator()(this=0x00007ffffffe05e0) const at STLFunctionalExtras.h:68:12
frame #7: 0x000055555e68ad7d clang`clang::runWithSufficientStackSpace(Diag=function_ref<void ()> @ 0x00007ffffffe05f0, Fn=function_ref<void ()> @ 0x00007ffffffe05e0) at Stack.h:46:7
frame #8: 0x000055555e67841e clang`clang::ASTReader::ReadDeclRecord(this=0x0000555564ee3040, ID=GlobalDeclID @ 0x00007ffffffe0e60) at ASTReaderDecl.cpp:4153:3
frame #9: 0x000055555e57e86a clang`clang::ASTReader::GetDecl(this=0x0000555564ee3040, ID=GlobalDeclID @ 0x00007ffffffe0ed0) at ASTReader.cpp:7898:5
frame #10: 0x000055555e5ae522 clang`clang::ASTReader::ReadDecl(this=0x0000555564ee3040, F=0x0000555564f1f9e0, R=0x00007ffffffe1098, I=0x00007ffffffe1090) at ASTReader.h:1979:12
frame #11: 0x000055555e5dff08 clang`clang::ASTRecordReader::readDecl(this=0x00007ffffffe1078) at ASTRecordReader.h:190:20
frame #12: 0x000055555e5dfe25 clang`clang::ASTRecordReader::readDeclRef(this=0x00007ffffffe1078) at ASTRecordReader.h:193:12
frame #13: 0x000055555e604c61 clang`clang::serialization::AbstractTypeReader<clang::ASTRecordReader>::readRecordType(this=0x00007ffffffe1020) at AbstractTypeReader.inc:714:47
frame #14: 0x000055555e5a6fe1 clang`clang::serialization::AbstractTypeReader<clang::ASTRecordReader>::read(this=0x00007ffffffe1020, kind=Record) at AbstractTypeReader.inc:112:14
frame #15: 0x000055555e58242a clang`clang::ASTReader::readTypeRecord(this=0x0000555564ee3040, ID=4294967408) at ASTReader.cpp:6780:21
frame #16: 0x000055555e57dd01 clang`clang::ASTReader::GetType(this=0x0000555564ee3040, ID=4294967408) at ASTReader.cpp:7499:26
frame #17: 0x000055555e584b75 clang`clang::ASTReader::getLocalType(this=0x0000555564ee3040, F=0x0000555564f1f9e0, LocalID=4152) at ASTReader.cpp:7513:10
frame #18: 0x000055555e5caa73 clang`clang::ASTReader::readType(this=0x0000555564ee3040, F=0x0000555564f1f9e0, Record=0x00007ffffffe37c8, Idx=0x00007ffffffe37c0) at ASTReader.h:1922:12
frame #19: 0x000055555e5a9618 clang`clang::ASTRecordReader::readType(this=0x00007ffffffe37a8) at ASTRecordReader.h:176:20
frame #20: 0x000055555e5a6bd5 clang`clang::ASTRecordReader::readQualType(this=0x00007ffffffe37a8) at ASTRecordReader.h:179:12
frame #21: 0x000055555e5a99b0 clang`clang::serialization::BasicReaderBase<clang::ASTRecordReader>::readTemplateArgument(this=0x00007ffffffe37a8) at AbstractBasicReader.inc:942:39
frame #22: 0x000055555e5af76b clang`clang::ASTRecordReader::readTemplateArgument(this=0x00007ffffffe37a8, Canonicalize=true) at ASTRecordReader.h:236:28
frame #23: 0x000055555e58bb46 clang`clang::ASTRecordReader::readTemplateArgumentList(this=0x00007ffffffe37a8, TemplArgs=0x00007ffffffe2f10, Canonicalize=true) at ASTReader.cpp:9313:25
frame #24: 0x000055555e648c29 clang`clang::ASTDeclReader::VisitFunctionDecl(this=0x00007ffffffe3750, FD=0x0000555564f70e38) at ASTReaderDecl.cpp:958:12
frame #25: 0x000055555e67c1ff clang`clang::declvisitor::Base<std::add_pointer, clang::ASTDeclReader, void>::Visit(this=0x00007ffffffe3750, D=0x0000555564f70e38) at DeclNodes.inc:238:1
frame #26: 0x000055555e6466d4 clang`clang::ASTDeclReader::Visit(this=0x00007ffffffe3750, D=0x0000555564f70e38) at ASTReaderDecl.cpp:542:37
frame #27: 0x000055555e67b76f clang`clang::ASTReader::ReadDeclRecord(clang::GlobalDeclID)::$_2::operator()(this=0x00007ffffffe3300) const at ASTReaderDecl.cpp:4154:51
frame #28: 0x000055555e67b745 clang`void llvm::function_ref<void ()>::callback_fn<clang::ASTReader::ReadDeclRecord(clang::GlobalDeclID)::$_2>(callable=140737488237312) at STLFunctionalExtras.h:45:12
frame #29: 0x000055555b9904a9 clang`llvm::function_ref<void ()>::operator()(this=0x00007ffffffe31c0) const at STLFunctionalExtras.h:68:12
frame #30: 0x000055555e68ad7d clang`clang::runWithSufficientStackSpace(Diag=function_ref<void ()> @ 0x00007ffffffe31d0, Fn=function_ref<void ()> @ 0x00007ffffffe31c0) at Stack.h:46:7
frame #31: 0x000055555e67841e clang`clang::ASTReader::ReadDeclRecord(this=0x0000555564ee3040, ID=GlobalDeclID @ 0x00007ffffffe3a40) at ASTReaderDecl.cpp:4153:3
frame #32: 0x000055555e57e86a clang`clang::ASTReader::GetDecl(this=0x0000555564ee3040, ID=GlobalDeclID @ 0x00007ffffffe3ab0) at ASTReader.cpp:7898:5
frame #33: 0x000055555e584d25 clang`clang::ASTReader::GetExternalDecl(this=0x0000555564ee3040, ID=GlobalDeclID @ 0x00007ffffffe3ae8) at ASTReader.cpp:7595:60
frame #34: 0x0000555563bac6bc clang`clang::RedeclarableTemplateDecl::loadLazySpecializationsImpl(this=0x0000555564f6dea8) const at DeclTemplate.cpp:353:42
frame #35: 0x0000555563bacb35 clang`clang::FunctionTemplateDecl::LoadLazySpecializations(this=0x0000555564f6dea8) const at DeclTemplate.cpp:444:3
frame #36: 0x0000555563bacb59 clang`clang::FunctionTemplateDecl::getSpecializations(this=0x0000555564f6dea8) const at DeclTemplate.cpp:449:3
frame #37: 0x0000555563bacb95 clang`clang::FunctionTemplateDecl::findSpecialization(this=0x0000555564f6dea8, Args=ArrayRef<clang::TemplateArgument> @ 0x00007ffffffe3bb0, InsertPos=0x00007ffffffe44b0) at DeclTemplate.cpp:456:33
frame #38: 0x0000555563167ec9 clang`clang::TemplateDeclInstantiator::VisitFunctionDecl(this=0x00007ffffffe46d8, D=0x0000555564f6e148, TemplateParams=0x0000000000000000, FunctionRewriteKind=None) at SemaTemplateInstantiateDecl.cpp:2106:27
frame #39: 0x0000555563170623 clang`clang::TemplateDeclInstantiator::VisitFunctionDecl(this=0x00007ffffffe46d8, D=0x0000555564f6e148) at SemaTemplateInstantiateDecl.cpp:3828:10
frame #40: 0x000055556314a6cb clang`clang::declvisitor::Base<std::add_pointer, clang::TemplateDeclInstantiator, clang::Decl*>::Visit(this=0x00007ffffffe46d8, D=0x0000555564f6e148) at DeclNodes.inc:238:1
frame #41: 0x00005555631e3094 clang`clang::Sema::SubstDecl(clang::Decl*, clang::DeclContext*, clang::MultiLevelTemplateArgumentList const&)::$_0::operator()(this=0x00007ffffffe4698) const at SemaTemplateInstantiateDecl.cpp:4099:27
frame #42: 0x00005555631e3065 clang`void llvm::function_ref<void ()>::callback_fn<clang::Sema::SubstDecl(clang::Decl*, clang::DeclContext*, clang::MultiLevelTemplateArgumentList const&)::$_0>(callable=140737488242328) at STLFunctionalExtras.h:45:12
frame #43: 0x000055555b9904a9 clang`llvm::function_ref<void ()>::operator()(this=0x00007ffffffe4600) const at STLFunctionalExtras.h:68:12
frame #44: 0x000055555e68ad7d clang`clang::runWithSufficientStackSpace(Diag=function_ref<void ()> @ 0x00007ffffffe4610, Fn=function_ref<void ()> @ 0x00007ffffffe4600) at Stack.h:46:7
frame #45: 0x0000555561a12ac0 clang`clang::Sema::runWithSufficientStackSpace(this=0x0000555564f38d00, Loc=(ID = 2147461292), Fn=function_ref<void ()> @ 0x00007ffffffe4668) at Sema.cpp:575:3
frame #46: 0x0000555563171987 clang`clang::Sema::SubstDecl(this=0x0000555564f38d00, D=0x0000555564f6e148, Owner=0x0000555564ee09f0, TemplateArgs=0x00007ffffffe4a50) at SemaTemplateInstantiateDecl.cpp:4098:3
frame #47: 0x0000555562eb8325 clang`clang::Sema::FinishTemplateArgumentDeduction(this=0x0000555564f38d00, FunctionTemplate=0x0000555564f6dea8, Deduced=0x00007ffffffe54f0, NumExplicitlySpecified=1, Specialization=0x00007ffffffe5840, Info=0x00007ffffffe5850, OriginalCallArgs=0x00007ffffffe5368, PartialOverloading=false, CheckNonDependent=function_ref<bool ()> @ 0x00007ffffffe4d50) at SemaTemplateDeduction.cpp:3882:7
frame #48: 0x0000555562fc11c9 clang`clang::Sema::DeduceTemplateArguments(clang::FunctionTemplateDecl*, clang::TemplateArgumentListInfo*, llvm::ArrayRef<clang::Expr*>, clang::FunctionDecl*&, clang::sema::TemplateDeductionInfo&, bool, bool, clang::QualType, clang::Expr::Classification, llvm::function_ref<bool (llvm::ArrayRef<clang::QualType>)>)::$_2::operator()(this=0x00007ffffffe4f70) const at SemaTemplateDeduction.cpp:4572:14
frame #49: 0x0000555562fc10e5 clang`void llvm::function_ref<void ()>::callback_fn<clang::Sema::DeduceTemplateArguments(clang::FunctionTemplateDecl*, clang::TemplateArgumentListInfo*, llvm::ArrayRef<clang::Expr*>, clang::FunctionDecl*&, clang::sema::TemplateDeductionInfo&, bool, bool, clang::QualType, clang::Expr::Classification, llvm::function_ref<bool (llvm::ArrayRef<clang::QualType>)>)::$_2>(callable=140737488244592) at STLFunctionalExtras.h:45:12
frame #50: 0x000055555b9904a9 clang`llvm::function_ref<void ()>::operator()(this=0x00007ffffffe4e50) const at STLFunctionalExtras.h:68:12
frame #51: 0x000055555e68ad7d clang`clang::runWithSufficientStackSpace(Diag=function_ref<void ()> @ 0x00007ffffffe4e60, Fn=function_ref<void ()> @ 0x00007ffffffe4e50) at Stack.h:46:7
frame #52: 0x0000555561a12ac0 clang`clang::Sema::runWithSufficientStackSpace(this=0x0000555564f38d00, Loc=(ID = 2147461369), Fn=function_ref<void ()> @ 0x00007ffffffe4eb8) at Sema.cpp:575:3
frame #53: 0x0000555562ebaa6b clang`clang::Sema::DeduceTemplateArguments(this=0x0000555564f38d00, FunctionTemplate=0x0000555564f6dea8, ExplicitTemplateArgs=0x00007ffffffe5c70, Args=ArrayRef<clang::Expr *> @ 0x00007ffffffe5670, Specialization=0x00007ffffffe5840, Info=0x00007ffffffe5850, PartialOverloading=false, AggregateDeductionCandidate=false, ObjectType=QualType @ 0x00007ffffffe5668, ObjectClassification=(Kind = 21845, Modifiable = 0), CheckNonDependent=function_ref<bool (llvm::ArrayRef<clang::QualType>)> @ 0x00007ffffffe56c8) at SemaTemplateDeduction.cpp:4571:3
frame #54: 0x0000555562be0db7 clang`clang::Sema::AddTemplateOverloadCandidate(this=0x0000555564f38d00, FunctionTemplate=0x0000555564f6dea8, FoundDecl=DeclAccessPair @ 0x00007ffffffe5a98, ExplicitTemplateArgs=0x00007ffffffe5c70, Args=ArrayRef<clang::Expr *> @ 0x00007ffffffe5a88, CandidateSet=0x00007ffffffe6088, SuppressUserConversions=false, PartialOverloading=false, AllowExplicit=true, IsADLCandidate=NotADL, PO=Normal, AggregateCandidateDeduction=false) at SemaOverload.cpp:7695:40
frame #55: 0x0000555562bf5221 clang`AddOverloadedCallCandidate(S=0x0000555564f38d00, FoundDecl=DeclAccessPair @ 0x00007ffffffe5be8, ExplicitTemplateArgs=0x00007ffffffe5c70, Args=ArrayRef<clang::Expr *> @ 0x00007ffffffe5bd8, CandidateSet=0x00007ffffffe6088, PartialOverloading=false, KnownValid=true) at SemaOverload.cpp:13506:7
frame #56: 0x0000555562bf4eb1 clang`clang::Sema::AddOverloadedCallCandidates(this=0x0000555564f38d00, ULE=0x0000555564f70658, Args=ArrayRef<clang::Expr *> @ 0x00007ffffffe5dc0, CandidateSet=0x00007ffffffe6088, PartialOverloading=false) at SemaOverload.cpp:13560:5
frame #57: 0x0000555562bf564e clang`clang::Sema::buildOverloadedCallSet(this=0x0000555564f38d00, S=0x0000000000000000, Fn=0x0000555564f70658, ULE=0x0000555564f70658, Args=clang::MultiExprArg @ 0x00007ffffffe5f38, RParenLoc=(ID = 2147461369), CandidateSet=0x00007ffffffe6088, Result=0x00007ffffffe6060) at SemaOverload.cpp:13866:3
frame #58: 0x0000555562bf5bb9 clang`clang::Sema::BuildOverloadedCallExpr(this=0x0000555564f38d00, S=0x0000000000000000, Fn=0x0000555564f70658, ULE=0x0000555564f70658, LParenLoc=(ID = 2147461369), Args=clang::MultiExprArg @ 0x00007ffffffe7ae0, RParenLoc=(ID = 2147461385), ExecConfig=0x0000000000000000, AllowTypoCorrection=true, CalleesAddressIsTaken=false) at SemaOverload.cpp:14074:7
frame #59: 0x000055556236593d clang`clang::Sema::BuildCallExpr(this=0x0000555564f38d00, Scope=0x0000000000000000, Fn=0x0000555564f70658, LParenLoc=(ID = 2147461369), ArgExprs=clang::MultiExprArg @ 0x00007ffffffe8058, RParenLoc=(ID = 2147461385), ExecConfig=0x0000000000000000, IsExecConfig=false, AllowRecovery=true) at SemaExpr.cpp:6476:16
frame #60: 0x000055556237ea9f clang`clang::Sema::ActOnCallExpr(this=0x0000555564f38d00, Scope=0x0000000000000000, Fn=0x0000555564f70658, LParenLoc=(ID = 2147461369), ArgExprs=clang::MultiExprArg @ 0x00007ffffffe81e0, RParenLoc=(ID = 2147461385), ExecConfig=0x0000000000000000) at SemaExpr.cpp:6362:7
frame #61: 0x000055556310a362 clang`clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::RebuildCallExpr(this=0x00007ffffffe91d0, Callee=0x0000555564f70658, LParenLoc=(ID = 2147461369), Args=clang::MultiExprArg @ 0x00007ffffffe8260, RParenLoc=(ID = 2147461385), ExecConfig=0x0000000000000000) at TreeTransform.h:2860:22
frame #62: 0x00005555630ebb32 clang`clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformCallExpr(this=0x00007ffffffe91d0, E=0x0000555564f6e340) at TreeTransform.h:12458:23
frame #63: 0x00005555630d9f70 clang`clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformExpr(this=0x00007ffffffe91d0, E=0x0000555564f6e340) at StmtNodes.inc:602:1
frame #64: 0x00005555631113e4 clang`clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformDecltypeType(this=0x00007ffffffe91d0, TLB=0x00007ffffffe9088, TL=DecltypeTypeLoc @ 0x00007ffffffe8888) at TreeTransform.h:6644:31
frame #65: 0x00005555630cfd1c clang`clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformType(this=0x00007ffffffe91d0, TLB=0x00007ffffffe9088, T=(Ty = 0x0000555564f6e3a0, Data = 0x0000555564f70640)) at TypeNodes.inc:39:1
frame #66: 0x00005555630cf30f clang`clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformType(this=0x00007ffffffe91d0, DI=0x0000555564f70638) at TreeTransform.h:5015:34
frame #67: 0x00005555630d0e64 clang`clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformType(this=0x00007ffffffe91d0, T=QualType @ 0x00007ffffffe9180) at TreeTransform.h:4994:40
frame #68: 0x00005555630d0d9f clang`clang::Sema::SubstType(this=0x0000555564f38d00, T=QualType @ 0x00007ffffffe9230, TemplateArgs=0x00007ffffffe9570, Loc=(ID = 2147461333), Entity=(Ptr = 93825254449080)) at SemaTemplateInstantiate.cpp:2849:23
frame #69: 0x0000555562eb792d clang`clang::Sema::SubstituteExplicitTemplateArguments(this=0x0000555564f38d00, FunctionTemplate=0x0000555564f6dbd8, ExplicitTemplateArgs=0x00007ffffffea830, Deduced=0x00007ffffffea0b0, ParamTypes=0x00007ffffffea060, FunctionType=0x0000000000000000, Info=0x00007ffffffea410) at SemaTemplateDeduction.cpp:3560:9
frame #70: 0x0000555562fc10be clang`clang::Sema::DeduceTemplateArguments(clang::FunctionTemplateDecl*, clang::TemplateArgumentListInfo*, llvm::ArrayRef<clang::Expr*>, clang::FunctionDecl*&, clang::sema::TemplateDeductionInfo&, bool, bool, clang::QualType, clang::Expr::Classification, llvm::function_ref<bool (llvm::ArrayRef<clang::QualType>)>)::$_0::operator()(this=0x00007ffffffea008) const at SemaTemplateDeduction.cpp:4405:16
frame #71: 0x0000555562fc1075 clang`void llvm::function_ref<void ()>::callback_fn<clang::Sema::DeduceTemplateArguments(clang::FunctionTemplateDecl*, clang::TemplateArgumentListInfo*, llvm::ArrayRef<clang::Expr*>, clang::FunctionDecl*&, clang::sema::TemplateDeductionInfo&, bool, bool, clang::QualType, clang::Expr::Classification, llvm::function_ref<bool (llvm::ArrayRef<clang::QualType>)>)::$_0>(callable=140737488265224) at STLFunctionalExtras.h:45:12
frame #72: 0x000055555b9904a9 clang`llvm::function_ref<void ()>::operator()(this=0x00007ffffffe9a10) const at STLFunctionalExtras.h:68:12
frame #73: 0x000055555e68ad7d clang`clang::runWithSufficientStackSpace(Diag=function_ref<void ()> @ 0x00007ffffffe9a20, Fn=function_ref<void ()> @ 0x00007ffffffe9a10) at Stack.h:46:7
frame #74: 0x0000555561a12ac0 clang`clang::Sema::runWithSufficientStackSpace(this=0x0000555564f38d00, Loc=(ID = 2147461519), Fn=function_ref<void ()> @ 0x00007ffffffe9a78) at Sema.cpp:575:3
frame #75: 0x0000555562eba143 clang`clang::Sema::DeduceTemplateArguments(this=0x0000555564f38d00, FunctionTemplate=0x0000555564f6dbd8, ExplicitTemplateArgs=0x00007ffffffea830, Args=ArrayRef<clang::Expr *> @ 0x00007ffffffea230, Specialization=0x00007ffffffea400, Info=0x00007ffffffea410, PartialOverloading=false, AggregateDeductionCandidate=false, ObjectType=QualType @ 0x00007ffffffea228, ObjectClassification=(Kind = 0, Modifiable = 0), CheckNonDependent=function_ref<bool (llvm::ArrayRef<clang::QualType>)> @ 0x00007ffffffea288) at SemaTemplateDeduction.cpp:4404:5
frame #76: 0x0000555562be0db7 clang`clang::Sema::AddTemplateOverloadCandidate(this=0x0000555564f38d00, FunctionTemplate=0x0000555564f6dbd8, FoundDecl=DeclAccessPair @ 0x00007ffffffea658, ExplicitTemplateArgs=0x00007ffffffea830, Args=ArrayRef<clang::Expr *> @ 0x00007ffffffea648, CandidateSet=0x00007ffffffeac48, SuppressUserConversions=false, PartialOverloading=false, AllowExplicit=true, IsADLCandidate=NotADL, PO=Normal, AggregateCandidateDeduction=false) at SemaOverload.cpp:7695:40
frame #77: 0x0000555562bf5221 clang`AddOverloadedCallCandidate(S=0x0000555564f38d00, FoundDecl=DeclAccessPair @ 0x00007ffffffea7a8, ExplicitTemplateArgs=0x00007ffffffea830, Args=ArrayRef<clang::Expr *> @ 0x00007ffffffea798, CandidateSet=0x00007ffffffeac48, PartialOverloading=false, KnownValid=true) at SemaOverload.cpp:13506:7
frame #78: 0x0000555562bf4eb1 clang`clang::Sema::AddOverloadedCallCandidates(this=0x0000555564f38d00, ULE=0x0000555564f6e880, Args=ArrayRef<clang::Expr *> @ 0x00007ffffffea980, CandidateSet=0x00007ffffffeac48, PartialOverloading=false) at SemaOverload.cpp:13560:5
frame #79: 0x0000555562bf564e clang`clang::Sema::buildOverloadedCallSet(this=0x0000555564f38d00, S=0x0000000000000000, Fn=0x0000555564f6e880, ULE=0x0000555564f6e880, Args=clang::MultiExprArg @ 0x00007ffffffeaaf8, RParenLoc=(ID = 2147461519), CandidateSet=0x00007ffffffeac48, Result=0x00007ffffffeac20) at SemaOverload.cpp:13866:3
frame #80: 0x0000555562bf5bb9 clang`clang::Sema::BuildOverloadedCallExpr(this=0x0000555564f38d00, S=0x0000000000000000, Fn=0x0000555564f6e880, ULE=0x0000555564f6e880, LParenLoc=(ID = 2147461519), Args=clang::MultiExprArg @ 0x00007ffffffec6a0, RParenLoc=(ID = 2147461535), ExecConfig=0x0000000000000000, AllowTypoCorrection=true, CalleesAddressIsTaken=false) at SemaOverload.cpp:14074:7
frame #81: 0x000055556236593d clang`clang::Sema::BuildCallExpr(this=0x0000555564f38d00, Scope=0x0000000000000000, Fn=0x0000555564f6e880, LParenLoc=(ID = 2147461519), ArgExprs=clang::MultiExprArg @ 0x00007ffffffecc18, RParenLoc=(ID = 2147461535), ExecConfig=0x0000000000000000, IsExecConfig=false, AllowRecovery=true) at SemaExpr.cpp:6476:16
frame #82: 0x000055556237ea9f clang`clang::Sema::ActOnCallExpr(this=0x0000555564f38d00, Scope=0x0000000000000000, Fn=0x0000555564f6e880, LParenLoc=(ID = 2147461519), ArgExprs=clang::MultiExprArg @ 0x00007ffffffecda0, RParenLoc=(ID = 2147461535), ExecConfig=0x0000000000000000) at SemaExpr.cpp:6362:7
frame #83: 0x000055556310a362 clang`clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::RebuildCallExpr(this=0x00007ffffffee338, Callee=0x0000555564f6e880, LParenLoc=(ID = 2147461519), Args=clang::MultiExprArg @ 0x00007ffffffece20, RParenLoc=(ID = 2147461535), ExecConfig=0x0000000000000000) at TreeTransform.h:2860:22
frame #84: 0x00005555630ebb32 clang`clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformCallExpr(this=0x00007ffffffee338, E=0x0000555564f6e478) at TreeTransform.h:12458:23
frame #85: 0x00005555630d9f70 clang`clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformExpr(this=0x00007ffffffee338, E=0x0000555564f6e478) at StmtNodes.inc:602:1
frame #86: 0x00005555631113e4 clang`clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformDecltypeType(this=0x00007ffffffee338, TLB=0x00007ffffffee2e0, TL=DecltypeTypeLoc @ 0x00007ffffffed448) at TreeTransform.h:6644:31
frame #87: 0x00005555630cfd1c clang`clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformType(this=0x00007ffffffee338, TLB=0x00007ffffffee2e0, T=(Ty = 0x0000555564f6e4d0, Data = 0x0000555564f6e578)) at TypeNodes.inc:39:1
frame #88: 0x000055556311de01 clang`clang::QualType clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformFunctionProtoType<clang::Sema::SubstFunctionDeclType(clang::TypeSourceInfo*, clang::MultiLevelTemplateArgumentList const&, clang::SourceLocation, clang::DeclarationName, clang::CXXRecordDecl*, clang::Qualifiers, bool)::$_0>(this=0x00007ffffffee338, TLB=0x00007ffffffee2e0, TL=FunctionProtoTypeLoc @ 0x00007ffffffee108, ThisContext=0x0000555564f6c570, ThisTypeQuals=(Mask = 0), TransformExceptionSpec=(unnamed class) @ 0x00007ffffffee0ff) at TreeTransform.h:6271:33
frame #89: 0x00005555630d13ec clang`clang::QualType (anonymous namespace)::TemplateInstantiator::TransformFunctionProtoType<clang::Sema::SubstFunctionDeclType(clang::TypeSourceInfo*, clang::MultiLevelTemplateArgumentList const&, clang::SourceLocation, clang::DeclarationName, clang::CXXRecordDecl*, clang::Qualifiers, bool)::$_0>(this=0x00007ffffffee338, TLB=0x00007ffffffee2e0, TL=FunctionProtoTypeLoc @ 0x00007ffffffee218, ThisContext=0x0000555564f6c570, ThisTypeQuals=(Mask = 0), TransformExceptionSpec=(unnamed class) @ 0x00007ffffffee20f) at SemaTemplateInstantiate.cpp:2409:21
frame #90: 0x00005555630d10a9 clang`clang::Sema::SubstFunctionDeclType(this=0x0000555564f38d00, T=0x0000555564f6e560, Args=0x00007ffffffefa50, Loc=(ID = 2147461488), Entity=(Ptr = 93825254448984), ThisContext=0x0000555564f6c570, ThisTypeQuals=(Mask = 0), EvaluateConstraints=false) at SemaTemplateInstantiate.cpp:2905:27
frame #91: 0x000055556316a2c5 clang`clang::TemplateDeclInstantiator::SubstFunctionType(this=0x00007ffffffef6c8, D=0x0000555564f6d340, Params=0x00007ffffffeef00) at SemaTemplateInstantiateDecl.cpp:4466:38
frame #92: 0x00005555631661fe clang`clang::TemplateDeclInstantiator::VisitCXXMethodDecl(this=0x00007ffffffef6c8, D=0x0000555564f6d340, TemplateParams=0x0000555564f6e760, FunctionRewriteKind=None) at SemaTemplateInstantiateDecl.cpp:2546:27
frame #93: 0x0000555563165afe clang`clang::TemplateDeclInstantiator::VisitFunctionTemplateDecl(this=0x00007ffffffef6c8, D=0x0000555564f6d198) at SemaTemplateInstantiateDecl.cpp:1933:47
frame #94: 0x000055556314a9f9 clang`clang::declvisitor::Base<std::add_pointer, clang::TemplateDeclInstantiator, clang::Decl*>::Visit(this=0x00007ffffffef6c8, D=0x0000555564f6d198) at DeclNodes.inc:518:1
frame #95: 0x00005555630d3b96 clang`clang::Sema::InstantiateClass(this=0x0000555564f38d00, PointOfInstantiation=(ID = 90), Instantiation=0x0000555564f6c570, Pattern=0x0000555564f4b348, TemplateArgs=0x00007ffffffefa50, TSK=TSK_ImplicitInstantiation, Complain=true) at SemaTemplateInstantiate.cpp:3522:36
frame #96: 0x00005555630d51e0 clang`clang::Sema::InstantiateClassTemplateSpecialization(this=0x0000555564f38d00, PointOfInstantiation=(ID = 90), ClassTemplateSpec=0x0000555564f6c570, TSK=TSK_ImplicitInstantiation, Complain=true) at SemaTemplateInstantiate.cpp:3969:10
frame #97: 0x00005555632a8f58 clang`clang::Sema::RequireCompleteTypeImpl(clang::SourceLocation, clang::QualType, clang::Sema::CompleteTypeKind, clang::Sema::TypeDiagnoser*)::$_0::operator()(this=0x00007ffffffefdc8) const at SemaType.cpp:9183:23
frame #98: 0x00005555632a8f05 clang`void llvm::function_ref<void ()>::callback_fn<clang::Sema::RequireCompleteTypeImpl(clang::SourceLocation, clang::QualType, clang::Sema::CompleteTypeKind, clang::Sema::TypeDiagnoser*)::$_0>(callable=140737488289224) at STLFunctionalExtras.h:45:12
frame #99: 0x000055555b9904a9 clang`llvm::function_ref<void ()>::operator()(this=0x00007ffffffefba0) const at STLFunctionalExtras.h:68:12
frame #100: 0x000055555e68ad7d clang`clang::runWithSufficientStackSpace(Diag=function_ref<void ()> @ 0x00007ffffffefbb0, Fn=function_ref<void ()> @ 0x00007ffffffefba0) at Stack.h:46:7
frame #101: 0x0000555561a12ac0 clang`clang::Sema::runWithSufficientStackSpace(this=0x0000555564f38d00, Loc=(ID = 90), Fn=function_ref<void ()> @ 0x00007ffffffefc08) at Sema.cpp:575:3
frame #102: 0x00005555632892b7 clang`clang::Sema::RequireCompleteTypeImpl(this=0x0000555564f38d00, Loc=(ID = 90), T=QualType @ 0x00007ffffffeff00, Kind=AcceptSizeless, Diagnoser=0x00007ffffffeffe8) at SemaType.cpp:9182:9
frame #103: 0x0000555563288b93 clang`clang::Sema::RequireCompleteType(this=0x0000555564f38d00, Loc=(ID = 90), T=QualType @ 0x00007ffffffeff60, Kind=AcceptSizeless, Diagnoser=0x00007ffffffeffe8) at SemaType.cpp:8908:7
frame #104: 0x0000555561bd4ade clang`clang::Sema::RequireCompleteType(this=0x0000555564f38d00, Loc=(ID = 90), T=QualType @ 0x00007ffffffeffa0, Diagnoser=0x00007ffffffeffe8) at Sema.h:14947:12
frame #105: 0x00005555623821ce clang`clang::Sema::CheckCallReturnType(this=0x0000555564f38d00, ReturnType=QualType @ 0x00007fffffff0020, Loc=(ID = 90), CE=0x0000555564f6cff8, FD=0x0000555564f6ce00) at SemaExpr.cpp:20030:7
frame #106: 0x0000555562380e07 clang`clang::Sema::BuildResolvedCallExpr(this=0x0000555564f38d00, Fn=0x0000555564f6cfe0, NDecl=0x0000555564f6ce00, LParenLoc=(ID = 112), Args=ArrayRef<clang::Expr *> @ 0x00007fffffff0b58, RParenLoc=(ID = 113), Config=0x0000000000000000, IsExecConfig=false, UsesADL=NotADL) at SemaExpr.cpp:6822:7
frame #107: 0x0000555562bf61aa clang`FinishOverloadedCallExpr(SemaRef=0x0000555564f38d00, S=0x0000555564f55fa0, Fn=0x0000555564f69b10, ULE=0x0000555564f69b10, LParenLoc=(ID = 112), Args=clang::MultiExprArg @ 0x00007fffffff1020, RParenLoc=(ID = 113), ExecConfig=0x0000000000000000, CandidateSet=0x00007fffffff1148, Best=0x00007fffffff1100, OverloadResult=OR_Success, AllowTypoCorrection=true) at SemaOverload.cpp:13962:20
frame #108: 0x0000555562bf5e95 clang`clang::Sema::BuildOverloadedCallExpr(this=0x0000555564f38d00, S=0x0000555564f55fa0, Fn=0x0000555564f69b10, ULE=0x0000555564f69b10, LParenLoc=(ID = 112), Args=clang::MultiExprArg @ 0x00007fffffff2ba0, RParenLoc=(ID = 113), ExecConfig=0x0000000000000000, AllowTypoCorrection=true, CalleesAddressIsTaken=false) at SemaOverload.cpp:14103:10
frame #109: 0x000055556236593d clang`clang::Sema::BuildCallExpr(this=0x0000555564f38d00, Scope=0x0000555564f55fa0, Fn=0x0000555564f69b10, LParenLoc=(ID = 112), ArgExprs=clang::MultiExprArg @ 0x00007fffffff3118, RParenLoc=(ID = 113), ExecConfig=0x0000000000000000, IsExecConfig=false, AllowRecovery=true) at SemaExpr.cpp:6476:16
frame #110: 0x000055556237ea9f clang`clang::Sema::ActOnCallExpr(this=0x0000555564f38d00, Scope=0x0000555564f55fa0, Fn=0x0000555564f69b10, LParenLoc=(ID = 112), ArgExprs=clang::MultiExprArg @ 0x00007fffffff32a0, RParenLoc=(ID = 113), ExecConfig=0x0000000000000000) at SemaExpr.cpp:6362:7
frame #111: 0x0000555561896acb clang`clang::Parser::ParsePostfixExpressionSuffix(this=0x0000555564f44790, LHS=(Value = 93825254464272)) at ParseExpr.cpp:2244:23
frame #112: 0x000055556189bf0c clang`clang::Parser::ParseCastExpression(this=0x0000555564f44790, ParseKind=AnyCastExpr, isAddressOfOperand=false, NotCastExpr=0x00007fffffff72a7, isTypeCast=NotTypeCast, isVectorLiteral=false, NotPrimaryExpression=0x0000000000000000) at ParseExpr.cpp:1946:9
frame #113: 0x0000555561894f39 clang`clang::Parser::ParseCastExpression(this=0x0000555564f44790, ParseKind=AnyCastExpr, isAddressOfOperand=false, isTypeCast=NotTypeCast, isVectorLiteral=false, NotPrimaryExpression=0x0000000000000000) at ParseExpr.cpp:712:20
frame #114: 0x0000555561893431 clang`clang::Parser::ParseAssignmentExpression(this=0x0000555564f44790, isTypeCast=NotTypeCast) at ParseExpr.cpp:182:20
frame #115: 0x00005555618932df clang`clang::Parser::ParseExpression(this=0x0000555564f44790, isTypeCast=NotTypeCast) at ParseExpr.cpp:133:18
frame #116: 0x000055556192f2b8 clang`clang::Parser::ParseExprStatement(this=0x0000555564f44790, StmtCtx=Compound) at ParseStmt.cpp:563:19
frame #117: 0x000055556192d5ea clang`clang::Parser::ParseStatementOrDeclarationAfterAttributes(this=0x0000555564f44790, Stmts=0x00007fffffff8240, StmtCtx=Compound, TrailingElseLoc=0x0000000000000000, CXX11Attrs=0x00007fffffff7cd8, GNUAttrs=0x00007fffffff7c48) at ParseStmt.cpp:292:14
frame #118: 0x000055556192cc5d clang`clang::Parser::ParseStatementOrDeclaration(this=0x0000555564f44790, Stmts=0x00007fffffff8240, StmtCtx=Compound, TrailingElseLoc=0x0000000000000000) at ParseStmt.cpp:124:20
frame #119: 0x0000555561935ef2 clang`clang::Parser::ParseCompoundStatementBody(this=0x0000555564f44790, isStmtExpr=false) at ParseStmt.cpp:1257:11
frame #120: 0x00005555619375e4 clang`clang::Parser::ParseFunctionStatementBody(this=0x0000555564f44790, Decl=0x0000555564f4abe8, BodyScope=0x00007fffffff86a0) at ParseStmt.cpp:2535:21
frame #121: 0x000055556185b880 clang`clang::Parser::ParseFunctionDefinition(this=0x0000555564f44790, D=0x00007fffffff90c0, TemplateInfo=0x00007fffffffa5a0, LateParsedAttrs=0x00007fffffff8f08) at Parser.cpp:1520:10
frame #122: 0x00005555619047a9 clang`clang::Parser::ParseDeclGroup(this=0x0000555564f44790, DS=0x00007fffffffa640, Context=File, Attrs=0x00007fffffffad78, TemplateInfo=0x00007fffffffa5a0, DeclEnd=0x0000000000000000, FRI=0x0000000000000000) at ParseDecl.cpp:2434:17
frame #123: 0x000055556185a637 clang`clang::Parser::ParseDeclOrFunctionDefInternal(this=0x0000555564f44790, Attrs=0x00007fffffffad78, DeclSpecAttrs=0x00007ffffffface8, DS=0x00007fffffffa640, AS=AS_none) at Parser.cpp:1244:10
frame #124: 0x0000555561859b2e clang`clang::Parser::ParseDeclarationOrFunctionDefinition(this=0x0000555564f44790, Attrs=0x00007fffffffad78, DeclSpecAttrs=0x00007ffffffface8, DS=0x0000000000000000, AS=AS_none) at Parser.cpp:1266:12
frame #125: 0x00005555618593b9 clang`clang::Parser::ParseExternalDeclaration(this=0x0000555564f44790, Attrs=0x00007fffffffad78, DeclSpecAttrs=0x00007ffffffface8, DS=0x0000000000000000) at Parser.cpp:1069:14
frame #126: 0x00005555618571fb clang`clang::Parser::ParseTopLevelDecl(this=0x0000555564f44790, Result=0x00007fffffffafb8, ImportState=0x00007fffffffafb4) at Parser.cpp:758:12
frame #127: 0x0000555561851e2c clang`clang::ParseAST(S=0x0000555564f38d00, PrintStats=false, SkipFunctionBodies=false) at ParseAST.cpp:171:20
frame #128: 0x000055555e2c5ee1 clang`clang::ASTFrontendAction::ExecuteAction(this=0x0000555564eb06d0) at FrontendAction.cpp:1192:3
frame #129: 0x000055555e2c58fc clang`clang::FrontendAction::Execute(this=0x0000555564eb06d0) at FrontendAction.cpp:1078:8
frame #130: 0x000055555e1de2e6 clang`clang::CompilerInstance::ExecuteAction(this=0x0000555564ea8a80, Act=0x0000555564eb06d0) at CompilerInstance.cpp:1061:33
frame #131: 0x000055555e4a3528 clang`clang::ExecuteCompilerInvocation(Clang=0x0000555564ea8a80) at ExecuteCompilerInvocation.cpp:280:25
frame #132: 0x000055555aec82e9 clang`cc1_main(Argv=ArrayRef<const char *> @ 0x00007fffffffba08, Argv0="llvm-project/build/bin/clang", MainAddr=0x000055555aeba5f0) at cc1_main.cpp:285:15
frame #133: 0x000055555aebbd32 clang`ExecuteCC1Tool(ArgV=0x00007fffffffcd18, ToolContext=0x00007fffffffd550) at driver.cpp:215:12
frame #134: 0x000055555aebaa9b clang`clang_main(Argc=12, Argv=0x00007fffffffd728, ToolContext=0x00007fffffffd550) at driver.cpp:256:12
frame #135: 0x000055555aeed535 clang`main(argc=12, argv=0x00007fffffffd728) at clang-driver.cpp:17:10
frame #136: 0x00007ffff7829590 libc.so.6`__libc_start_call_main + 128
frame #137: 0x00007ffff7829640 libc.so.6`__libc_start_main@@GLIBC_2.34 + 128
frame #138: 0x000055555aeba525 clang`_start + 37

Short version:

frame #0: clang::ASTDeclReader::VisitCXXRecordDeclImpl: reading CXXRecordDecl for lambda imported in ./folly-conv.h - will become canonical because it is the first decl seen
frame #24: clang::ASTDeclReader::VisitFunctionDecl: reading FunctionDecl template specialization of `__declval` for lambda imported in ./folly-conv.h
frame #34: RedeclarableTemplateDecl::loadLazySpecializationsImpl: load all specialization for `__declval` imported in ./thrift_cpp2_base.h
frame #55: AddOverloadedCallCandidate: call for `__declval` imported in ./thrift_cpp2_base.h
frame #77: AddOverloadedCallCandidate: call for `declval` imported in ./thrift_cpp2_base.h
frame #95: clang::Sema::InstantiateClass: instantiation of Expected<unsigned int, const char *> member thenOrThrow
frame #107: FinishOverloadedCallExpr call tryTo<unsigned int> template function imported in ./thrift_cpp2_base.h

My testing on real code showed that reverting the order of loading specialization is not enough if instead of two modules there are much more modules. Therefore I'm keep working on a solution that works on real example with many modules.

@dmpolukhin dmpolukhin marked this pull request as draft August 21, 2024 19:56
@dmpolukhin
Copy link
Contributor Author

@ChuanqiXu9 please take another look. I changed approach to remember which lambdas exist in FunctionDecl and load them for the first decl. I'm still testing it but interested to know does it look like something that address your concernes?

@ChuanqiXu9
Copy link
Member

Yeah, while the implementation need to be polished, the shape is what I want.

@dmpolukhin
Copy link
Contributor Author

Quick update, all clang/cxx-library tests pass with the change but when I test it on my real project with modules I see crash or assert in ASTDeclMerger::MergeDefinitionData about faked lambda. I'm still creating small reproducer but it looks like it happens when lambda is inside class member function + some other conditions that I don't understand yet.

@ChuanqiXu9
Copy link
Member

Quick update, all clang/cxx-library tests pass with the change but when I test it on my real project with modules I see crash or assert in ASTDeclMerger::MergeDefinitionData about faked lambda. I'm still creating small reproducer but it looks like it happens when lambda is inside class member function + some other conditions that I don't understand yet.

Thanks. And I am curious about your real project, is it open source?

@dmpolukhin dmpolukhin force-pushed the assert-not-instantiated-in-scope-cxx-modules branch from d7db624 to 90de760 Compare September 2, 2024 14:52
@dmpolukhin
Copy link
Contributor Author

I am curious about your real project, is it open source?

Unfortunately, it is not an open source project but we use bunch of OSS libraries like Folly, Thrift and many other so I see bugs that cannot be easily minimized and reproduced. I added test-case for the crash I observe (now asserts happens in different place but it is the same root cause that I changed order of lambda deserialization). I'm still working on a fix.

@ChuanqiXu9
Copy link
Member

I am curious about your real project, is it open source?

Unfortunately, it is not an open source project but we use bunch of OSS libraries like Folly, Thrift and many other so I see bugs that cannot be easily minimized and reproduced. I added test-case for the crash I observe (now asserts happens in different place but it is the same root cause that I changed order of lambda deserialization). I'm still working on a fix.

Got it. I am pretty interested use case for modules. And from your commit history, it looks like you prefer header units than named modules?

@dmpolukhin
Copy link
Contributor Author

Got it. I am pretty interested use case for modules. And from your commit history, it looks like you prefer header units than named modules?

Yes, we prefer header units for the time being because it can be implemented with minimal sources changes and gives moderate compile time improvements. Also it should open future path to named modules. Also with header units we have some flexibility how to compose modules. In our experiments build time perforce significantly depends on number of modules required for compilation number of AST nodes that are merged.

@ChuanqiXu9
Copy link
Member

Got it. I am pretty interested use case for modules. And from your commit history, it looks like you prefer header units than named modules?

Yes, we prefer header units for the time being because it can be implemented with minimal sources changes and gives moderate compile time improvements. Also it should open future path to named modules. Also with header units we have some flexibility how to compose modules. In our experiments build time perforce significantly depends on number of modules required for compilation number of AST nodes that are merged.

Got it. Looking for your public reports : )

…d from different modules

Summary:
Because AST loading code is lazy and happens in unpredictable order it could happen that function and lambda inside function can be loaded from different modules. In this case, captured DeclRefExpr won’t match the corresponding VarDecl inside function. In AST it looks like this:
```
FunctionDecl 0x555564f4aff0 <Conv.h:33:1, line:41:1> line:33:35 imported in ./thrift_cpp2_base.h hidden tryTo 'Expected<Tgt, const char *> ()' inline
|-also in ./folly-conv.h
`-CompoundStmt 0x555564f7cfc8 <col:43, line:41:1>
  |-DeclStmt 0x555564f7ced8 <line:34:3, col:17>
  | `-VarDecl 0x555564f7cef8 <col:3, col:16> col:7 imported in ./thrift_cpp2_base.h hidden referenced result 'Tgt' cinit
  |   `-IntegerLiteral 0x555564f7d080 <col:16> 'int' 0
  |-CallExpr 0x555564f7cea8 <line:39:3, col:76> '<dependent type>'
  | |-UnresolvedLookupExpr 0x555564f7bea0 <col:3, col:19> '<overloaded function type>' lvalue (no ADL) = 'then_' 0x555564f7bef0
  | |-CXXTemporaryObjectExpr 0x555564f7bcb0 <col:25, col:45> 'Expected<bool, int>':'folly::Expected<bool, int>' 'void () noexcept' zeroing
  | `-LambdaExpr 0x555564f7bc88 <col:48, col:75> '(lambda at Conv.h:39:48)'
  |   |-CXXRecordDecl 0x555564f76b88 <col:48> col:48 imported in ./folly-conv.h hidden implicit <undeserialized declarations> class definition
  |   | |-also in ./thrift_cpp2_base.h
  |   | `-DefinitionData lambda empty standard_layout trivially_copyable literal can_const_default_init
  |   |   |-DefaultConstructor defaulted_is_constexpr
  |   |   |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
  |   |   |-MoveConstructor exists simple trivial needs_implicit
  |   |   |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
  |   |   |-MoveAssignment
  |   |   `-Destructor simple irrelevant trivial constexpr needs_implicit
  |   `-CompoundStmt 0x555564f7d1a8 <col:58, col:75>
  |     `-ReturnStmt 0x555564f7d198 <col:60, col:67>
  |       `-DeclRefExpr 0x555564f7d0a0 <col:67> 'Tgt' lvalue Var 0x555564f7d0c8 'result' 'Tgt' refers_to_enclosing_variable_or_capture
  `-ReturnStmt 0x555564f7bc78 <line:40:3, col:11>
    `-InitListExpr 0x555564f7bc38 <col:10, col:11> 'void'
```
I’m not sure that it is the right fix for the problem so any ideas how to fix it better are very appreciated.

Test Plan: check-clang
…d from different modules

Summary:
Because AST loading code is lazy and happens in unpredictable order it could happen that function and lambda inside function can be loaded from different modules. In this case, captured DeclRefExpr won’t match the corresponding VarDecl inside function. In AST it looks like this:
```
FunctionDecl 0x555564f4aff0 <Conv.h:33:1, line:41:1> line:33:35 imported in ./thrift_cpp2_base.h hidden tryTo 'Expected<Tgt, const char *> ()' inline
|-also in ./folly-conv.h
`-CompoundStmt 0x555564f7cfc8 <col:43, line:41:1>
  |-DeclStmt 0x555564f7ced8 <line:34:3, col:17>
  | `-VarDecl 0x555564f7cef8 <col:3, col:16> col:7 imported in ./thrift_cpp2_base.h hidden referenced result 'Tgt' cinit
  |   `-IntegerLiteral 0x555564f7d080 <col:16> 'int' 0
  |-CallExpr 0x555564f7cea8 <line:39:3, col:76> '<dependent type>'
  | |-UnresolvedLookupExpr 0x555564f7bea0 <col:3, col:19> '<overloaded function type>' lvalue (no ADL) = 'then_' 0x555564f7bef0
  | |-CXXTemporaryObjectExpr 0x555564f7bcb0 <col:25, col:45> 'Expected<bool, int>':'folly::Expected<bool, int>' 'void () noexcept' zeroing
  | `-LambdaExpr 0x555564f7bc88 <col:48, col:75> '(lambda at Conv.h:39:48)'
  |   |-CXXRecordDecl 0x555564f76b88 <col:48> col:48 imported in ./folly-conv.h hidden implicit <undeserialized declarations> class definition
  |   | |-also in ./thrift_cpp2_base.h
  |   | `-DefinitionData lambda empty standard_layout trivially_copyable literal can_const_default_init
  |   |   |-DefaultConstructor defaulted_is_constexpr
  |   |   |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
  |   |   |-MoveConstructor exists simple trivial needs_implicit
  |   |   |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
  |   |   |-MoveAssignment
  |   |   `-Destructor simple irrelevant trivial constexpr needs_implicit
  |   `-CompoundStmt 0x555564f7d1a8 <col:58, col:75>
  |     `-ReturnStmt 0x555564f7d198 <col:60, col:67>
  |       `-DeclRefExpr 0x555564f7d0a0 <col:67> 'Tgt' lvalue Var 0x555564f7d0c8 'result' 'Tgt' refers_to_enclosing_variable_or_capture
  `-ReturnStmt 0x555564f7bc78 <line:40:3, col:11>
    `-InitListExpr 0x555564f7bc38 <col:10, col:11> 'void'
```
I’m not sure that it is the right fix for the problem so any ideas how to fix it better are very appreciated.

Test Plan: check-clang
kyulee-com and others added 4 commits September 6, 2024 02:03
This fixes a build break from [llvm/llvm-project] Reland [CGData]
llvm-cgdata llvm#89884 (PR llvm#101461)
Add missing dependency that sometimes makes a build fails with ninja.
This fixes a build break from [llvm/llvm-project] Reland [CGData]
llvm-cgdata llvm#89884 (PR llvm#101461)
@dmpolukhin dmpolukhin force-pushed the assert-not-instantiated-in-scope-cxx-modules branch from 90de760 to b5f6a30 Compare September 6, 2024 09:50
@dmpolukhin dmpolukhin marked this pull request as ready for review September 6, 2024 09:51
@dmpolukhin
Copy link
Contributor Author

@ChuanqiXu9 please take a look, I had to load lambdas delayed to avoid bad cycles when current function was not fully deserialized yet but lambda inside reference it. Now this change fixes my original issue and doesn't introduce any new crashes on our codebase so it is step forward. Unfortunately it seems that it doesn't fix all lambda related issues but I need to reduce them and fix.

Comment on lines 1192 to 1193
/// It is required to have the right canonical declaration for lambda class
/// from the same module as the function.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe it is better to expand this statement as we did in this patch. So that other readers can have a better understanding for it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

for (unsigned I = 0; I != NumLambdas; ++I)
Reader.PendingLambdas.push_back(Record.readDeclID());
} else {
(void)Record.readIntArray(NumLambdas);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: skipInts might be better API here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thank for the suggestion, I missed this function.

Comment on lines 799 to 802
llvm::SmallVector<const Decl *, 2> Lambdas = collectLambdas(D);
Record.push_back(Lambdas.size());
for (const auto *L : Lambdas)
Record.AddDeclRef(L);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it good to only do this for the first decl?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems that doing it only for canonical is good enough, at least I don't see other examples.

Comment on lines 799 to 802
llvm::SmallVector<const Decl *, 2> Lambdas = collectLambdas(D);
Record.push_back(Lambdas.size());
for (const auto *L : Lambdas)
Record.AddDeclRef(L);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also probably we need to update the abbreviation. You need to look at DeclCXXMethodAbbrev and getFunctionDeclAbbrev.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems that it is not required but added comment there to clarify it.

Copy link
Member

@ChuanqiXu9 ChuanqiXu9 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@dmpolukhin dmpolukhin merged commit d778689 into llvm:main Sep 10, 2024
8 checks passed
@dmpolukhin
Copy link
Contributor Author

@ChuanqiXu9 thank you a lot for the review and help with the changes, very appreciated!

@dmpolukhin dmpolukhin deleted the assert-not-instantiated-in-scope-cxx-modules branch September 11, 2024 09:00
@aeubanks
Copy link
Contributor

this is causing a crash with precompiled headers. I can try to reduce, but hopefully the problem is obvious from this assert/stack trace?

clang++: ../../llvm/include/llvm/ADT/SmallVector.h:295: const_reference llvm::SmallVectorTemplateCommon<std::unique_ptr<clang::serialization::ModuleFile>>::operator[](size_type) const [T = std::unique_ptr<clang::serialization::ModuleFile>]: Assertion `idx < size()' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.	Program arguments: ../../../../llvm-project/build/rel/bin/clang++ -MMD -MF obj/third_party/blink/renderer/core/probe/instrumentation_probes/core_probes_impl.o.d -DDCHECK_ALWAYS_ON=1 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D_FORTIFY_SOURCE=2 -DCR_XCODE_VERSION=1500 -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE -DCOMPONENT_BUILD -DCR_LIBCXX_REVISION=6ae6f38d10eda881c16d91932348fc6d4ee98332 -DTEMP_REBUILD_HACK -DNDEBUG -DNVALGRIND -DDYNAMIC_ANNOTATIONS_ENABLED=0 -DBLINK_CORE_IMPLEMENTATION=1 -DSK_ENABLE_SKSL -DSK_UNTIL_CRBUG_1187654_IS_FIXED -DSK_USER_CONFIG_HEADER=\"../../skia/config/SkUserConfig.h\" -DSK_WIN_FONTMGR_NO_SIMULATIONS -DSK_DISABLE_LEGACY_INIT_DECODERS -DSK_DISABLE_LEGACY_BACKEND_TEXTURE_FUNCS -DSK_DISABLE_LEGACY_TEXTURE_INFO_FUNCS -DSK_DISABLE_LEGACY_BACKEND_SEMAPHORE_FUNCS -DSK_DISABLE_LEGACY_GRAPHITE_IMAGES -DSK_DISABLE_LEGACY_DAWN_TEXTURE_INFO_FUNCS -DSK_DISABLE_LEGACY_DAWN_BACKEND_TEXTURE_FUNCS -DSK_CODEC_DECODES_JPEG -DSK_ENCODE_JPEG -DSK_ENCODE_PNG -DSK_ENCODE_WEBP -DSKIA_DLL -DSKCMS_API=__attribute__((visibility(\"default\"))) -DSK_BUILD_FOR_MAC -DSK_GANESH -DSK_GPU_WORKAROUNDS_HEADER=\"gpu/config/gpu_driver_bug_workaround_autogen.h\" -DSK_GL -DSK_GRAPHITE -DSK_DAWN -DSK_METAL -DCHROMIUM -DLIBYUV_DISABLE_NEON -DLIBYUV_DISABLE_SVE -DLIBYUV_DISABLE_SME -DLIBYUV_DISABLE_LSX -DLIBYUV_DISABLE_LASX -DBLINK_IMPLEMENTATION=1 -DINSIDE_BLINK -DABSL_CONSUME_DLL -DABSL_FLAGS_STRIP_NAMES=0 -DCR_CXX_INCLUDE=\"third_party/rust/chromium_crates_io/vendor/cxx-1.0.128/include/cxx.h\" -DBORINGSSL_SHARED_LIBRARY -DU_USING_ICU_NAMESPACE=0 -DU_ENABLE_DYLOAD=0 -DUSE_CHROMIUM_ICU=1 -DU_ENABLE_TRACING=1 -DU_ENABLE_RESOURCE_TRACING=0 -DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_FILE -DGOOGLE_PROTOBUF_NO_RTTI -DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER -DGOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE=0 -DHAVE_PTHREAD -DPROTOBUF_USE_DLLS -DWEBRTC_ENABLE_SYMBOL_EXPORT -DWEBRTC_ENABLE_AVX2 -DWEBRTC_CHROMIUM_BUILD -DWEBRTC_POSIX -DWEBRTC_MAC -DABSL_ALLOCATOR_NOTHROW=1 -DLOGGING_INSIDE_WEBRTC -DWGPU_SHARED_LIBRARY -DUSING_V8_SHARED -DUSING_V8_SHARED_PRIVATE -DV8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT=0 -DV8_ARRAY_BUFFER_VIEW_INTERNAL_FIELD_COUNT=0 -DV8_PROMISE_INTERNAL_FIELD_COUNT=0 -DV8_COMPRESS_POINTERS -DV8_COMPRESS_POINTERS_IN_SHARED_CAGE -DV8_31BIT_SMIS_ON_64BIT_ARCH -DV8_ENABLE_SANDBOX -DV8_DEPRECATION_WARNINGS -DV8_USE_PERFETTO -DV8_HAVE_TARGET_OS -DV8_TARGET_OS_MACOS -DCPPGC_CAGED_HEAP -DCPPGC_YOUNG_GENERATION -DCPPGC_POINTER_COMPRESSION -DCPPGC_ENABLE_LARGER_CAGE -DCPPGC_SLIM_WRITE_BARRIER -DLEVELDB_PLATFORM_CHROMIUM=1 -DLEVELDB_SHARED_LIBRARY -DCRASHPAD_ZLIB_SOURCE_EXTERNAL -DUSE_LIBJPEG_TURBO=1 -DMANGLE_JPEG_NAMES -DWEBP_EXTERN=extern -DUSING_V8_BASE_SHARED -DUSING_V8_PLATFORM_SHARED -DLIBXSLT_STATIC -I../.. -Igen -I../../buildtools/third_party/libc++ -I../../third_party/perfetto/include -Igen/third_party/perfetto/build_config -Igen/third_party/perfetto -I../../third_party/skia -Igen/third_party/skia -I../../third_party/wuffs/src/release/c -Igen/third_party/dawn/include -I../../third_party/dawn/include -I../../third_party/khronos -I../../gpu -I../../net/third_party/quiche/overrides -I../../net/third_party/quiche/src/quiche/common/platform/default -I../../net/third_party/quiche/src -I../../third_party/libyuv/include -I../../base/allocator/partition_allocator/src -Igen/base/allocator/partition_allocator/src -I../../third_party/abseil-cpp -I../../third_party/boringssl/src/include -I../../third_party/protobuf/src -Igen/protoc_out -I../../third_party/ipcz/include -I../../third_party/ced/src -I../../third_party/icu/source/common -I../../third_party/icu/source/i18n -Igen/net/third_party/quiche/src -I../../third_party/webrtc_overrides -I../../third_party/webrtc -Igen/third_party/webrtc -I../../v8/include -I../../third_party/libwebm/source -I../../third_party/angle/include -I../../third_party/mesa_headers -I../../third_party/leveldatabase -I../../third_party/leveldatabase/src -I../../third_party/leveldatabase/src/include -I../../third_party/crashpad/crashpad -I../../third_party/crashpad/crashpad/compat/mac -I../../third_party/crashpad/crashpad/compat/non_win -I../../third_party/zlib -I../../third_party/libaom/source/libaom -I../../third_party/libaom/source/config/linux/x64 -I../../third_party/libjpeg_turbo -I../../third_party/libpng -I../../third_party/libwebp/src/src -I../../third_party/ots/src/include -Igen/v8/include -I../../third_party/fp16/src/include -I../../third_party/libxml/src/include -I../../third_party/libxml/mac/include -I../../third_party/libxslt/src -Wall -Wextra -Wimplicit-fallthrough -Wextra-semi -Wunreachable-code-aggressive -Wthread-safety -Wunguarded-availability -Wno-missing-field-initializers -Wno-unused-parameter -Wno-psabi -Wloop-analysis -Wno-unneeded-internal-declaration -Wno-cast-function-type -Wno-deprecated-this-capture -Wno-vla-extension -Wno-thread-safety-reference-return -Wshadow -fno-delete-null-pointer-checks -fno-ident -fno-strict-aliasing -fstack-protector -femit-dwarf-unwind=no-compact-unwind -fcolor-diagnostics -fmerge-all-constants -fno-sized-deallocation -fcrash-diagnostics-dir=../../tools/clang/crashreports -mllvm -instcombine-lower-dbg-declare=0 -mllvm -split-threshold-for-reg-with-hint=0 -ffp-contract=off -fcomplete-member-pointers --target=x86_64-apple-macos -Wno-builtin-macro-redefined -D__DATE__= -D__TIME__= -D__TIMESTAMP__= -ffile-compilation-dir=. -no-canonical-prefixes -ftrivial-auto-var-init=pattern -fno-omit-frame-pointer -isysroot ../../build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk -mmacos-version-min=11.0 -fvisibility=hidden -Wheader-hygiene -Wstring-conversion -Wtautological-overlap-compare -Wexit-time-destructors -Wglobal-constructors -O2 -fno-math-errno -gdwarf-4 -g1 -gdwarf-aranges -Wconversion -Wno-float-conversion -Wno-sign-conversion -Wno-implicit-float-conversion -Wno-implicit-int-conversion -DPROTOBUF_ALLOW_DEPRECATED=1 -DLIBXML_STATIC= -Wno-invalid-offsetof -Wenum-compare-conditional -Wno-c++11-narrowing-const-reference -Wno-missing-template-arg-list-after-template-kw -Wno-dangling-assignment-gsl -std=c++20 -Wno-trigraphs -fno-exceptions -fno-rtti -nostdinc++ -isystem../../third_party/libc++/src/include -isystem../../third_party/libc++abi/src/include -fvisibility-inlines-hidden -include obj/third_party/blink/renderer/core/probe/instrumentation_probes/precompile_core.h-cc -c gen/third_party/blink/renderer/core/core_probes_impl.cc -o obj/third_party/blink/renderer/core/probe/instrumentation_probes/core_probes_impl.o
1.	../../third_party/blink/renderer/core/layout/layout_box.h:1471:2: current parser token ';'
2.	../../third_party/blink/renderer/core/layout/layout_box.h:51:1: parsing namespace 'blink'
3.	../../third_party/blink/renderer/core/layout/layout_box.h:205:1: parsing struct/union/class body 'blink::LayoutBox'
 #0 0x0000558776cc7588 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../llvm/lib/Support/Unix/Signals.inc:723:13
 #1 0x0000558776cc51ce llvm::sys::RunSignalHandlers() /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../llvm/lib/Support/Signals.cpp:106:18
 #2 0x0000558776c42cd6 HandleCrash /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../llvm/lib/Support/CrashRecoveryContext.cpp:73:5
 #3 0x0000558776c42cd6 CrashRecoverySignalHandler(int) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../llvm/lib/Support/CrashRecoveryContext.cpp:390:51
 #4 0x00007fa1cc0591a0 (/lib/x86_64-linux-gnu/libc.so.6+0x3d1a0)
 #5 0x00007fa1cc0a70ec __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #6 0x00007fa1cc059102 gsignal ./signal/../sysdeps/posix/raise.c:27:6
 #7 0x00007fa1cc0424f2 abort ./stdlib/abort.c:81:7
 #8 0x00007fa1cc042415 _nl_load_domain ./intl/loadmsgcat.c:1177:9
 #9 0x00007fa1cc051d32 (/lib/x86_64-linux-gnu/libc.so.6+0x35d32)
#10 0x0000558778c53b02 translateGlobalDeclIDToIndex /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Serialization/ASTReader.cpp:7916:5
#11 0x0000558778c53b02 clang::ASTReader::GetDecl(clang::GlobalDeclID) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Serialization/ASTReader.cpp:7953:20
#12 0x0000558778c6605c clang::ASTReader::finishPendingActions() /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Serialization/ASTReader.cpp:9933:18
#13 0x0000558778c6a39b clang::ASTReader::FinishedDeserializing() /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Serialization/ASTReader.cpp:10406:3
#14 0x00005587776c8c9a clang::DeclContext::LoadLexicalDeclsFromExternalStorage() const /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/AST/DeclBase.cpp:1589:1
#15 0x00005587776c8f52 clang::DeclContext::decls_begin() const /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/AST/DeclBase.cpp:1625:24
#16 0x00005587776993fd SkipToNextDecl /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/include/clang/AST/DeclBase.h:2380:14
#17 0x00005587776993fd specific_decl_iterator /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/include/clang/AST/DeclBase.h:2405:7
#18 0x00005587776993fd method_begin /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/include/clang/AST/DeclCXX.h:669:12
#19 0x00005587776993fd methods /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/include/clang/AST/DeclCXX.h:663:25
#20 0x00005587776993fd (anonymous namespace)::FinalOverriderCollector::Collect(clang::CXXRecordDecl const*, bool, clang::CXXRecordDecl const*, clang::CXXFinalOverriderMap&) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/AST/CXXInheritance.cpp:568:22
#21 0x0000558777699162 (anonymous namespace)::FinalOverriderCollector::Collect(clang::CXXRecordDecl const*, bool, clang::CXXRecordDecl const*, clang::CXXFinalOverriderMap&) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/AST/CXXInheritance.cpp:530:9
#22 0x0000558777699162 (anonymous namespace)::FinalOverriderCollector::Collect(clang::CXXRecordDecl const*, bool, clang::CXXRecordDecl const*, clang::CXXFinalOverriderMap&) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/AST/CXXInheritance.cpp:530:9
#23 0x000055877769857f size /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../llvm/include/llvm/ADT/SmallVector.h:78:32
#24 0x000055877769857f end /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../llvm/include/llvm/ADT/SmallVector.h:269:37
#25 0x000055877769857f end /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../llvm/include/llvm/ADT/MapVector.h:71:34
#26 0x000055877769857f clang::CXXRecordDecl::getFinalOverriders(clang::CXXFinalOverriderMap&) const /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/AST/CXXInheritance.cpp:649:17
#27 0x00005587776d6006 hasPureVirtualFinalOverrider(clang::CXXRecordDecl const&, clang::CXXFinalOverriderMap const*) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/AST/DeclCXX.cpp:2118:12
#28 0x00005587776d5c9a clang::CXXRecordDecl::completeDefinition(clang::CXXFinalOverriderMap*) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/AST/DeclCXX.cpp:2144:7
#29 0x00005587782e1189 clang::Sema::ActOnFields(clang::Scope*, clang::SourceLocation, clang::Decl*, llvm::ArrayRef<clang::Decl*>, clang::SourceLocation, clang::SourceLocation, clang::ParsedAttributesView const&) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Sema/SemaDecl.cpp:0:15
#30 0x00005587783f0a96 clang::Sema::ActOnFinishCXXMemberSpecification(clang::Scope*, clang::SourceLocation, clang::Decl*, clang::SourceLocation, clang::SourceLocation, clang::ParsedAttributesView const&) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Sema/SemaDeclCXX.cpp:10463:3
#31 0x0000558777e787c4 clang::Parser::ParseCXXMemberSpecification(clang::SourceLocation, clang::SourceLocation, clang::ParsedAttributes&, unsigned int, clang::Decl*) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Parse/ParseDeclCXX.cpp:3966:7
#32 0x0000558777e761eb clang::Parser::ParseClassSpecifier(clang::tok::TokenKind, clang::SourceLocation, clang::DeclSpec&, clang::Parser::ParsedTemplateInfo&, clang::AccessSpecifier, bool, clang::Parser::DeclSpecContext, clang::ParsedAttributes&) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Parse/ParseDeclCXX.cpp:0:7
#33 0x0000558777e9def5 empty /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../llvm/include/llvm/ADT/SmallVector.h:81:46
#34 0x0000558777e9def5 empty /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/include/clang/Sema/ParsedAttr.h:843:40
#35 0x0000558777e9def5 clang::Parser::ParseDeclarationSpecifiers(clang::DeclSpec&, clang::Parser::ParsedTemplateInfo&, clang::AccessSpecifier, clang::Parser::DeclSpecContext, clang::Parser::LateParsedAttrList*, clang::ImplicitTypenameContext) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Parse/ParseDecl.cpp:4701:23
#36 0x0000558777e17858 clang::Parser::ParseDeclOrFunctionDefInternal(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec&, clang::AccessSpecifier) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Parse/Parser.cpp:1153:10
#37 0x0000558777e17486 clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*, clang::AccessSpecifier) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Parse/Parser.cpp:1266:12
#38 0x0000558777e163ac clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Parse/Parser.cpp:0:14
#39 0x0000558777e6b87f ~AttributePool /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/include/clang/Sema/ParsedAttr.h:726:22
#40 0x0000558777e6b87f ~ParsedAttributes /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/include/clang/Sema/ParsedAttr.h:958:7
#41 0x0000558777e6b87f clang::Parser::ParseInnerNamespace(llvm::SmallVector<clang::Parser::InnerNamespaceInfo, 4u> const&, unsigned int, clang::SourceLocation&, clang::ParsedAttributes&, clang::BalancedDelimiterTracker&) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Parse/ParseDeclCXX.cpp:273:5
#42 0x0000558777e6aa2d Exit /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/include/clang/Parse/Parser.h:1197:15
#43 0x0000558777e6aa2d clang::Parser::ParseNamespace(clang::DeclaratorContext, clang::SourceLocation&, clang::SourceLocation) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Parse/ParseDeclCXX.cpp:252:18
#44 0x0000558777e976b8 ObjCDeclContextSwitch /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/include/clang/Parse/Parser.h:1093:11
#45 0x0000558777e976b8 clang::Parser::ParseDeclaration(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::ParsedAttributes&, clang::SourceLocation*) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Parse/ParseDecl.cpp:2049:25
#46 0x0000558777e15fbd clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Parse/Parser.cpp:0:0
#47 0x0000558777e144f3 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Parse/Parser.cpp:758:10
#48 0x0000558777e0fe7e clang::ParseAST(clang::Sema&, bool, bool) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Parse/ParseAST.cpp:170:5
#49 0x0000558775ff593f clang::FrontendAction::Execute() /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Frontend/FrontendAction.cpp:1082:10
#50 0x0000558775f62b2d getPtr /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../llvm/include/llvm/Support/Error.h:279:42
#51 0x0000558775f62b2d operator bool /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../llvm/include/llvm/Support/Error.h:242:16
#52 0x0000558775f62b2d clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Frontend/CompilerInstance.cpp:1061:23
#53 0x00005587760ce923 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:280:25
#54 0x00005587756d6435 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/tools/driver/cc1_main.cpp:285:15
#55 0x00005587756e5379 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/tools/driver/driver.cpp:217:12
#56 0x0000558775dbf079 operator() /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Driver/Job.cpp:440:30
#57 0x0000558775dbf079 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::$_0>(long) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../llvm/include/llvm/ADT/STLFunctionalExtras.h:45:12
#58 0x0000558776c42a1e operator() /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../llvm/include/llvm/ADT/STLFunctionalExtras.h:0:12
#59 0x0000558776c42a1e llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../llvm/lib/Support/CrashRecoveryContext.cpp:426:3
#60 0x0000558775dbeef3 clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Driver/Job.cpp:440:7
#61 0x0000558775d7d956 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Driver/Compilation.cpp:199:15
#62 0x0000558775d7dc0e clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Driver/Compilation.cpp:253:13
#63 0x0000558775d9a8bd empty /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../llvm/include/llvm/ADT/SmallVector.h:81:46
#64 0x0000558775d9a8bd clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/lib/Driver/Driver.cpp:1946:23
#65 0x00005587756e4c51 clang_main(int, char**, llvm::ToolContext const&) /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/../../clang/tools/driver/driver.cpp:393:21
#66 0x00005587756e61d7 main /usr/local/google/home/aeubanks/repos/llvm-project/build/rel/gen/clang/tools/driver/clang-driver.cpp:17:10
#67 0x00007fa1cc043b8a __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#68 0x00007fa1cc043c45 call_init ./csu/../csu/libc-start.c:128:20
#69 0x00007fa1cc043c45 __libc_start_main ./csu/../csu/libc-start.c:347:5
#70 0x00005587756d4b21 _start (../../../../llvm-project/build/rel/bin/clang+++0x25e8b21)
clang++: �[0;1;31merror: �[0m�[1mclang frontend command failed with exit code 134 (use -v to see invocation)�[0m
clang version 20.0.0
Target: x86_64-apple-macos
Thread model: posix
InstalledDir: ../../../../llvm-project/build/rel/bin
Build config: +assertions

@pranavk
Copy link
Contributor

pranavk commented Sep 12, 2024

I am seeing internal crashes due to this as well. I am reverting this as it's causing issues in chromium open-source project as well as @aeubanks mentioned above. Feel free to reland.

pranavk added a commit to pranavk/llvm-project that referenced this pull request Sep 12, 2024
…de loaded from different modules (llvm#104512)"

This reverts commit d778689.
pranavk added a commit that referenced this pull request Sep 12, 2024
#108311)

…de loaded from different modules (#104512)"

This reverts commit d778689.
for (unsigned I = 0; I != NumLambdas; ++I)
Reader.PendingLambdas.push_back(Record.readDeclID());
} else {
Record.skipInts(NumLambdas);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is not paired with writing process. It will only write a zero if it is not the first.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ChuanqiXu9 could you please elaborate why you think it may not be paired? Code in ASTDeclWriter looks like this:

  if (D->isCanonicalDecl()) {
    llvm::SmallVector<const Decl *, 2> Lambdas = collectLambdas(D);
    Record.push_back(Lambdas.size());
    for (const auto *L : Lambdas)
      Record.AddDeclRef(L);
  } else {
    Record.push_back(0);
  }

So in the first case it writes size + following decls, in the second case it writes 0. I looked the implementation of skipInts for skipInts(0) it does nothing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, it was an oversight. I took too quickly from the above stack trace.

@dmpolukhin
Copy link
Contributor Author

this is causing a crash with precompiled headers. I can try to reduce, but hopefully the problem is obvious from this assert/stack trace?

@aeubanks could you please create a reproducer or at least some instruction how it can be reproduced? From the stack trace it is not clear. The crash happens on translating GlobalDeclID but it has no clue what was wrong with the value.

@aeubanks
Copy link
Contributor

let me try to come up with a reduced repro

@aeubanks
Copy link
Contributor

aeubanks commented Sep 12, 2024

repro.zip

edit: got a better reduced repro, see attachment

@dmpolukhin
Copy link
Contributor Author

repro.zip

edit: got a better reduced repro, see attachment

Thank you for the reproducer, I see the crash and I'm working on it.

dmpolukhin added a commit that referenced this pull request Sep 25, 2024
…m different modules (#109167)

Summary:
Because AST loading code is lazy and happens in unpredictable order, it
is possible that a function and lambda inside the function can be loaded
from different modules. As a result, the captured DeclRefExpr won’t
match the corresponding VarDecl inside the function. This situation is
reflected in the AST as follows:

```
FunctionDecl 0x555564f4aff0 <Conv.h:33:1, line:41:1> line:33:35 imported in ./thrift_cpp2_base.h hidden tryTo 'Expected<Tgt, const char *> ()' inline
|-also in ./folly-conv.h
`-CompoundStmt 0x555564f7cfc8 <col:43, line:41:1>
  |-DeclStmt 0x555564f7ced8 <line:34:3, col:17>
  | `-VarDecl 0x555564f7cef8 <col:3, col:16> col:7 imported in ./thrift_cpp2_base.h hidden referenced result 'Tgt' cinit
  |   `-IntegerLiteral 0x555564f7d080 <col:16> 'int' 0
  |-CallExpr 0x555564f7cea8 <line:39:3, col:76> '<dependent type>'
  | |-UnresolvedLookupExpr 0x555564f7bea0 <col:3, col:19> '<overloaded function type>' lvalue (no ADL) = 'then_' 0x555564f7bef0
  | |-CXXTemporaryObjectExpr 0x555564f7bcb0 <col:25, col:45> 'Expected<bool, int>':'folly::Expected<bool, int>' 'void () noexcept' zeroing
  | `-LambdaExpr 0x555564f7bc88 <col:48, col:75> '(lambda at Conv.h:39:48)'
  |   |-CXXRecordDecl 0x555564f76b88 <col:48> col:48 imported in ./folly-conv.h hidden implicit <undeserialized declarations> class definition
  |   | |-also in ./thrift_cpp2_base.h
  |   | `-DefinitionData lambda empty standard_layout trivially_copyable literal can_const_default_init
  |   |   |-DefaultConstructor defaulted_is_constexpr
  |   |   |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
  |   |   |-MoveConstructor exists simple trivial needs_implicit
  |   |   |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
  |   |   |-MoveAssignment
  |   |   `-Destructor simple irrelevant trivial constexpr needs_implicit
  |   `-CompoundStmt 0x555564f7d1a8 <col:58, col:75>
  |     `-ReturnStmt 0x555564f7d198 <col:60, col:67>
  |       `-DeclRefExpr 0x555564f7d0a0 <col:67> 'Tgt' lvalue Var 0x555564f7d0c8 'result' 'Tgt' refers_to_enclosing_variable_or_capture
  `-ReturnStmt 0x555564f7bc78 <line:40:3, col:11>
    `-InitListExpr 0x555564f7bc38 <col:10, col:11> 'void'
```

This diff modifies the AST deserialization process to load lambdas
within the canonical function declaration sooner, immediately following
the function, ensuring that they are loaded from the same module.

Re-land #104512 Added test case
that caused crash due to multiple enclosed lambdas deserialization.

Test Plan: check-clang
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:modules C++20 modules and Clang Header Modules clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants