This revision was automatically updated to reflect the committed changes. Closed by commit rG051cc460ba91: [C++20] Determine the dependency of unevaluated lambdas more accurately (authored by lime, committed by erichkeane).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D140554/new/ https://reviews.llvm.org/D140554 Files: clang/docs/ReleaseNotes.rst clang/include/clang/Sema/Sema.h clang/lib/Sema/TreeTransform.h clang/test/CodeGenCXX/cxx20-unevaluated-lambda-crash.cpp clang/test/SemaCXX/lambda-unevaluated.cpp Index: clang/test/SemaCXX/lambda-unevaluated.cpp =================================================================== --- clang/test/SemaCXX/lambda-unevaluated.cpp +++ clang/test/SemaCXX/lambda-unevaluated.cpp @@ -61,9 +61,7 @@ // Same. template<int N> void g(const char (*)[([]{ return N; })()]) {} // expected-note {{candidate}} template<int N> void g(const char (*)[([]{ return N; })()]) {} // expected-note {{candidate}} -// FIXME: We instantiate the lambdas into the context of the function template, -// so we think they're dependent and can't evaluate a call to them. -void use_g() { g<6>(&"hello"); } // expected-error {{no matching function}} +void use_g() { g<6>(&"hello"); } // expected-error {{ambiguous}} } namespace GH51416 { Index: clang/test/CodeGenCXX/cxx20-unevaluated-lambda-crash.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/cxx20-unevaluated-lambda-crash.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 %s -emit-llvm -o - | FileCheck %s + +// CHECK-LABEL: define linkonce_odr void @"_ZN10Issue579601EIiEENS_1FILNS_3$_0EEEEv"() +namespace Issue57960 { +template<auto> +class F {}; + +template<typename D> +F<[]{}> E() { + return {}; +} + +static auto f = E<int>(); +} Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -13234,10 +13234,11 @@ // 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 isUnevaluatedContext() to distinguish the function parameter case. + // use evaluation contexts to distinguish the function parameter case. CXXRecordDecl::LambdaDependencyKind DependencyKind = CXXRecordDecl::LDK_Unknown; - if (getSema().isUnevaluatedContext() && + if ((getSema().isUnevaluatedContext() || + getSema().isConstantEvaluatedContext()) && (getSema().CurContext->isFileContext() || !getSema().CurContext->getParent()->isDependentContext())) DependencyKind = CXXRecordDecl::LDK_NeverDependent; Index: clang/include/clang/Sema/Sema.h =================================================================== --- clang/include/clang/Sema/Sema.h +++ clang/include/clang/Sema/Sema.h @@ -9624,6 +9624,12 @@ return ExprEvalContexts.back().isUnevaluated(); } + bool isConstantEvaluatedContext() const { + assert(!ExprEvalContexts.empty() && + "Must be in an expression evaluation context"); + return ExprEvalContexts.back().isConstantEvaluated(); + } + bool isImmediateFunctionContext() const { assert(!ExprEvalContexts.empty() && "Must be in an expression evaluation context"); Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -338,6 +338,8 @@ - In C mode, when ``e1`` has ``__attribute__((noreturn))`` but ``e2`` doesn't, ``(c ? e1 : e2)`` is no longer considered noreturn. `Issue 59792 <https://github.com/llvm/llvm-project/issues/59792>`_ +- Fix an issue that makes Clang crash on lambda template parameters. This fixes + `Issue 57960 <https://github.com/llvm/llvm-project/issues/57960>`_ Improvements to Clang's diagnostics ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Index: clang/test/SemaCXX/lambda-unevaluated.cpp =================================================================== --- clang/test/SemaCXX/lambda-unevaluated.cpp +++ clang/test/SemaCXX/lambda-unevaluated.cpp @@ -61,9 +61,7 @@ // Same. template<int N> void g(const char (*)[([]{ return N; })()]) {} // expected-note {{candidate}} template<int N> void g(const char (*)[([]{ return N; })()]) {} // expected-note {{candidate}} -// FIXME: We instantiate the lambdas into the context of the function template, -// so we think they're dependent and can't evaluate a call to them. -void use_g() { g<6>(&"hello"); } // expected-error {{no matching function}} +void use_g() { g<6>(&"hello"); } // expected-error {{ambiguous}} } namespace GH51416 { Index: clang/test/CodeGenCXX/cxx20-unevaluated-lambda-crash.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/cxx20-unevaluated-lambda-crash.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 %s -emit-llvm -o - | FileCheck %s + +// CHECK-LABEL: define linkonce_odr void @"_ZN10Issue579601EIiEENS_1FILNS_3$_0EEEEv"() +namespace Issue57960 { +template<auto> +class F {}; + +template<typename D> +F<[]{}> E() { + return {}; +} + +static auto f = E<int>(); +} Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -13234,10 +13234,11 @@ // 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 isUnevaluatedContext() to distinguish the function parameter case. + // use evaluation contexts to distinguish the function parameter case. CXXRecordDecl::LambdaDependencyKind DependencyKind = CXXRecordDecl::LDK_Unknown; - if (getSema().isUnevaluatedContext() && + if ((getSema().isUnevaluatedContext() || + getSema().isConstantEvaluatedContext()) && (getSema().CurContext->isFileContext() || !getSema().CurContext->getParent()->isDependentContext())) DependencyKind = CXXRecordDecl::LDK_NeverDependent; Index: clang/include/clang/Sema/Sema.h =================================================================== --- clang/include/clang/Sema/Sema.h +++ clang/include/clang/Sema/Sema.h @@ -9624,6 +9624,12 @@ return ExprEvalContexts.back().isUnevaluated(); } + bool isConstantEvaluatedContext() const { + assert(!ExprEvalContexts.empty() && + "Must be in an expression evaluation context"); + return ExprEvalContexts.back().isConstantEvaluated(); + } + bool isImmediateFunctionContext() const { assert(!ExprEvalContexts.empty() && "Must be in an expression evaluation context"); Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -338,6 +338,8 @@ - In C mode, when ``e1`` has ``__attribute__((noreturn))`` but ``e2`` doesn't, ``(c ? e1 : e2)`` is no longer considered noreturn. `Issue 59792 <https://github.com/llvm/llvm-project/issues/59792>`_ +- Fix an issue that makes Clang crash on lambda template parameters. This fixes + `Issue 57960 <https://github.com/llvm/llvm-project/issues/57960>`_ Improvements to Clang's diagnostics ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits