https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/98023
>From 74d7184777e977ab3e83bfcae7e08e550ef32a39 Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Mon, 8 Jul 2024 21:28:30 +0800 Subject: [PATCH 1/5] [Clang] Ensure the method scope at the late parsing of noexcept specifiers --- clang/docs/ReleaseNotes.rst | 2 +- clang/lib/Parse/ParseCXXInlineMethods.cpp | 15 +++++++++++++-- .../expr/expr.prim/expr.prim.general/p3-0x.cpp | 5 +++-- clang/test/CodeGenCXX/mangle-exception-spec.cpp | 11 +++++++++++ clang/test/SemaCXX/cxx0x-noexcept-expression.cpp | 8 ++++++++ 5 files changed, 36 insertions(+), 5 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 838cb69f647ee..b521de4515e1f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -958,7 +958,7 @@ Bug Fixes to C++ Support - Fixed a type constraint substitution issue involving a generic lambda expression. (#GH93821) - Fix a crash caused by improper use of ``__array_extent``. (#GH80474) - Fixed several bugs in capturing variables within unevaluated contexts. (#GH63845), (#GH67260), (#GH69307), - (#GH88081), (#GH89496), (#GH90669) and (#GH91633). + (#GH88081), (#GH89496), (#GH90669), (#GH91633) and (#GH97453). - Fixed handling of brace ellison when building deduction guides. (#GH64625), (#GH83368). - Clang now instantiates local constexpr functions eagerly for constant evaluators. (#GH35052), (#GH94849) - Fixed a failed assertion when attempting to convert an integer representing the difference diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index 943ce0fdde3a3..faab9c6b19caa 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -511,11 +511,13 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { // and the end of the function-definition, member-declarator, or // declarator. CXXMethodDecl *Method; + FunctionDecl *FunctionToPush; if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(LM.Method)) - Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl()); + FunctionToPush = FunTmpl->getTemplatedDecl(); else - Method = dyn_cast<CXXMethodDecl>(LM.Method); + FunctionToPush = cast<FunctionDecl>(LM.Method); + Method = dyn_cast<CXXMethodDecl>(FunctionToPush); Sema::CXXThisScopeRAII ThisScope( Actions, Method ? Method->getParent() : nullptr, @@ -529,6 +531,15 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { ExprResult NoexceptExpr; CachedTokens *ExceptionSpecTokens; + // Push a function scope so that tryCaptureVariable() can properly visit + // function scopes involving function parameters that are referenced inside + // the noexcept specifier e.g. through a lambda expression. + // Example: + // struct X { + // void ICE(int val) noexcept(noexcept([val]{})); + // }; + Sema::SynthesizedFunctionScope Scope(Actions, FunctionToPush); + ExceptionSpecificationType EST = tryParseExceptionSpecification(/*Delayed=*/false, SpecificationRange, DynamicExceptions, diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp index b59cc175a1976..d50d05d17ab7a 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp @@ -113,8 +113,9 @@ namespace Static { static auto g() -> decltype(this->m); // expected-error{{'this' cannot be used in a static member function declaration}} static int h(); - - static int i() noexcept(noexcept(m + 2)); // expected-error{{'this' cannot be implicitly used in a static member function declaration}} + + // The use of 'm' doesn't constitute an ODR use, so we don't have a reason to reject it. + static int i() noexcept(noexcept(m + 2)); }; auto X1::h() -> decltype(m) { return 0; } // expected-error{{'this' cannot be implicitly used in a static member function declaration}} diff --git a/clang/test/CodeGenCXX/mangle-exception-spec.cpp b/clang/test/CodeGenCXX/mangle-exception-spec.cpp index 15f7a8b6cb504..1bc268e1b6ca4 100644 --- a/clang/test/CodeGenCXX/mangle-exception-spec.cpp +++ b/clang/test/CodeGenCXX/mangle-exception-spec.cpp @@ -47,3 +47,14 @@ template auto i<>(int()) -> int (*)(); // CHECK-CXX11: define {{.*}} @_Z1iIJfEEPDwiDpT_EFivEPS2_( // CHECK-CXX17: define {{.*}} @_Z1iIJfEEPDwiDpT_EFivES3_( template auto i<float>(int()) -> int (*)(); + +template <class T> +struct X1 { + T m; + static void j(int (X1::*)() noexcept(noexcept(m + 2))); +}; + +void foo() { + // CHECK-CXX17: call {{.*}} @_ZN2X1IiE1jEMS0_DoFivE( + X1<int>::j(nullptr); +} diff --git a/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp b/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp index c616a77f36619..53d23580d02a2 100644 --- a/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp +++ b/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp @@ -157,3 +157,11 @@ void f5() { // expected-error@-1 {{no member named 'non_existent' in 'typeid_::X<true>'}} } } // namespace typeid_ + +namespace GH97453 { + +struct X { + void ICE(int that) noexcept(noexcept([that]() {})); +}; + +} // namespace GH97453 >From 58f8ba2d6cb8809078059bbcab86d691e55efe4c Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Tue, 9 Jul 2024 12:53:39 +0800 Subject: [PATCH 2/5] Comments --- clang/lib/Parse/ParseCXXInlineMethods.cpp | 15 +++++++-------- .../expr/expr.prim/expr.prim.general/p3-0x.cpp | 5 ++++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index faab9c6b19caa..2df84e78d7f0e 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -523,14 +523,6 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { Actions, Method ? Method->getParent() : nullptr, Method ? Method->getMethodQualifiers() : Qualifiers{}, Method && getLangOpts().CPlusPlus11); - - // Parse the exception-specification. - SourceRange SpecificationRange; - SmallVector<ParsedType, 4> DynamicExceptions; - SmallVector<SourceRange, 4> DynamicExceptionRanges; - ExprResult NoexceptExpr; - CachedTokens *ExceptionSpecTokens; - // Push a function scope so that tryCaptureVariable() can properly visit // function scopes involving function parameters that are referenced inside // the noexcept specifier e.g. through a lambda expression. @@ -540,6 +532,13 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { // }; Sema::SynthesizedFunctionScope Scope(Actions, FunctionToPush); + // Parse the exception-specification. + SourceRange SpecificationRange; + SmallVector<ParsedType, 4> DynamicExceptions; + SmallVector<SourceRange, 4> DynamicExceptionRanges; + ExprResult NoexceptExpr; + CachedTokens *ExceptionSpecTokens; + ExceptionSpecificationType EST = tryParseExceptionSpecification(/*Delayed=*/false, SpecificationRange, DynamicExceptions, diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp index d50d05d17ab7a..203490632dffb 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp @@ -114,7 +114,10 @@ namespace Static { static int h(); - // The use of 'm' doesn't constitute an ODR use, so we don't have a reason to reject it. + // [expr.prim.id.general]p4: + // An id-expression that denotes a non-static data member... can only be used: + // ... + // (4.3) if that id-expression denotes a non-static data member and it appears in an unevaluated operand. static int i() noexcept(noexcept(m + 2)); }; >From 048d321b5d76ed723b606f947859bbbd10242c8d Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Tue, 9 Jul 2024 18:55:08 +0800 Subject: [PATCH 3/5] Fixup --- clang/lib/Parse/ParseCXXInlineMethods.cpp | 12 ++++++++---- .../CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp | 8 ++------ clang/test/CodeGenCXX/mangle-exception-spec.cpp | 11 ----------- 3 files changed, 10 insertions(+), 21 deletions(-) diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index 2df84e78d7f0e..2aa8562f3feee 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -519,10 +519,6 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { FunctionToPush = cast<FunctionDecl>(LM.Method); Method = dyn_cast<CXXMethodDecl>(FunctionToPush); - Sema::CXXThisScopeRAII ThisScope( - Actions, Method ? Method->getParent() : nullptr, - Method ? Method->getMethodQualifiers() : Qualifiers{}, - Method && getLangOpts().CPlusPlus11); // Push a function scope so that tryCaptureVariable() can properly visit // function scopes involving function parameters that are referenced inside // the noexcept specifier e.g. through a lambda expression. @@ -530,8 +526,16 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { // struct X { // void ICE(int val) noexcept(noexcept([val]{})); // }; + // Setup the CurScope to match the function DeclContext - we have such + // assumption in IsInFnTryBlockHandler(). + ParseScope FnScope(this, Scope::FnScope); Sema::SynthesizedFunctionScope Scope(Actions, FunctionToPush); + Sema::CXXThisScopeRAII ThisScope( + Actions, Method ? Method->getParent() : nullptr, + Method ? Method->getMethodQualifiers() : Qualifiers{}, + Method && getLangOpts().CPlusPlus11); + // Parse the exception-specification. SourceRange SpecificationRange; SmallVector<ParsedType, 4> DynamicExceptions; diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp index 203490632dffb..b59cc175a1976 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp @@ -113,12 +113,8 @@ namespace Static { static auto g() -> decltype(this->m); // expected-error{{'this' cannot be used in a static member function declaration}} static int h(); - - // [expr.prim.id.general]p4: - // An id-expression that denotes a non-static data member... can only be used: - // ... - // (4.3) if that id-expression denotes a non-static data member and it appears in an unevaluated operand. - static int i() noexcept(noexcept(m + 2)); + + static int i() noexcept(noexcept(m + 2)); // expected-error{{'this' cannot be implicitly used in a static member function declaration}} }; auto X1::h() -> decltype(m) { return 0; } // expected-error{{'this' cannot be implicitly used in a static member function declaration}} diff --git a/clang/test/CodeGenCXX/mangle-exception-spec.cpp b/clang/test/CodeGenCXX/mangle-exception-spec.cpp index 1bc268e1b6ca4..15f7a8b6cb504 100644 --- a/clang/test/CodeGenCXX/mangle-exception-spec.cpp +++ b/clang/test/CodeGenCXX/mangle-exception-spec.cpp @@ -47,14 +47,3 @@ template auto i<>(int()) -> int (*)(); // CHECK-CXX11: define {{.*}} @_Z1iIJfEEPDwiDpT_EFivEPS2_( // CHECK-CXX17: define {{.*}} @_Z1iIJfEEPDwiDpT_EFivES3_( template auto i<float>(int()) -> int (*)(); - -template <class T> -struct X1 { - T m; - static void j(int (X1::*)() noexcept(noexcept(m + 2))); -}; - -void foo() { - // CHECK-CXX17: call {{.*}} @_ZN2X1IiE1jEMS0_DoFivE( - X1<int>::j(nullptr); -} >From f9ff91eb4fe35ab40b0c27314340735100caf0c7 Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Tue, 9 Jul 2024 19:00:30 +0800 Subject: [PATCH 4/5] Add a case for setting up a Scope --- clang/test/SemaCXX/cxx0x-noexcept-expression.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp b/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp index 53d23580d02a2..b3c102830f359 100644 --- a/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp +++ b/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp @@ -160,6 +160,16 @@ void f5() { namespace GH97453 { +struct UnconstrainedCtor { + int value_; + + template <typename T> + constexpr UnconstrainedCtor(T value) noexcept(noexcept(value_ = value)) + : value_(static_cast<int>(value)) {} +}; + +UnconstrainedCtor U(42); + struct X { void ICE(int that) noexcept(noexcept([that]() {})); }; >From 4fba1d1e23490c380320ad6912bb5d28379efe77 Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Thu, 11 Jul 2024 13:11:30 +0800 Subject: [PATCH 5/5] Avoid setting extra flags --- clang/lib/Parse/ParseCXXInlineMethods.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index 2aa8562f3feee..9ccbbf9a7d5d0 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -529,7 +529,10 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { // Setup the CurScope to match the function DeclContext - we have such // assumption in IsInFnTryBlockHandler(). ParseScope FnScope(this, Scope::FnScope); - Sema::SynthesizedFunctionScope Scope(Actions, FunctionToPush); + Sema::ContextRAII FnContext(Actions, FunctionToPush, + /*NewThisContext=*/false); + Sema::FunctionScopeRAII PopFnContext(Actions); + Actions.PushFunctionScope(); Sema::CXXThisScopeRAII ThisScope( Actions, Method ? Method->getParent() : nullptr, _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits