Skip to content

Commit 54826d4

Browse files
committed
[clang][Interp] Emit dummy pointers for unknown static locals
We used to emit dummy pointers for unknown declarations in certain cases in C, but this is also necessary in C++. I'm limiting this to static local variables for now.
1 parent 9c6a2de commit 54826d4

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3239,9 +3239,14 @@ bool ByteCodeExprGen<Emitter>::VisitDeclRefExpr(const DeclRefExpr *E) {
32393239
return this->emitGetPtrThisField(Offset, E);
32403240
}
32413241

3242-
// Lazily visit global declarations we haven't seen yet.
3243-
// This happens in C.
3244-
if (!Ctx.getLangOpts().CPlusPlus) {
3242+
// Try to lazily visit (or emit dummy pointers for) declarations
3243+
// we haven't seen yet.
3244+
if (Ctx.getLangOpts().CPlusPlus) {
3245+
if (const auto *VD = dyn_cast<VarDecl>(D); VD && VD->isStaticLocal()) {
3246+
if (std::optional<unsigned> I = P.getOrCreateDummy(D))
3247+
return this->emitGetPtrGlobal(*I, E);
3248+
}
3249+
} else {
32453250
if (const auto *VD = dyn_cast<VarDecl>(D);
32463251
VD && VD->getAnyInitializer() && VD->getType().isConstQualified()) {
32473252
if (!this->visitVarDecl(VD))

clang/test/AST/Interp/functions.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,3 +523,23 @@ namespace Move {
523523
constexpr int A = std::move(5);
524524
static_assert(A == 5, "");
525525
}
526+
527+
namespace StaticLocals {
528+
void test() {
529+
static int j; // both-note {{declared here}}
530+
static_assert(&j != nullptr, ""); // both-warning {{always true}}
531+
532+
static_assert(j == 0, ""); // both-error {{not an integral constant expression}} \
533+
// both-note {{read of non-const variable 'j'}}
534+
535+
static int k = 0; // both-note {{declared here}}
536+
static_assert(k == 0, ""); // both-error {{not an integral constant expression}} \
537+
// both-note {{read of non-const variable 'k'}}
538+
539+
static const int l = 12;
540+
static_assert(l == 12, "");
541+
542+
static const int m; // both-error {{default initialization}}
543+
static_assert(m == 0, "");
544+
}
545+
}

0 commit comments

Comments
 (0)