Skip to content

Commit a3390c4

Browse files
committed
[Clang] Static member initializers are not immediate escalating context.
Per CWG2760, default members initializers should be consider part the body of consstructors, which mean they are evaluated in an immediate escalating context. However, this does not apply to static members. This patch produces some extraneous diagnostics, unfortunately we do not have a good way to report an error back to the initializer and this is a preexisting issue Fixes #65985
1 parent 69b056d commit a3390c4

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,10 @@ Bug Fixes to C++ Support
281281
a non-template inner-class between the function and the class template.
282282
(`#65810 <https://github.com/llvm/llvm-project/issues/65810>`_)
283283

284+
- Fix a crash when calling a non-constant immediate function
285+
in the initializer of a static data member.
286+
(`#65985 <https://github.com/llvm/llvm-project/issues/65985>_`).
287+
284288
Bug Fixes to AST Handling
285289
^^^^^^^^^^^^^^^^^^^^^^^^^
286290
- Fixed an import failure of recursive friend class template.

clang/lib/Parse/ParseDeclCXX.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3230,13 +3230,21 @@ ExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction,
32303230
assert(Tok.isOneOf(tok::equal, tok::l_brace) &&
32313231
"Data member initializer not starting with '=' or '{'");
32323232

3233+
bool IsFieldInitialization = isa_and_present<FieldDecl>(D);
3234+
32333235
EnterExpressionEvaluationContext Context(
32343236
Actions,
3235-
isa_and_present<FieldDecl>(D)
3237+
IsFieldInitialization
32363238
? Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed
32373239
: Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
32383240
D);
3239-
Actions.ExprEvalContexts.back().InImmediateEscalatingFunctionContext = true;
3241+
3242+
// CWG2760
3243+
// Default member initializers used to initialize a base or member subobject
3244+
// [...] are considered to be part of the function body
3245+
Actions.ExprEvalContexts.back().InImmediateEscalatingFunctionContext =
3246+
IsFieldInitialization;
3247+
32403248
if (TryConsumeToken(tok::equal, EqualLoc)) {
32413249
if (Tok.is(tok::kw_delete)) {
32423250
// In principle, an initializer of '= delete p;' is legal, but it will

clang/test/SemaCXX/cxx2b-consteval-propagate.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,3 +330,26 @@ struct S {
330330
S s(0); // expected-note {{in the default initializer of 'j'}}
331331

332332
}
333+
334+
namespace GH65985 {
335+
336+
int consteval operator""_foo(unsigned long long V) {
337+
return 0;
338+
}
339+
int consteval operator""_bar(unsigned long long V); // expected-note 3{{here}}
340+
341+
struct C {
342+
static const int a = 1_foo;
343+
static constexpr int b = 1_foo;
344+
static const int c = 1_bar; // expected-error {{call to consteval function 'GH65985::operator""_bar' is not a constant expression}} \
345+
// expected-note {{undefined function 'operator""_bar' cannot be used in a constant expression}} \
346+
// expected-error {{in-class initializer for static data member is not a constant expression}}
347+
348+
// FIXME: remove duplicate diagnostics
349+
static constexpr int d = 1_bar; // expected-error {{call to consteval function 'GH65985::operator""_bar' is not a constant expression}} \
350+
// expected-note {{undefined function 'operator""_bar' cannot be used in a constant expression}} \
351+
// expected-error {{constexpr variable 'd' must be initialized by a constant expression}} \
352+
// expected-note {{undefined function 'operator""_bar' cannot be used in a constant expression}}
353+
};
354+
355+
}

0 commit comments

Comments
 (0)