diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1435,6 +1435,20 @@ return Result; } + bool LambdaExpressionShouldBeConsideredDependent(LambdaExpr * E) const { + if(E->getLambdaClass()->isNeverDependentLambda()) + return false; + + if(SemaRef.CurContext->isDependentContext()) + return true; + + return llvm::any_of(TemplateArgs.getInnermost(), [](const TemplateArgument & C) { + return C.isDependent(); + }); + + } + + ExprResult TransformRequiresExpr(RequiresExpr *E) { LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true); ExprResult TransReq = inherited::TransformRequiresExpr(E); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -761,6 +761,8 @@ /// the body. StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body); + bool LambdaExpressionShouldBeConsideredDependent(LambdaExpr *E) const; + QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL); StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr); @@ -13294,18 +13296,9 @@ // Create the local class that will describe the lambda. - // FIXME: DependencyKind below is wrong when substituting inside a templated - // context that isn't a DeclContext (such as a variable template), or when - // substituting an unevaluated lambda inside of a function's parameter's type - // - as parameter types are not instantiated from within a function's DC. We - // use evaluation contexts to distinguish the function parameter case. CXXRecordDecl::LambdaDependencyKind DependencyKind = - CXXRecordDecl::LDK_Unknown; - if ((getSema().isUnevaluatedContext() || - getSema().isConstantEvaluatedContext()) && - (getSema().CurContext->isFileContext() || - !getSema().CurContext->getParent()->isDependentContext())) - DependencyKind = CXXRecordDecl::LDK_NeverDependent; + getDerived().LambdaExpressionShouldBeConsideredDependent(E) ? + CXXRecordDecl::LDK_AlwaysDependent : CXXRecordDecl::LDK_NeverDependent; CXXRecordDecl *OldClass = E->getLambdaClass(); CXXRecordDecl *Class = getSema().createLambdaClosureType( @@ -13578,6 +13571,12 @@ return S; } +template +bool TreeTransform::LambdaExpressionShouldBeConsideredDependent(LambdaExpr *) const { + return false; +} + + template ExprResult TreeTransform::TransformCXXUnresolvedConstructExpr( diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp --- a/clang/test/SemaCXX/lambda-expressions.cpp +++ b/clang/test/SemaCXX/lambda-expressions.cpp @@ -715,3 +715,23 @@ // CHECK-NEXT: ConstantExpr // CHECK-NEXT: value: Int 2 } + +#if __cplusplus > 201402L +namespace GH62916 { + +template int { return T(42); }()> +struct P { + static constexpr int value = U; +}; + +template +constexpr P foo() { + return {}; +} + +void test() { + static_assert(foo().value == 42); +} + +} +#endif