Skip to content
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

Regression introduced with implementation of P2036R3 (assertion error) #65067

Closed
alejandro-alvarez-sonarsource opened this issue Aug 29, 2023 · 7 comments
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party duplicate Resolved as duplicate regression

Comments

@alejandro-alvarez-sonarsource
Copy link
Contributor

Hello,

Commit 93d7002 introduced a regression. A reproducing snippet:

template <typename T> T &declval() noexcept {}

template <typename T> struct FakeVoidToVoid {};

template <typename Func> inline auto call(Func &&func) { return func(); }

template <typename Func>
using NormalizedCallResult = FakeVoidToVoid<decltype(call(declval<Func>()))>;

template <typename T> class SemiFuture {
public:
  template <typename Func> auto then(Func &&func) {
    return and_then(wrapCB<T>(func));
  }

  template <typename Func> auto and_then(Func &&func) {
    using Result = NormalizedCallResult<Func>;
  }

protected:
  template <typename RawArg, typename Func> auto wrapCB(Func &&func) {
    return [func = func](auto... args) -> SemiFuture<decltype(func(args...))> {return {};};
  }
};

auto removeDocumentsInRange(SemiFuture<void> waitForActiveQueriesToComplete) {
  return waitForActiveQueriesToComplete.then([]() {});
}

This has been reduced from code coming from MongoDB.

