Skip to content

Commit c042273

Browse files
authored
[clang][bytecode] Check lambda captures before binding decls (#148130)
If the given decls is a lambda capture (but also a BindingDecl), handle it as a lambda capture instead of a BindingDecl.
1 parent 7b91df3 commit c042273

File tree

2 files changed

+24
-12
lines changed

2 files changed

+24
-12
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6532,14 +6532,13 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
65326532
if (DiscardResult)
65336533
return true;
65346534

6535-
if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
6535+
if (const auto *ECD = dyn_cast<EnumConstantDecl>(D))
65366536
return this->emitConst(ECD->getInitVal(), E);
6537-
} else if (const auto *BD = dyn_cast<BindingDecl>(D)) {
6538-
return this->visit(BD->getBinding());
6539-
} else if (const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
6537+
if (const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
65406538
const Function *F = getFunction(FuncDecl);
65416539
return F && this->emitGetFnPtr(F, E);
6542-
} else if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(D)) {
6540+
}
6541+
if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(D)) {
65436542
if (std::optional<unsigned> Index = P.getOrCreateGlobal(D)) {
65446543
if (!this->emitGetPtrGlobal(*Index, E))
65456544
return false;
@@ -6560,21 +6559,25 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
65606559
// value.
65616560
bool IsReference = D->getType()->isReferenceType();
65626561

6563-
// Check for local/global variables and parameters.
6562+
// Local variables.
65646563
if (auto It = Locals.find(D); It != Locals.end()) {
65656564
const unsigned Offset = It->second.Offset;
65666565
if (IsReference)
65676566
return this->emitGetLocal(classifyPrim(E), Offset, E);
65686567
return this->emitGetPtrLocal(Offset, E);
6569-
} else if (auto GlobalIndex = P.getGlobal(D)) {
6568+
}
6569+
// Global variables.
6570+
if (auto GlobalIndex = P.getGlobal(D)) {
65706571
if (IsReference) {
65716572
if (!Ctx.getLangOpts().CPlusPlus11)
65726573
return this->emitGetGlobal(classifyPrim(E), *GlobalIndex, E);
65736574
return this->emitGetGlobalUnchecked(classifyPrim(E), *GlobalIndex, E);
65746575
}
65756576

65766577
return this->emitGetPtrGlobal(*GlobalIndex, E);
6577-
} else if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
6578+
}
6579+
// Function parameters.
6580+
if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
65786581
if (auto It = this->Params.find(PVD); It != this->Params.end()) {
65796582
if (IsReference || !It->second.IsPtr)
65806583
return this->emitGetParam(classifyPrim(E), It->second.Offset, E);
@@ -6600,20 +6603,25 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
66006603
return this->visitDeclRef(D, E);
66016604
};
66026605

6603-
// Handle lambda captures.
6606+
// Lambda captures.
66046607
if (auto It = this->LambdaCaptures.find(D);
66056608
It != this->LambdaCaptures.end()) {
66066609
auto [Offset, IsPtr] = It->second;
66076610

66086611
if (IsPtr)
66096612
return this->emitGetThisFieldPtr(Offset, E);
66106613
return this->emitGetPtrThisField(Offset, E);
6611-
} else if (const auto *DRE = dyn_cast<DeclRefExpr>(E);
6612-
DRE && DRE->refersToEnclosingVariableOrCapture()) {
6614+
}
6615+
6616+
if (const auto *DRE = dyn_cast<DeclRefExpr>(E);
6617+
DRE && DRE->refersToEnclosingVariableOrCapture()) {
66136618
if (const auto *VD = dyn_cast<VarDecl>(D); VD && VD->isInitCapture())
66146619
return revisit(VD);
66156620
}
66166621

6622+
if (const auto *BD = dyn_cast<BindingDecl>(D))
6623+
return this->visit(BD->getBinding());
6624+
66176625
// Avoid infinite recursion.
66186626
if (D == InitializingDecl)
66196627
return this->emitDummyPtr(D, E);
@@ -6666,7 +6674,7 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
66666674
if (VD->evaluateValue())
66676675
return revisit(VD);
66686676

6669-
if (!D->getType()->isReferenceType())
6677+
if (!IsReference)
66706678
return this->emitDummyPtr(D, E);
66716679

66726680
return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),

clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -fcxx-exceptions
44
// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s -DCPP14_AND_EARLIER -fcxx-exceptions
55

6+
// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks %s -fcxx-exceptions -fexperimental-new-constant-interpreter
7+
// RUN: %clang_cc1 -std=c++20 -verify -fsyntax-only -fblocks %s -fcxx-exceptions -fexperimental-new-constant-interpreter
8+
// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -fcxx-exceptions -fexperimental-new-constant-interpreter
9+
// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s -DCPP14_AND_EARLIER -fcxx-exceptions -fexperimental-new-constant-interpreter
610

711
namespace test_lambda_is_literal {
812
#ifdef CPP14_AND_EARLIER

0 commit comments

Comments
 (0)