[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:58:21 PST 2025
https://github.com/cor3ntin updated https://github.com/llvm/llvm-project/pull/112860
>From 04846ad527b4558bd334b6502264c34fc405f205 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 | 1 +
clang/lib/AST/Decl.cpp | 13 ++++++++++++
.../SemaCXX/cxx2b-consteval-propagate.cpp | 21 +++++++++++++++++++
3 files changed, 35 insertions(+)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cad17c1b3957b6..c749e34d6d2c5d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -971,6 +971,7 @@ Bug Fixes to C++ Support
- 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)
- Fixed various false diagnostics related to the use of immediate functions. (#GH123472)
+- 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 a1a51d38b93e1f..507f7f9a6dccaf 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 f22b065c3bb88c615f9700f63e1dc449f13af2a2 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 507f7f9a6dccaf..8764cb4f5c3d39 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 b10d359e44dd100bc537f38f1a852bab113835d9 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 8764cb4f5c3d39..ddde16ada5af88 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