Before 93d7002, the func in decltype(func(args...) would refer to the parameter func. After the commit, it would refer to the variable func introduced by the capture. It looks like other parts of the parser (i,e, TemplateInstantiator::TransformDecl) do not expect to find a VarDecl and fail to handle them.

This regression happens for C++14 and higher, even though "Change scope of lambda trailing-return-type" was introduced with C++23.

@alejandro-alvarez-sonarsource
Copy link
Contributor Author

With only this snippet it doesn't trigger, but with the full translation unit from MongoDB we can get a SIGSEGV later on if assertions are disabled.

[Inlined] llvm::DenseMapBase::LookupBucketFor<…>(const clang::ValueDecl *const &, const llvm::detail::DenseMapPair<…> *&) const DenseMap.h:658
[Inlined] llvm::DenseMapBase::contains(const clang::ValueDecl *) const DenseMap.h:147
[Inlined] llvm::DenseMapBase::count(const clang::ValueDecl *) const DenseMap.h:152
[Inlined] isVariableAlreadyCapturedInScopeInfo(clang::sema::CapturingScopeInfo *, clang::ValueDecl *, bool &, clang::QualType &, clang::QualType &) SemaExpr.cpp:19093
clang::Sema::tryCaptureVariable(clang::ValueDecl *, clang::SourceLocation, clang::Sema::TryCaptureKind, clang::SourceLocation, bool, clang::QualType &, clang::QualType &, const unsigned int *) SemaExpr.cpp:19651
[Inlined] clang::Sema::NeedToCaptureVariable(clang::ValueDecl *, clang::SourceLocation) SemaExpr.cpp:19829
clang::Sema::BuildDeclRefExpr(clang::ValueDecl *, clang::QualType, clang::ExprValueKind, const clang::DeclarationNameInfo &, clang::NestedNameSpecifierLoc, clang::NamedDecl *, clang::SourceLocation, const clang::TemplateArgumentListInfo *) SemaExpr.cpp:2184
clang::Sema::BuildDeclRefExpr(clang::ValueDecl *, clang::QualType, clang::ExprValueKind, const clang::DeclarationNameInfo &, const clang::CXXScopeSpec *, clang::NamedDecl *, clang::SourceLocation, const clang::TemplateArgumentListInfo *) SemaExpr.cpp:2114
clang::Sema::BuildDeclarationNameExpr(const clang::CXXScopeSpec &, const clang::DeclarationNameInfo &, clang::NamedDecl *, clang::NamedDecl *, const clang::TemplateArgumentListInfo *, bool) SemaExpr.cpp:3603
[Inlined] clang::TreeTransform::RebuildDeclRefExpr(clang::NestedNameSpecifierLoc, clang::ValueDecl *, const clang::DeclarationNameInfo &, clang::NamedDecl *, clang::TemplateArgumentListInfo *) TreeTransform.h:2633
clang::TreeTransform::TransformDeclRefExpr(clang::DeclRefExpr *) TreeTransform.h:10854
clang::TreeTransform::TransformCallExpr(clang::CallExpr *) TreeTransform.h:11332
clang::TreeTransform::TransformDecltypeType(clang::TypeLocBuilder &, clang::DecltypeTypeLoc) TreeTransform.h:6423
clang::TreeTransform::TransformType(clang::TypeSourceInfo *) TreeTransform.h:4870
clang::TreeTransform::TransformTemplateArgument(const clang::TemplateArgumentLoc &, clang::TemplateArgumentLoc &, bool) TreeTransform.h:4599
[Inlined] clang::TreeTransform::TransformTemplateArguments<…>(clang::TemplateArgumentLocContainerIterator<…>, clang::TemplateArgumentLocContainerIterator<…>, clang::TemplateArgumentListInfo &, bool) TreeTransform.h:4825
clang::TreeTransform::TransformTemplateSpecializationType(clang::TypeLocBuilder &, clang::TemplateSpecializationTypeLoc, clang::TemplateName) TreeTransform.h:6872
clang::TreeTransform::TransformTemplateSpecializationType(clang::TypeLocBuilder &, clang::TemplateSpecializationTypeLoc) TreeTransform.h:6633
clang::TreeTransform::TransformElaboratedType(clang::TypeLocBuilder &, clang::ElaboratedTypeLoc) TreeTransform.h:6987
clang::TreeTransform::TransformType(clang::TypeSourceInfo *) TreeTransform.h:4870
clang::TreeTransform::TransformTemplateArgument(const clang::TemplateArgumentLoc &, clang::TemplateArgumentLoc &, bool) TreeTransform.h:4599
[Inlined] clang::TreeTransform::TransformTemplateArguments<…>(clang::TemplateArgumentLocContainerIterator<…>, clang::TemplateArgumentLocContainerIterator<…>, clang::TemplateArgumentListInfo &, bool) TreeTransform.h:4825
clang::TreeTransform::TransformTemplateSpecializationType(clang::TypeLocBuilder &, clang::TemplateSpecializationTypeLoc, clang::TemplateName) TreeTransform.h:6872
clang::TreeTransform::TransformTemplateSpecializationType(clang::TypeLocBuilder &, clang::TemplateSpecializationTypeLoc) TreeTransform.h:6633
clang::TreeTransform::TransformElaboratedType(clang::TypeLocBuilder &, clang::ElaboratedTypeLoc) TreeTransform.h:6987
[Inlined] clang::TreeTransform::TransformFunctionProtoType<…>(clang::TypeLocBuilder &, clang::FunctionProtoTypeLoc, clang::CXXRecordDecl *, clang::Qualifiers, $_0) TreeTransform.h:6106
[Inlined] TemplateInstantiator::TransformFunctionProtoType<…>(clang::TypeLocBuilder &, clang::FunctionProtoTypeLoc, clang::CXXRecordDecl *, clang::Qualifiers, $_0) SemaTemplateInstantiate.cpp:2096
clang::Sema::SubstFunctionDeclType(clang::TypeSourceInfo *, const clang::MultiLevelTemplateArgumentList &, clang::SourceLocation, clang::DeclarationName, clang::CXXRecordDecl *, clang::Qualifiers, bool) SemaTemplateInstantiate.cpp:2612
clang::TemplateDeclInstantiator::SubstFunctionType(clang::FunctionDecl *, llvm::SmallVectorImpl<…> &) SemaTemplateInstantiateDecl.cpp:4428
clang::TemplateDeclInstantiator::VisitCXXMethodDecl(clang::CXXMethodDecl *, clang::TemplateParameterList *, std::optional<…>, clang::TemplateDeclInstantiator::RewriteKind) SemaTemplateInstantiateDecl.cpp:2463
[Inlined] $_0::operator()() const SemaTemplateInstantiateDecl.cpp:4032
llvm::function_ref::callback_fn<…>(long) STLFunctionalExtras.h:45
[Inlined] llvm::function_ref::operator()() const STLFunctionalExtras.h:68
[Inlined] clang::runWithSufficientStackSpace(llvm::function_ref<…>, llvm::function_ref<…>) Stack.h:46
clang::Sema::runWithSufficientStackSpace(clang::SourceLocation, llvm::function_ref<…>) Sema.cpp:513
clang::Sema::SubstDecl(clang::Decl *, clang::DeclContext *, const clang::MultiLevelTemplateArgumentList &) SemaTemplateInstantiateDecl.cpp:4031
clang::Sema::FinishTemplateArgumentDeduction(clang::FunctionTemplateDecl *, llvm::SmallVectorImpl<…> &, unsigned int, clang::FunctionDecl *&, clang::sema::TemplateDeductionInfo &, const llvm::SmallVectorImpl<…> *, bool, llvm::function_ref<…>) SemaTemplateDeduction.cpp:3631
[Inlined] $_2::operator()() const SemaTemplateDeduction.cpp:4252
llvm::function_ref::callback_fn<…>(long) STLFunctionalExtras.h:45
[Inlined] llvm::function_ref::operator()() const STLFunctionalExtras.h:68
[Inlined] clang::runWithSufficientStackSpace(llvm::function_ref<…>, llvm::function_ref<…>) Stack.h:46
clang::Sema::runWithSufficientStackSpace(clang::SourceLocation, llvm::function_ref<…>) Sema.cpp:513
clang::Sema::DeduceTemplateArguments(clang::FunctionTemplateDecl *, clang::TemplateArgumentListInfo *, llvm::ArrayRef<…>, clang::FunctionDecl *&, clang::sema::TemplateDeductionInfo &, bool, bool, llvm::function_ref<…>) SemaTemplateDeduction.cpp:4251
clang::Sema::AddMethodTemplateCandidate(clang::FunctionTemplateDecl *, clang::DeclAccessPair, clang::CXXRecordDecl *, clang::TemplateArgumentListInfo *, clang::QualType, clang::Expr::Classification, llvm::ArrayRef<…>, clang::OverloadCandidateSet &, bool, bool, clang::OverloadCandidateParamOrder) SemaOverload.cpp:7297
clang::Sema::AddMethodCandidate(clang::DeclAccessPair, clang::QualType, clang::Expr::Classification, llvm::ArrayRef<…>, clang::OverloadCandidateSet &, bool, clang::OverloadCandidateParamOrder) SemaOverload.cpp:7087
clang::Sema::BuildCallToObjectOfClassType(clang::Scope *, clang::Expr *, clang::SourceLocation, llvm::MutableArrayRef<…>, clang::SourceLocation) SemaOverload.cpp:14982
clang::Sema::BuildCallExpr(clang::Scope *, clang::Expr *, clang::SourceLocation, llvm::MutableArrayRef<…>, clang::SourceLocation, clang::Expr *, bool, bool) SemaExpr.cpp:7115
clang::Sema::ActOnCallExpr(clang::Scope *, clang::Expr *, clang::SourceLocation, llvm::MutableArrayRef<…>, clang::SourceLocation, clang::Expr *) SemaExpr.cpp:7031
[Inlined] clang::TreeTransform::RebuildCallExpr(clang::Expr *, clang::SourceLocation, llvm::MutableArrayRef<…>, clang::SourceLocation, clang::Expr *) TreeTransform.h:2779
clang::TreeTransform::TransformCallExpr(clang::CallExpr *) TreeTransform.h:11360
clang::TreeTransform::TransformReturnStmt(clang::ReturnStmt *) TreeTransform.h:7887
clang::TreeTransform::TransformCompoundStmt(clang::CompoundStmt *, bool) TreeTransform.h:7487
clang::Sema::SubstStmt(clang::Stmt *, const clang::MultiLevelTemplateArgumentList &) SemaTemplateInstantiate.cpp:3986
clang::Sema::InstantiateFunctionDefinition(clang::SourceLocation, clang::FunctionDecl *, bool, bool, bool) SemaTemplateInstantiateDecl.cpp:5119
[Inlined] llvm::function_ref::operator()() const STLFunctionalExtras.h:68
[Inlined] clang::runWithSufficientStackSpace(llvm::function_ref<…>, llvm::function_ref<…>) Stack.h:46
clang::Sema::runWithSufficientStackSpace(clang::SourceLocation, llvm::function_ref<…>) Sema.cpp:513
clang::Sema::DeduceReturnType(clang::FunctionDecl *, clang::SourceLocation, bool) SemaTemplateDeduction.cpp:5022
clang::Sema::DiagnoseUseOfDecl(clang::NamedDecl *, llvm::ArrayRef<…>, const clang::ObjCInterfaceDecl *, bool, bool, clang::ObjCInterfaceDecl *, bool) SemaExpr.cpp:306
FinishOverloadedCallExpr(clang::Sema &, clang::Scope *, clang::Expr *, clang::UnresolvedLookupExpr *, clang::SourceLocation, llvm::MutableArrayRef<…>, clang::SourceLocation, clang::Expr *, clang::OverloadCandidateSet *, clang::OverloadCandidate **, clang::OverloadingResult, bool) SemaOverload.cpp:13487
clang::Sema::BuildOverloadedCallExpr(clang::Scope *, clang::Expr *, clang::UnresolvedLookupExpr *, clang::SourceLocation, llvm::MutableArrayRef<…>, clang::SourceLocation, clang::Expr *, bool, bool) SemaOverload.cpp:13603
clang::Sema::BuildCallExpr(clang::Scope *, clang::Expr *, clang::SourceLocation, llvm::MutableArrayRef<…>, clang::SourceLocation, clang::Expr *, bool, bool) SemaExpr.cpp:7142
clang::Sema::ActOnCallExpr(clang::Scope *, clang::Expr *, clang::SourceLocation, llvm::MutableArrayRef<…>, clang::SourceLocation, clang::Expr *) SemaExpr.cpp:7031
[Inlined] clang::TreeTransform::RebuildCallExpr(clang::Expr *, clang::SourceLocation, llvm::MutableArrayRef<…>, clang::SourceLocation, clang::Expr *) TreeTransform.h:2779
clang::TreeTransform::TransformCallExpr(clang::CallExpr *) TreeTransform.h:11360
clang::TreeTransform::TransformDecltypeType(clang::TypeLocBuilder &, clang::DecltypeTypeLoc) TreeTransform.h:6423
clang::TreeTransform::TransformType(clang::TypeSourceInfo *) TreeTransform.h:4870
clang::TreeTransform::TransformTemplateArgument(const clang::TemplateArgumentLoc &, clang::TemplateArgumentLoc &, bool) TreeTransform.h:4599
[Inlined] clang::TreeTransform::TransformTemplateArguments<…>(clang::TemplateArgumentLocContainerIterator<…>, clang::TemplateArgumentLocContainerIterator<…>, clang::TemplateArgumentListInfo &, bool) TreeTransform.h:4825
clang::TreeTransform::TransformTemplateSpecializationType(clang::TypeLocBuilder &, clang::TemplateSpecializationTypeLoc, clang::TemplateName) TreeTransform.h:6872
clang::TreeTransform::TransformTemplateSpecializationType(clang::TypeLocBuilder &, clang::TemplateSpecializationTypeLoc) TreeTransform.h:6633
clang::TreeTransform::TransformElaboratedType(clang::TypeLocBuilder &, clang::ElaboratedTypeLoc) TreeTransform.h:6987
clang::TreeTransform::TransformType(clang::TypeSourceInfo *) TreeTransform.h:4870
clang::TreeTransform::TransformTemplateArgument(const clang::TemplateArgumentLoc &, clang::TemplateArgumentLoc &, bool) TreeTransform.h:4599
[Inlined] clang::TreeTransform::TransformTemplateArguments<…>(clang::TemplateArgumentLocContainerIterator<…>, clang::TemplateArgumentLocContainerIterator<…>, clang::TemplateArgumentListInfo &, bool) TreeTransform.h:4825
clang::TreeTransform::TransformTemplateSpecializationType(clang::TypeLocBuilder &, clang::TemplateSpecializationTypeLoc, clang::TemplateName) TreeTransform.h:6872
clang::TreeTransform::TransformTemplateSpecializationType(clang::TypeLocBuilder &, clang::TemplateSpecializationTypeLoc) TreeTransform.h:6633
clang::TreeTransform::TransformElaboratedType(clang::TypeLocBuilder &, clang::ElaboratedTypeLoc) TreeTransform.h:6987
clang::TreeTransform::TransformType(clang::TypeSourceInfo *) TreeTransform.h:4870
[Inlined] clang::TreeTransform::TransformType(clang::QualType) TreeTransform.h:4849
clang::Sema::SubstType(clang::QualType, const clang::MultiLevelTemplateArgumentList &, clang::SourceLocation, clang::DeclarationName) SemaTemplateInstantiate.cpp:2552
clang::Sema::CheckTemplateIdType(clang::TemplateName, clang::SourceLocation, clang::TemplateArgumentListInfo &) SemaTemplate.cpp:3928
[Inlined] clang::TreeTransform::RebuildTemplateSpecializationType(clang::TemplateName, clang::SourceLocation, clang::TemplateArgumentListInfo &) TreeTransform.h:15087
clang::TreeTransform::TransformTemplateSpecializationType(clang::TypeLocBuilder &, clang::TemplateSpecializationTypeLoc, clang::TemplateName) TreeTransform.h:6880
clang::TreeTransform::TransformTemplateSpecializationType(clang::TypeLocBuilder &, clang::TemplateSpecializationTypeLoc) TreeTransform.h:6633
clang::TreeTransform::TransformElaboratedType(clang::TypeLocBuilder &, clang::ElaboratedTypeLoc) TreeTransform.h:6987
clang::TreeTransform::TransformType(clang::TypeSourceInfo *) TreeTransform.h:4870
clang::Sema::SubstType(clang::TypeSourceInfo *, const clang::MultiLevelTemplateArgumentList &, clang::SourceLocation, clang::DeclarationName, bool) SemaTemplateInstantiate.cpp:2505
clang::TemplateDeclInstantiator::InstantiateTypedefNameDecl(clang::TypedefNameDecl *, bool) SemaTemplateInstantiateDecl.cpp:966
clang::TemplateDeclInstantiator::VisitTypeAliasDecl(clang::TypeAliasDecl *) SemaTemplateInstantiateDecl.cpp:1048
[Inlined] $_0::operator()() const SemaTemplateInstantiateDecl.cpp:4032
llvm::function_ref::callback_fn<…>(long) STLFunctionalExtras.h:45
[Inlined] llvm::function_ref::operator()() const STLFunctionalExtras.h:68
[Inlined] clang::runWithSufficientStackSpace(llvm::function_ref<…>, llvm::function_ref<…>) Stack.h:46
clang::Sema::runWithSufficientStackSpace(clang::SourceLocation, llvm::function_ref<…>) Sema.cpp:513
clang::Sema::SubstDecl(clang::Decl *, clang::DeclContext *, const clang::MultiLevelTemplateArgumentList &) SemaTemplateInstantiateDecl.cpp:4031
[Inlined] TemplateInstantiator::TransformDefinition(clang::SourceLocation, clang::Decl *) SemaTemplateInstantiate.cpp:1570
clang::TreeTransform::TransformDeclStmt(clang::DeclStmt *) TreeTransform.h:7903
clang::TreeTransform::TransformCompoundStmt(clang::CompoundStmt *, bool) TreeTransform.h:7487
clang::Sema::SubstStmt(clang::Stmt *, const clang::MultiLevelTemplateArgumentList &) SemaTemplateInstantiate.cpp:3986
clang::Sema::InstantiateFunctionDefinition(clang::SourceLocation, clang::FunctionDecl *, bool, bool, bool) SemaTemplateInstantiateDecl.cpp:5119
[Inlined] llvm::function_ref::operator()() const STLFunctionalExtras.h:68
[Inlined] clang::runWithSufficientStackSpace(llvm::function_ref<…>, llvm::function_ref<…>) Stack.h:46
clang::Sema::runWithSufficientStackSpace(clang::SourceLocation, llvm::function_ref<…>) Sema.cpp:513
clang::Sema::DeduceReturnType(clang::FunctionDecl *, clang::SourceLocation, bool) SemaTemplateDeduction.cpp:5022
clang::Sema::DiagnoseUseOfDecl(clang::NamedDecl *, llvm::ArrayRef<…>, const clang::ObjCInterfaceDecl *, bool, bool, clang::ObjCInterfaceDecl *, bool) SemaExpr.cpp:306
[Inlined] clang::Sema::DiagnoseUseOfOverloadedDecl(clang::NamedDecl *, clang::SourceLocation) Sema.h:5435
clang::Sema::BuildCallToMemberFunction(clang::Scope *, clang::Expr *, clang::SourceLocation, llvm::MutableArrayRef<…>, clang::SourceLocation, clang::Expr *, bool, bool) SemaOverload.cpp:14811
clang::Sema::ActOnCallExpr(clang::Scope *, clang::Expr *, clang::SourceLocation, llvm::MutableArrayRef<…>, clang::SourceLocation, clang::Expr *) SemaExpr.cpp:7031
[Inlined] clang::TreeTransform::RebuildCallExpr(clang::Expr *, clang::SourceLocation, llvm::MutableArrayRef<…>, clang::SourceLocation, clang::Expr *) TreeTransform.h:2779
clang::TreeTransform::TransformCallExpr(clang::CallExpr *) TreeTransform.h:11360
clang::TreeTransform::TransformExprs(clang::Expr *const *, unsigned int, bool, llvm::SmallVectorImpl<…> &, bool *) TreeTransform.h:4240
clang::TreeTransform::TransformCXXUnresolvedConstructExpr(clang::CXXUnresolvedConstructExpr *) TreeTransform.h:13665
clang::TreeTransform::TransformReturnStmt(clang::ReturnStmt *) TreeTransform.h:7887
clang::TreeTransform::TransformCompoundStmt(clang::CompoundStmt *, bool) TreeTransform.h:7487
clang::Sema::SubstStmt(clang::Stmt *, const clang::MultiLevelTemplateArgumentList &) SemaTemplateInstantiate.cpp:3986
clang::Sema::InstantiateFunctionDefinition(clang::SourceLocation, clang::FunctionDecl *, bool, bool, bool) SemaTemplateInstantiateDecl.cpp:5119
[Inlined] llvm::function_ref::operator()() const STLFunctionalExtras.h:68
[Inlined] clang::runWithSufficientStackSpace(llvm::function_ref<…>, llvm::function_ref<…>) Stack.h:46
clang::Sema::runWithSufficientStackSpace(clang::SourceLocation, llvm::function_ref<…>) Sema.cpp:513
clang::Sema::DeduceReturnType(clang::FunctionDecl *, clang::SourceLocation, bool) SemaTemplateDeduction.cpp:5022
clang::Sema::DiagnoseUseOfDecl(clang::NamedDecl *, llvm::ArrayRef<…>, const clang::ObjCInterfaceDecl *, bool, bool, clang::ObjCInterfaceDecl *, bool) SemaExpr.cpp:306
[Inlined] clang::Sema::DiagnoseUseOfOverloadedDecl(clang::NamedDecl *, clang::SourceLocation) Sema.h:5435
clang::Sema::BuildCallToMemberFunction(clang::Scope *, clang::Expr *, clang::SourceLocation, llvm::MutableArrayRef<…>, clang::SourceLocation, clang::Expr *, bool, bool) SemaOverload.cpp:14811
clang::Sema::ActOnCallExpr(clang::Scope *, clang::Expr *, clang::SourceLocation, llvm::MutableArrayRef<…>, clang::SourceLocation, clang::Expr *) SemaExpr.cpp:7031
[Inlined] clang::TreeTransform::RebuildCallExpr(clang::Expr *, clang::SourceLocation, llvm::MutableArrayRef<…>, clang::SourceLocation, clang::Expr *) TreeTransform.h:2779
clang::TreeTransform::TransformCallExpr(clang::CallExpr *) TreeTransform.h:11360
clang::TreeTransform::TransformReturnStmt(clang::ReturnStmt *) TreeTransform.h:7887
clang::TreeTransform::TransformCompoundStmt(clang::CompoundStmt *, bool) TreeTransform.h:7487
[Inlined] clang::TreeTransform::TransformLambdaBody(clang::LambdaExpr *, clang::Stmt *) TreeTransform.h:13606
clang::TreeTransform::TransformLambdaExpr(clang::LambdaExpr *) TreeTransform.h:13579
TemplateInstantiator::TransformLambdaExpr(clang::LambdaExpr *) SemaTemplateInstantiate.cpp:1403
clang::TreeTransform::TransformExprs(clang::Expr *const *, unsigned int, bool, llvm::SmallVectorImpl<…> &, bool *) TreeTransform.h:4240
clang::TreeTransform::TransformCallExpr(clang::CallExpr *) TreeTransform.h:11339
clang::TreeTransform::TransformReturnStmt(clang::ReturnStmt *) TreeTransform.h:7887
clang::TreeTransform::TransformCompoundStmt(clang::CompoundStmt *, bool) TreeTransform.h:7487
clang::Sema::SubstStmt(clang::Stmt *, const clang::MultiLevelTemplateArgumentList &) SemaTemplateInstantiate.cpp:3986
clang::Sema::InstantiateFunctionDefinition(clang::SourceLocation, clang::FunctionDecl *, bool, bool, bool) SemaTemplateInstantiateDecl.cpp:5119
clang::Sema::PerformPendingInstantiations(bool) SemaTemplateInstantiateDecl.cpp:6376
clang::Sema::ActOnEndOfTranslationUnitFragment(clang::Sema::TUFragmentKind) Sema.cpp:1083
clang::Sema::ActOnEndOfTranslationUnit() Sema.cpp:1119
clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<…> &, clang::Sema::ModuleImportState &) Parser.cpp:709
clang::ParseAST(clang::Sema &, bool, bool) ParseAST.cpp:163
[Inlined] $_4::operator()() const Core.cpp:977
llvm::function_ref::callback_fn<…>(long) STLFunctionalExtras.h:45
[Inlined] auto void llvm::thread::GenericThreadProxy<std::tuple<void (*)(void*), sonarsource::(anonymous namespace)::Data*>>(void*)::'lambda'(auto&&, auto&&...)::operator()<void (*&)(void*), sonarsource::(anonymous namespace)::Data*&>(auto&&, auto&&...) const thread.h:43
[Inlined] auto std::__invoke_impl<void, void llvm::thread::GenericThreadProxy<std::tuple<void (*)(void*), sonarsource::(anonymous namespace)::Data*>>(void*)::'lambda'(auto&&, auto&&...), void (*&)(void*), sonarsource::(anonymous namespace)::Data*&>(std::__invoke_other, void llvm::thread::GenericThreadProxy<std::tuple<void (*)(void*), sonarsource::(anonymous namespace)::Data*>>(void*)::'lambda'(auto&&, auto&&...)&&, void (*&)(void*), sonarsource::(anonymous namespace)::Data*&) invoke.h:61
[Inlined] std::__invoke_result<auto, auto...>::type std::__invoke<void llvm::thread::GenericThreadProxy<std::tuple<void (*)(void*), sonarsource::(anonymous namespace)::Data*>>(void*)::'lambda'(auto&&, auto&&...), void (*&)(void*), sonarsource::(anonymous namespace)::Data*&>(auto&&, auto&&...) invoke.h:96
[Inlined] decltype(auto) std::__apply_impl<void llvm::thread::GenericThreadProxy<std::tuple<void (*)(void*), sonarsource::(anonymous namespace)::Data*>>(void*)::'lambda'(auto&&, auto&&...), std::tuple<void (*)(void*), sonarsource::(anonymous namespace)::Data*>&, 0ul, 1ul>(auto&&, std::tuple<void (*)(void*), sonarsource::(anonymous namespace)::Data*>&, std::integer_sequence<unsigned long, 0ul, 1ul>) tuple:1852
[Inlined] decltype(auto) std::apply<void llvm::thread::GenericThreadProxy<std::tuple<void (*)(void*), sonarsource::(anonymous namespace)::Data*>>(void*)::'lambda'(auto&&, auto&&...), std::tuple<void (*)(void*), sonarsource::(anonymous namespace)::Data*>&>(auto&&, std::tuple<void (*)(void*), sonarsource::(anonymous namespace)::Data*>&) tuple:1863
[Inlined] llvm::thread::GenericThreadProxy<…>(void *) thread.h:41
llvm::thread::ThreadProxy<…>(void *) thread.h:55
start_thread pthread_create.c:442
__clone3 0x00007fc1ca126a00

