Skip to content

Commit 7cfeedf

Browse files
authored
[clang][bytecode] Change diagnostics for self-initialization (#141006)
Change the diagnostics when reading from the variable we're currently initializing do be the same as the one the current interpreter emits.
1 parent 4667209 commit 7cfeedf

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,21 @@ bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
669669

670670
if (const auto *VD = Ptr.getDeclDesc()->asVarDecl();
671671
VD && (VD->isConstexpr() || VD->hasGlobalStorage())) {
672+
673+
if (!S.getLangOpts().CPlusPlus23 && VD == S.EvaluatingDecl) {
674+
if (!S.getLangOpts().CPlusPlus14 &&
675+
!VD->getType().isConstant(S.getASTContext())) {
676+
// Diagnose as non-const read.
677+
diagnoseNonConstVariable(S, OpPC, VD);
678+
} else {
679+
const SourceInfo &Loc = S.Current->getSource(OpPC);
680+
// Diagnose as "read of object outside its lifetime".
681+
S.FFDiag(Loc, diag::note_constexpr_access_uninit)
682+
<< AK << /*IsIndeterminate=*/false;
683+
}
684+
return false;
685+
}
686+
672687
if (VD->getAnyInitializer()) {
673688
const SourceInfo &Loc = S.Current->getSource(OpPC);
674689
S.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << VD;

clang/test/AST/ByteCode/cxx11.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ int array2[recurse2]; // both-warning {{variable length arrays in C++}} \
2323
// expected-error {{variable length array declaration not allowed at file scope}} \
2424
// ref-warning {{variable length array folded to constant array as an extension}}
2525

26+
constexpr int b = b; // both-error {{must be initialized by a constant expression}} \
27+
// both-note {{read of object outside its lifetime is not allowed in a constant expression}}
28+
29+
30+
[[clang::require_constant_initialization]] int c = c; // both-error {{variable does not have a constant initializer}} \
31+
// both-note {{attribute here}} \
32+
// both-note {{read of non-const variable}} \
33+
// both-note {{declared here}}
34+
35+
2636
struct S {
2737
int m;
2838
};

clang/test/AST/ByteCode/cxx17.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++17 -verify=expected,both %s
2-
// RUN: %clang_cc1 -std=c++17 -verify=ref,both %s
1+
// RUN: %clang_cc1 -std=c++17 -verify=expected,both %s -fexperimental-new-constant-interpreter
2+
// RUN: %clang_cc1 -std=c++17 -verify=ref,both %s
3+
4+
[[clang::require_constant_initialization]] int cc = cc; // both-error {{variable does not have a constant initializer}} \
5+
// both-note {{attribute here}} \
6+
// both-note {{ead of object outside its lifetime}}
7+
38

49
struct F { int a; int b;};
510
constexpr F getF() {

0 commit comments

Comments
 (0)