[clang] f52a467 - [Clang] Ensure the method scope at the late parsing of noexcept specifiers (#98023)

via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 11 18:51:49 PDT 2024


Author: Younan Zhang
Date: 2024-07-12T09:51:46+08:00
New Revision: f52a4679e683807d699e105a6139a5a91401667f

URL: https://github.com/llvm/llvm-project/commit/f52a4679e683807d699e105a6139a5a91401667f
DIFF: https://github.com/llvm/llvm-project/commit/f52a4679e683807d699e105a6139a5a91401667f.diff

LOG: [Clang] Ensure the method scope at the late parsing of noexcept specifiers (#98023)

Previously, we only pushed the function scope once we entered the
function definition, whereas tryCaptureVariable() requires at least one
function scope available when ParmVarDecls being captured have been
owned by a function. This led to problems parsing the noexcept
specifiers, as the DeclRefExprs inside them were improperly computed.

Fixes https://github.com/llvm/llvm-project/issues/97453

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Parse/ParseCXXInlineMethods.cpp
    clang/test/SemaCXX/cxx0x-noexcept-expression.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index be2f06766a755..e68398c167a23 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1011,7 +1011,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 a crash in constraint instantiation under nested lambdas with dependent parameters.
 - Fixed handling of brace ellison when building deduction guides. (#GH64625), (#GH83368).
 - Clang now instantiates local constexpr functions eagerly for constant evaluators. (#GH35052), (#GH94849)

diff  --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 943ce0fdde3a3..9ccbbf9a7d5d0 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -511,11 +511,28 @@ 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);
+
+    // 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]{}));
+    // };
+    // Setup the CurScope to match the function DeclContext - we have such
+    // assumption in IsInFnTryBlockHandler().
+    ParseScope FnScope(this, Scope::FnScope);
+    Sema::ContextRAII FnContext(Actions, FunctionToPush,
+                                /*NewThisContext=*/false);
+    Sema::FunctionScopeRAII PopFnContext(Actions);
+    Actions.PushFunctionScope();
 
     Sema::CXXThisScopeRAII ThisScope(
         Actions, Method ? Method->getParent() : nullptr,

diff  --git a/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp b/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp
index b9aeffbf034b2..a01edc77e02af 100644
--- a/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp
+++ b/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp
@@ -157,3 +157,21 @@ void f5() {
   // expected-error at -1 {{no member named 'non_existent' in 'typeid_::X<true>'}}
 }
 } // namespace typeid_
+
+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]() {}));
+};
+
+} // namespace GH97453


        


More information about the cfe-commits mailing list