@EugeneZelenko EugeneZelenko added clang:frontend Language frontend issues, e.g. anything involving "Sema" regression and removed new issue labels Aug 29, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Aug 29, 2023

@llvm/issue-subscribers-clang-frontend

@cor3ntin
Copy link
Contributor

cor3ntin commented Aug 29, 2023

reduced to

template <typename> class a {
public:
  template <typename b> void c(b f) { d<int>(f)(); }
  template <typename, typename b> auto d(b f) {
    return [f = f](auto... args) -> a<decltype(f(args...))> { return {}; };
  }
};
a<void> e;
auto fn1() {
  e.c([] {});
}

@cor3ntin cor3ntin added the confirmed Verified by a second party label Aug 29, 2023
@cor3ntin
Copy link
Contributor

This looks like a duplicate of #63675

@cor3ntin
Copy link
Contributor

I think in TemplateDeclInstantiator::VisitCXXMethodDecl we need to call addInstantiatedCapturesToScope, the same way we do when constraint checking. @erichkeane does that vaguely makes sense to you?

@cor3ntin cor3ntin added the duplicate Resolved as duplicate label Aug 29, 2023
@cor3ntin
Copy link
Contributor

This is a duplicate of #63675. I will close this one to avoid duplicating the discussion! Thanks for reporting it

