[clang] [Clang] Fix handling of immediate escalation for inherited constructors (PR #112860)

via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 22 00:57:04 PST 2025


https://github.com/cor3ntin updated https://github.com/llvm/llvm-project/pull/112860

>From b801140617023cda9fb2dcbb0a4098e2af94c42f Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Fri, 18 Oct 2024 10:59:35 +0200
Subject: [PATCH 1/3] '[Clang] Fix handling of immediate escalation for
 inherited constructors

Fixes #112677
---
 clang/docs/ReleaseNotes.rst                   |  2 +-
 clang/lib/AST/Decl.cpp                        | 13 ++++++++++++
 .../SemaCXX/cxx2b-consteval-propagate.cpp     | 21 +++++++++++++++++++
 3 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f19be0446d3fec..e12def1cd06bf7 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -968,7 +968,7 @@ Bug Fixes to C++ Support
   constraints are applied. (#GH122134)
 - Fixed canonicalization of pack indexing types - Clang did not always recognized identical pack indexing. (#GH123033)
 - Fixed a nested lambda substitution issue for constraint evaluation. (#GH123441)
-
+- Fix immediate escalation not propagating through inherited constructors.  (#GH112677)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index f641a72ed26448..cff4ec73f5244a 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -3283,6 +3283,13 @@ bool FunctionDecl::isImmediateEscalating() const {
   // consteval specifier,
   if (isDefaulted() && !isConsteval())
     return true;
+
+  if (auto *CD = dyn_cast<CXXConstructorDecl>(this);
+      CD && CD->isInheritingConstructor())
+    return CD->getInheritedConstructor()
+        .getConstructor()
+        ->isImmediateEscalating();
+
   // - a function that results from the instantiation of a templated entity
   // defined with the constexpr specifier.
   TemplatedKind TK = getTemplatedKind();
@@ -3303,6 +3310,12 @@ bool FunctionDecl::isImmediateFunction() const {
   if (isImmediateEscalating() && BodyContainsImmediateEscalatingExpressions())
     return true;
 
+  if (auto *CD = dyn_cast<CXXConstructorDecl>(this);
+      CD && CD->isInheritingConstructor())
+    return CD->getInheritedConstructor()
+        .getConstructor()
+        ->isImmediateFunction();
+
   if (const auto *MD = dyn_cast<CXXMethodDecl>(this);
       MD && MD->isLambdaStaticInvoker())
     return MD->getParent()->getLambdaCallOperator()->isImmediateFunction();
diff --git a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
index 378414f1361729..187a4958a2ee62 100644
--- a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
+++ b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
@@ -496,3 +496,24 @@ struct Y {
 template void g<Y>();
 
 }
+
+namespace GH112677 {
+
+class ConstEval {
+ public:
+  consteval ConstEval(int); // expected-note {{declared here}}
+};
+
+struct B {
+    ConstEval val;
+    template <class Anything = int> constexpr
+    B(int arg) : val(arg) {} // expected-note {{undefined constructor 'ConstEval'}}
+};
+struct C : B {
+    using B::B; // expected-note {{in call to 'B<int>(0)'}}
+};
+
+C c(0); // expected-note{{in implicit initialization for inherited constructor of 'C'}}
+// expected-error at -1 {{call to immediate function 'GH112677::C::B' is not a constant expression}}
+
+}

>From 8790c5bf97c7106ab0fd5528cc567652b32ead5c Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Sun, 20 Oct 2024 09:24:02 +0200
Subject: [PATCH 2/3] wip

---
 clang/include/clang/Sema/Sema.h | 2 +-
 clang/lib/AST/Decl.cpp          | 7 +++----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 9fa33d6ca76ba5..9a9998b114e0f7 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -13086,7 +13086,7 @@ class Sema final : public SemaBase {
       auto *FD = dyn_cast<FunctionDecl>(DC);
       S.PushFunctionScope();
       S.PushExpressionEvaluationContext(
-          (FD && FD->isConsteval())
+          (FD && FD->isImmediateFunction())
               ? ExpressionEvaluationContext::ImmediateFunctionContext
               : ExpressionEvaluationContext::PotentiallyEvaluated);
       if (FD) {
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index cff4ec73f5244a..52c44782405801 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -3285,10 +3285,9 @@ bool FunctionDecl::isImmediateEscalating() const {
     return true;
 
   if (auto *CD = dyn_cast<CXXConstructorDecl>(this);
-      CD && CD->isInheritingConstructor())
-    return CD->getInheritedConstructor()
-        .getConstructor()
-        ->isImmediateEscalating();
+      CD && CD->isInheritingConstructor() &&
+      CD->getInheritedConstructor().getConstructor()->isImmediateEscalating())
+    return true;
 
   // - a function that results from the instantiation of a templated entity
   // defined with the constexpr specifier.

>From f8bc77e323fbe8aec990909870d03a00382b09c4 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Wed, 22 Jan 2025 09:56:19 +0100
Subject: [PATCH 3/3] Fix the non-termplate case

---
 clang/lib/AST/Decl.cpp                        |  5 ++--
 .../SemaCXX/cxx2b-consteval-propagate.cpp     | 23 ++++++++++++++-----
 2 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 52c44782405801..c367519c72be1d 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -3285,9 +3285,8 @@ bool FunctionDecl::isImmediateEscalating() const {
     return true;
 
   if (auto *CD = dyn_cast<CXXConstructorDecl>(this);
-      CD && CD->isInheritingConstructor() &&
-      CD->getInheritedConstructor().getConstructor()->isImmediateEscalating())
-    return true;
+      CD && CD->isInheritingConstructor())
+    return CD->getInheritedConstructor().getConstructor();
 
   // - a function that results from the instantiation of a templated entity
   // defined with the constexpr specifier.
diff --git a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
index 187a4958a2ee62..3f3123eaee76b6 100644
--- a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
+++ b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
@@ -501,19 +501,30 @@ namespace GH112677 {
 
 class ConstEval {
  public:
-  consteval ConstEval(int); // expected-note {{declared here}}
+  consteval ConstEval(int); // expected-note 2{{declared here}}
 };
 
-struct B {
+struct TemplateCtor {
     ConstEval val;
     template <class Anything = int> constexpr
-    B(int arg) : val(arg) {} // expected-note {{undefined constructor 'ConstEval'}}
+    TemplateCtor(int arg) : val(arg) {} // expected-note {{undefined constructor 'ConstEval'}}
 };
-struct C : B {
-    using B::B; // expected-note {{in call to 'B<int>(0)'}}
+struct C : TemplateCtor {
+    using TemplateCtor::TemplateCtor; // expected-note {{in call to 'TemplateCtor<int>(0)'}}
 };
 
 C c(0); // expected-note{{in implicit initialization for inherited constructor of 'C'}}
-// expected-error at -1 {{call to immediate function 'GH112677::C::B' is not a constant expression}}
+// expected-error at -1 {{call to immediate function 'GH112677::C::TemplateCtor' is not a constant expression}}
+
+struct SimpleCtor { constexpr SimpleCtor(int) {}};
+struct D : SimpleCtor {
+    int y = 10;
+    ConstEval x = y; // expected-note {{undefined constructor 'ConstEval'}}
+    using SimpleCtor::SimpleCtor;
+    //expected-note at -1 {{'SimpleCtor' is an immediate constructor because the default initializer of 'x' contains a call to a consteval constructor 'ConstEval' and that call is not a constant expression}}
+};
+
+D d(0); // expected-note {{in implicit initialization for inherited constructor of 'D'}}
+// expected-error at -1 {{call to immediate function 'GH112677::D::SimpleCtor' is not a constant expression}}
 
 }



More information about the cfe-commits mailing list