[clang] [clang]use correct this scope to evaluate noexcept expr (PR #77416)

Congcong Cai via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 9 00:27:42 PST 2024


https://github.com/HerrCai0907 updated https://github.com/llvm/llvm-project/pull/77416

>From 0637a482c881f5ce31fd1debbc8dcc40a05c66ba Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0907 at 163.com>
Date: Tue, 9 Jan 2024 14:53:25 +0800
Subject: [PATCH 1/3] [clang]use correct this scope to evaluate noexcept expr
 when deduce template

Fixes: #77411
When substituting deduced type, noexcept expr in function decl should be instantiated and evaluated.
ThisScrope should be switched to method context
---
 clang/docs/ReleaseNotes.rst                       |  3 ++-
 clang/lib/Sema/TreeTransform.h                    |  6 ++++++
 .../test/SemaCXX/cxx1z-noexcept-function-type.cpp | 15 +++++++++++++++
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 803eb2f7c74cf6..2695a0e30f58e0 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -610,7 +610,8 @@ Bug Fixes in This Version
   of template classes. Fixes
   (`#68543 <https://github.com/llvm/llvm-project/issues/68543>`_,
   `#42496 <https://github.com/llvm/llvm-project/issues/42496>`_,
-  `#77071 <https://github.com/llvm/llvm-project/issues/77071>`_)
+  `#77071 <https://github.com/llvm/llvm-project/issues/77071>`_,
+  `#77411 <https://github.com/llvm/llvm-project/issues/77411>`_)
 - Fixed an issue when a shift count larger than ``__INT64_MAX__``, in a right
   shift operation, could result in missing warnings about
   ``shift count >= width of type`` or internal compiler error.
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index c8c5a51bf9f94e..fb7e15b5bcbb02 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -6192,6 +6192,12 @@ bool TreeTransform<Derived>::TransformExceptionSpec(
 
   // Instantiate a dynamic noexcept expression, if any.
   if (isComputedNoexcept(ESI.Type)) {
+    // Update this scrope because ContextDecl in Sema will be used in TransformExpr.
+    auto *Method = dyn_cast_or_null<CXXMethodDecl>(ESI.SourceTemplate);
+    Sema::CXXThisScopeRAII ThisScope(
+        SemaRef, Method ? Method->getParent() : nullptr,
+        Method ? Method->getMethodQualifiers() : Qualifiers{},
+        Method != nullptr);
     EnterExpressionEvaluationContext Unevaluated(
         getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
     ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
diff --git a/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp b/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp
index 11b1093f9064f6..5e56f19477d6ca 100644
--- a/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp
+++ b/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp
@@ -64,6 +64,21 @@ namespace DependentDefaultCtorExceptionSpec {
   struct A { multimap<int> Map; } a;
 
   static_assert(noexcept(A()));
+
+  template <class> struct NoexceptWithThis {
+    int ca;
+    template <class T> auto foo(T) noexcept(ca) { return true; }
+    // expected-error at -1 {{noexcept specifier argument is not a constant expression}}
+    // expected-note at -2 {{in instantiation of exception specification}}
+    // expected-note at -3 {{implicit use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function}}
+  };
+  struct InstantiateFromAnotherClass {
+    template <class B, class T = decltype(static_cast<bool (B::*)(int)>(&B::foo))> // expected-note {{in instantiation of function template specialization}}
+    InstantiateFromAnotherClass(B *) {} // expected-note {{in instantiation of default argument}}
+  };
+  NoexceptWithThis<int> f{};
+  // Don't crash here.
+  InstantiateFromAnotherClass b{&f}; // expected-note {{while substituting deduced template arguments into function template}}
 }
 
 #endif

>From 80b07ef334b9fdb0699d156e58eb13c8835d835a Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0907 at 163.com>
Date: Tue, 9 Jan 2024 15:54:54 +0800
Subject: [PATCH 2/3] fix format

---
 clang/lib/Sema/TreeTransform.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index fb7e15b5bcbb02..9dc0c55518ae21 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -6192,7 +6192,8 @@ bool TreeTransform<Derived>::TransformExceptionSpec(
 
   // Instantiate a dynamic noexcept expression, if any.
   if (isComputedNoexcept(ESI.Type)) {
-    // Update this scrope because ContextDecl in Sema will be used in TransformExpr.
+    // Update this scrope because ContextDecl in Sema will be used in
+    // TransformExpr.
     auto *Method = dyn_cast_or_null<CXXMethodDecl>(ESI.SourceTemplate);
     Sema::CXXThisScopeRAII ThisScope(
         SemaRef, Method ? Method->getParent() : nullptr,

>From edaee6a67f296dae7dd6ab5defbeab32a1d34724 Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0907 at 163.com>
Date: Tue, 9 Jan 2024 16:27:24 +0800
Subject: [PATCH 3/3] avoid use deprecated API

---
 clang/lib/Sema/TreeTransform.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 9dc0c55518ae21..e7a6550b1c993c 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -6194,7 +6194,7 @@ bool TreeTransform<Derived>::TransformExceptionSpec(
   if (isComputedNoexcept(ESI.Type)) {
     // Update this scrope because ContextDecl in Sema will be used in
     // TransformExpr.
-    auto *Method = dyn_cast_or_null<CXXMethodDecl>(ESI.SourceTemplate);
+    auto *Method = dyn_cast_if_present<CXXMethodDecl>(ESI.SourceTemplate);
     Sema::CXXThisScopeRAII ThisScope(
         SemaRef, Method ? Method->getParent() : nullptr,
         Method ? Method->getMethodQualifiers() : Qualifiers{},



More information about the cfe-commits mailing list