@cor3ntin cor3ntin closed this as not planned Won't fix, can't repro, duplicate, stale Aug 29, 2023
@erichkeane
Copy link
Collaborator

@cor3ntin : Yes, I think that sounds about right.

cor3ntin added a commit that referenced this issue Sep 6, 2023
Like concepts checking, a trailing return type of a lambda
in a dependent context may refer to captures in which case
they may need to be rebuilt, so the map of local decl
should include captures.

This patch reveal a pre-existing issue.
`this` is always recomputed by TreeTransform.

`*this` (like all captures) only become `const`
after the parameter list.

However, if try to recompute the value of `this` (in a parameter)
during template instantiation while determining the type of the call operator,
we will determine  it to be const (unless the lambda is mutable).

There is no good way to know at that point that we are in a parameter
or not, the easiest/best solution is to transform the type of this.

Note that doing so break a handful of HLSL tests.
So this is a prototype at this point.

Fixes #65067
Fixes #63675

Reviewed By: erichkeane

Differential Revision: https://reviews.llvm.org/D159126
cor3ntin added a commit that referenced this issue Sep 8, 2023
Like concepts checking, a trailing return type of a lambda
in a dependent context may refer to captures in which case
they may need to be rebuilt, so the map of local decl
should include captures.

This patch reveal a pre-existing issue.
`this` is always recomputed by TreeTransform.

