llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Younan Zhang (zyn0217)

<details>
<summary>Changes</summary>

Previously, we only pushed the method scope once we entered the function 
definition, whereas tryCaptureVariable() requires at least one function scope 
available when being called. This led to problems parsing the noexcept 
specifiers, as the DeclRefs inside them were improperly computed.

As a bonus, this also fixes an implementation glitch of C++11 
[expr.prim.general]p3: we shouldn't add an implicit 'this' to expressions 
inside noexcept specifiers.

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


---
Full diff: https://github.com/llvm/llvm-project/pull/98023.diff


5 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+1-1) 
- (modified) clang/lib/Parse/ParseCXXInlineMethods.cpp (+13-2) 
- (modified) clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp (+3-2) 
- (modified) clang/test/CodeGenCXX/mangle-exception-spec.cpp (+11) 
- (modified) clang/test/SemaCXX/cxx0x-noexcept-expression.cpp (+8) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 838cb69f647ee2..b521de4515e1f4 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 943ce0fdde3a38..faab9c6b19caac 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 b59cc175a1976f..d50d05d17ab7a1 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 15f7a8b6cb5048..1bc268e1b6ca44 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 c616a77f36619a..53d23580d02a28 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

``````````

</details>


https://github.com/llvm/llvm-project/pull/98023
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to