Index: clang/lib/AST/Interp/ByteCodeEmitter.h =================================================================== --- clang/lib/AST/Interp/ByteCodeEmitter.h +++ clang/lib/AST/Interp/ByteCodeEmitter.h @@ -68,11 +68,10 @@ /// Callback for local registration. Local createLocal(Descriptor *D); - /// Parameter indices. - llvm::DenseMap Params; + /// Parameter indices. > + llvm::DenseMap Params; /// Lambda captures. - /// Map from Decl* to [Offset, IsReference] pair. - llvm::DenseMap> LambdaCaptures; + llvm::DenseMap LambdaCaptures; unsigned LambdaThisCapture; /// Local descriptors. llvm::SmallVector, 2> Descriptors; Index: clang/lib/AST/Interp/ByteCodeEmitter.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeEmitter.cpp +++ clang/lib/AST/Interp/ByteCodeEmitter.cpp @@ -74,13 +74,14 @@ // Assign descriptors to all parameters. // Composite objects are lowered to pointers. for (const ParmVarDecl *PD : FuncDecl->parameters()) { - PrimType Ty = Ctx.classify(PD->getType()).value_or(PT_Ptr); - Descriptor *Desc = P.createDescriptor(PD, Ty); - ParamDescriptors.insert({ParamOffset, {Ty, Desc}}); - Params.insert({PD, ParamOffset}); + std::optional T = Ctx.classify(PD->getType()); + PrimType PT = T.value_or(PT_Ptr); + Descriptor *Desc = P.createDescriptor(PD, PT); + ParamDescriptors.insert({ParamOffset, {PT, Desc}}); + Params.insert({PD, {ParamOffset, T != std::nullopt}}); ParamOffsets.push_back(ParamOffset); - ParamOffset += align(primSize(Ty)); - ParamTypes.push_back(Ty); + ParamOffset += align(primSize(PT)); + ParamTypes.push_back(PT); } // Create a handle over the emitted code. Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1273,7 +1273,7 @@ llvm::function_ref Indirect) { auto It = this->Params.find(PD); if (It != this->Params.end()) { - unsigned Idx = It->second; + unsigned Idx = It->second.Offset; switch (AK) { case DerefKind::Read: return DiscardResult ? true : this->emitGetParam(T, Idx, LV); @@ -2253,18 +2253,19 @@ return this->emitGetPtrGlobal(*GlobalIndex, E); } else if (const auto *PVD = dyn_cast(D)) { if (auto It = this->Params.find(PVD); It != this->Params.end()) { - if (IsReference) - return this->emitGetParamPtr(It->second, E); - return this->emitGetPtrParam(It->second, E); + if (IsReference || !It->second.IsPtr) + return this->emitGetParamPtr(It->second.Offset, E); + + return this->emitGetPtrParam(It->second.Offset, E); } } // Handle lambda captures. if (auto It = this->LambdaCaptures.find(D); It != this->LambdaCaptures.end()) { - auto [Offset, IsReference] = It->second; + auto [Offset, IsPtr] = It->second; - if (IsReference) + if (IsPtr) return this->emitGetThisFieldPtr(Offset, E); return this->emitGetPtrThisField(Offset, E); } Index: clang/lib/AST/Interp/ByteCodeStmtGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeStmtGen.cpp +++ clang/lib/AST/Interp/ByteCodeStmtGen.cpp @@ -125,7 +125,7 @@ // We do the lvalue-to-rvalue conversion manually here, so no need // to care about references. PrimType ParamType = this->classify(PVD->getType()).value_or(PT_Ptr); - if (!this->emitGetParam(ParamType, It->second, MD)) + if (!this->emitGetParam(ParamType, It->second.Offset, MD)) return false; } Index: clang/lib/AST/Interp/Context.h =================================================================== --- clang/lib/AST/Interp/Context.h +++ clang/lib/AST/Interp/Context.h @@ -31,6 +31,11 @@ class State; enum PrimType : unsigned; +struct ParamOffset { + unsigned Offset; + bool IsPtr; +}; + /// Holds all information required to evaluate constexpr code in a module. class Context final { public: Index: clang/lib/AST/Interp/Context.cpp =================================================================== --- clang/lib/AST/Interp/Context.cpp +++ clang/lib/AST/Interp/Context.cpp @@ -27,6 +27,8 @@ Context::~Context() {} bool Context::isPotentialConstantExpr(State &Parent, const FunctionDecl *FD) { + llvm::errs() << __PRETTY_FUNCTION__ << "\n"; + FD->dump(); assert(Stk.empty()); Function *Func = P->getFunction(FD); if (!Func || !Func->hasBody()) { @@ -51,6 +53,9 @@ } bool Context::evaluateAsRValue(State &Parent, const Expr *E, APValue &Result) { + llvm::errs() << __PRETTY_FUNCTION__ << "\n"; + E->dump(); + assert(Stk.empty()); ByteCodeExprGen C(*this, *P, Parent, Stk, Result); if (Check(Parent, C.interpretExpr(E))) { Index: clang/lib/AST/Interp/EvalEmitter.h =================================================================== --- clang/lib/AST/Interp/EvalEmitter.h +++ clang/lib/AST/Interp/EvalEmitter.h @@ -75,10 +75,9 @@ } /// Parameter indices. - llvm::DenseMap Params; + llvm::DenseMap Params; /// Lambda captures. - /// Map from Decl* to [Offset, IsReference] pair. - llvm::DenseMap> LambdaCaptures; + llvm::DenseMap LambdaCaptures; unsigned LambdaThisCapture; /// Local descriptors. llvm::SmallVector, 2> Descriptors; Index: clang/test/AST/Interp/lambda.cpp =================================================================== --- clang/test/AST/Interp/lambda.cpp +++ clang/test/AST/Interp/lambda.cpp @@ -103,10 +103,7 @@ return a; } - /// FIXME: This should work in the new interpreter. -#if 0 - static_assert(foo() == 1); // expected-error {{not an integral constant expression}} -#endif + static_assert(foo() == 1); } namespace LambdasAsParams { Index: clang/test/AST/Interp/records.cpp =================================================================== --- clang/test/AST/Interp/records.cpp +++ clang/test/AST/Interp/records.cpp @@ -896,9 +896,7 @@ } -#if 0 constexpr bool BPand(BoolPair bp) { return bp.first && bp.second; } static_assert(BPand(BoolPair{true, false}) == false, ""); -#endif