cor3ntin created this revision. Herald added a project: All. cor3ntin requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D152002 Files: clang/lib/Sema/SemaTemplateInstantiate.cpp clang/lib/Sema/TreeTransform.h clang/test/SemaCXX/lambda-expressions.cpp Index: clang/test/SemaCXX/lambda-expressions.cpp =================================================================== --- clang/test/SemaCXX/lambda-expressions.cpp +++ clang/test/SemaCXX/lambda-expressions.cpp @@ -715,3 +715,23 @@ // CHECK-NEXT: ConstantExpr // CHECK-NEXT: value: Int 2 } + +#if __cplusplus > 201402L +namespace GH62916 { + +template <class T, int U = []() -> int { return T(42); }()> +struct P { + static constexpr int value = U; +}; + +template <class T> +constexpr P<T> foo() { + return {}; +} + +void test() { + static_assert(foo<int>().value == 42); +} + +} +#endif Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ 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<typename Derived> +bool TreeTransform<Derived>::LambdaExpressionShouldBeConsideredDependent(LambdaExpr *) const { + return false; +} + + template<typename Derived> ExprResult TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr( Index: clang/lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiate.cpp +++ 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);
Index: clang/test/SemaCXX/lambda-expressions.cpp =================================================================== --- clang/test/SemaCXX/lambda-expressions.cpp +++ clang/test/SemaCXX/lambda-expressions.cpp @@ -715,3 +715,23 @@ // CHECK-NEXT: ConstantExpr // CHECK-NEXT: value: Int 2 } + +#if __cplusplus > 201402L +namespace GH62916 { + +template <class T, int U = []() -> int { return T(42); }()> +struct P { + static constexpr int value = U; +}; + +template <class T> +constexpr P<T> foo() { + return {}; +} + +void test() { + static_assert(foo<int>().value == 42); +} + +} +#endif Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ 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<typename Derived> +bool TreeTransform<Derived>::LambdaExpressionShouldBeConsideredDependent(LambdaExpr *) const { + return false; +} + + template<typename Derived> ExprResult TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr( Index: clang/lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiate.cpp +++ 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);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits