[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.
This commit is contained in:
parent
7b91df3868
commit
c0422733e3
@ -6532,14 +6532,13 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
|
|||||||
if (DiscardResult)
|
if (DiscardResult)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
|
if (const auto *ECD = dyn_cast<EnumConstantDecl>(D))
|
||||||
return this->emitConst(ECD->getInitVal(), E);
|
return this->emitConst(ECD->getInitVal(), E);
|
||||||
} else if (const auto *BD = dyn_cast<BindingDecl>(D)) {
|
if (const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
|
||||||
return this->visit(BD->getBinding());
|
|
||||||
} else if (const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
|
|
||||||
const Function *F = getFunction(FuncDecl);
|
const Function *F = getFunction(FuncDecl);
|
||||||
return F && this->emitGetFnPtr(F, E);
|
return F && this->emitGetFnPtr(F, E);
|
||||||
} else if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(D)) {
|
}
|
||||||
|
if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(D)) {
|
||||||
if (std::optional<unsigned> Index = P.getOrCreateGlobal(D)) {
|
if (std::optional<unsigned> Index = P.getOrCreateGlobal(D)) {
|
||||||
if (!this->emitGetPtrGlobal(*Index, E))
|
if (!this->emitGetPtrGlobal(*Index, E))
|
||||||
return false;
|
return false;
|
||||||
@ -6560,13 +6559,15 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
|
|||||||
// value.
|
// value.
|
||||||
bool IsReference = D->getType()->isReferenceType();
|
bool IsReference = D->getType()->isReferenceType();
|
||||||
|
|
||||||
// Check for local/global variables and parameters.
|
// Local variables.
|
||||||
if (auto It = Locals.find(D); It != Locals.end()) {
|
if (auto It = Locals.find(D); It != Locals.end()) {
|
||||||
const unsigned Offset = It->second.Offset;
|
const unsigned Offset = It->second.Offset;
|
||||||
if (IsReference)
|
if (IsReference)
|
||||||
return this->emitGetLocal(classifyPrim(E), Offset, E);
|
return this->emitGetLocal(classifyPrim(E), Offset, E);
|
||||||
return this->emitGetPtrLocal(Offset, E);
|
return this->emitGetPtrLocal(Offset, E);
|
||||||
} else if (auto GlobalIndex = P.getGlobal(D)) {
|
}
|
||||||
|
// Global variables.
|
||||||
|
if (auto GlobalIndex = P.getGlobal(D)) {
|
||||||
if (IsReference) {
|
if (IsReference) {
|
||||||
if (!Ctx.getLangOpts().CPlusPlus11)
|
if (!Ctx.getLangOpts().CPlusPlus11)
|
||||||
return this->emitGetGlobal(classifyPrim(E), *GlobalIndex, E);
|
return this->emitGetGlobal(classifyPrim(E), *GlobalIndex, E);
|
||||||
@ -6574,7 +6575,9 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return this->emitGetPtrGlobal(*GlobalIndex, E);
|
return this->emitGetPtrGlobal(*GlobalIndex, E);
|
||||||
} else if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
|
}
|
||||||
|
// Function parameters.
|
||||||
|
if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
|
||||||
if (auto It = this->Params.find(PVD); It != this->Params.end()) {
|
if (auto It = this->Params.find(PVD); It != this->Params.end()) {
|
||||||
if (IsReference || !It->second.IsPtr)
|
if (IsReference || !It->second.IsPtr)
|
||||||
return this->emitGetParam(classifyPrim(E), It->second.Offset, E);
|
return this->emitGetParam(classifyPrim(E), It->second.Offset, E);
|
||||||
@ -6600,7 +6603,7 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
|
|||||||
return this->visitDeclRef(D, E);
|
return this->visitDeclRef(D, E);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle lambda captures.
|
// Lambda captures.
|
||||||
if (auto It = this->LambdaCaptures.find(D);
|
if (auto It = this->LambdaCaptures.find(D);
|
||||||
It != this->LambdaCaptures.end()) {
|
It != this->LambdaCaptures.end()) {
|
||||||
auto [Offset, IsPtr] = It->second;
|
auto [Offset, IsPtr] = It->second;
|
||||||
@ -6608,12 +6611,17 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
|
|||||||
if (IsPtr)
|
if (IsPtr)
|
||||||
return this->emitGetThisFieldPtr(Offset, E);
|
return this->emitGetThisFieldPtr(Offset, E);
|
||||||
return this->emitGetPtrThisField(Offset, E);
|
return this->emitGetPtrThisField(Offset, E);
|
||||||
} else if (const auto *DRE = dyn_cast<DeclRefExpr>(E);
|
}
|
||||||
DRE && DRE->refersToEnclosingVariableOrCapture()) {
|
|
||||||
|
if (const auto *DRE = dyn_cast<DeclRefExpr>(E);
|
||||||
|
DRE && DRE->refersToEnclosingVariableOrCapture()) {
|
||||||
if (const auto *VD = dyn_cast<VarDecl>(D); VD && VD->isInitCapture())
|
if (const auto *VD = dyn_cast<VarDecl>(D); VD && VD->isInitCapture())
|
||||||
return revisit(VD);
|
return revisit(VD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (const auto *BD = dyn_cast<BindingDecl>(D))
|
||||||
|
return this->visit(BD->getBinding());
|
||||||
|
|
||||||
// Avoid infinite recursion.
|
// Avoid infinite recursion.
|
||||||
if (D == InitializingDecl)
|
if (D == InitializingDecl)
|
||||||
return this->emitDummyPtr(D, E);
|
return this->emitDummyPtr(D, E);
|
||||||
@ -6666,7 +6674,7 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
|
|||||||
if (VD->evaluateValue())
|
if (VD->evaluateValue())
|
||||||
return revisit(VD);
|
return revisit(VD);
|
||||||
|
|
||||||
if (!D->getType()->isReferenceType())
|
if (!IsReference)
|
||||||
return this->emitDummyPtr(D, E);
|
return this->emitDummyPtr(D, E);
|
||||||
|
|
||||||
return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
|
return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -fcxx-exceptions
|
// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -fcxx-exceptions
|
||||||
// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s -DCPP14_AND_EARLIER -fcxx-exceptions
|
// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s -DCPP14_AND_EARLIER -fcxx-exceptions
|
||||||
|
|
||||||
|
// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks %s -fcxx-exceptions -fexperimental-new-constant-interpreter
|
||||||
|
// RUN: %clang_cc1 -std=c++20 -verify -fsyntax-only -fblocks %s -fcxx-exceptions -fexperimental-new-constant-interpreter
|
||||||
|
// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -fcxx-exceptions -fexperimental-new-constant-interpreter
|
||||||
|
// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s -DCPP14_AND_EARLIER -fcxx-exceptions -fexperimental-new-constant-interpreter
|
||||||
|
|
||||||
namespace test_lambda_is_literal {
|
namespace test_lambda_is_literal {
|
||||||
#ifdef CPP14_AND_EARLIER
|
#ifdef CPP14_AND_EARLIER
|
||||||
|
Loading…
x
Reference in New Issue
Block a user