Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
11 changes: 11 additions & 0 deletions clang/lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3283,6 +3283,11 @@ 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();

// - a function that results from the instantiation of a templated entity
// defined with the constexpr specifier.
TemplatedKind TK = getTemplatedKind();
Expand All @@ -3303,6 +3308,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();
Expand Down
32 changes: 32 additions & 0 deletions clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,3 +496,35 @@ struct Y {
template void g<Y>();

}

namespace GH112677 {

class ConstEval {
public:
consteval ConstEval(int); // expected-note 2{{declared here}}
};

struct TemplateCtor {
ConstEval val;
template <class Anything = int> constexpr
TemplateCtor(int arg) : val(arg) {} // expected-note {{undefined constructor 'ConstEval'}}
};
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@-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@-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@-1 {{call to immediate function 'GH112677::D::SimpleCtor' is not a constant expression}}

}
Loading