`*this` (like all captures) only become `const`
after the parameter list.

However, if try to recompute the value of `this` (in a parameter)
during template instantiation while determining the type of the call operator,
we will determine  it to be const (unless the lambda is mutable).

There is no good way to know at that point that we are in a parameter
or not, the easiest/best solution is to transform the type of this.

Note that doing so break a handful of HLSL tests.
So this is a prototype at this point.

Fixes #65067
Fixes #63675

Reviewed By: erichkeane

Differential Revision: https://reviews.llvm.org/D159126
avillega pushed a commit to avillega/llvm-project that referenced this issue Sep 11, 2023
Like concepts checking, a trailing return type of a lambda
in a dependent context may refer to captures in which case
they may need to be rebuilt, so the map of local decl
should include captures.

This patch reveal a pre-existing issue.
`this` is always recomputed by TreeTransform.

`*this` (like all captures) only become `const`
after the parameter list.

However, if try to recompute the value of `this` (in a parameter)
during template instantiation while determining the type of the call operator,
we will determine  it to be const (unless the lambda is mutable).

There is no good way to know at that point that we are in a parameter
or not, the easiest/best solution is to transform the type of this.

Note that doing so break a handful of HLSL tests.
So this is a prototype at this point.

Fixes llvm#65067
Fixes llvm#63675

Reviewed By: erichkeane

Differential Revision: https://reviews.llvm.org/D159126
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" confirmed Verified by a second party duplicate Resolved as duplicate regression
Projects
None yet
Development

No branches or pull requests

5 participants