diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ByteCode/Compiler.cpp | 11 | ||||
-rw-r--r-- | clang/lib/AST/ByteCode/Interp.h | 19 | ||||
-rw-r--r-- | clang/lib/AST/ByteCode/InterpBuiltin.cpp | 3 | ||||
-rw-r--r-- | clang/lib/AST/ByteCode/Opcodes.td | 2 |
4 files changed, 31 insertions, 4 deletions
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 9a1e61b..fe8d05c 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -1862,6 +1862,13 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits, if (Inits.size() == 1 && QT == Inits[0]->getType()) return this->delegate(Inits[0]); + const ConstantArrayType *CAT = + Ctx.getASTContext().getAsConstantArrayType(QT); + uint64_t NumElems = CAT->getZExtSize(); + + if (!this->emitCheckArraySize(NumElems, E)) + return false; + unsigned ElementIndex = 0; for (const Expr *Init : Inits) { if (const auto *EmbedS = @@ -1890,10 +1897,6 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits, // Expand the filler expression. // FIXME: This should go away. if (ArrayFiller) { - const ConstantArrayType *CAT = - Ctx.getASTContext().getAsConstantArrayType(QT); - uint64_t NumElems = CAT->getZExtSize(); - for (; ElementIndex != NumElems; ++ElementIndex) { if (!this->visitArrayElemInit(ElementIndex, ArrayFiller)) return false; diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 6cd9952..80488b5 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -175,6 +175,8 @@ bool handleFixedPointOverflow(InterpState &S, CodePtr OpPC, bool isConstexprUnknown(const Pointer &P); +inline bool CheckArraySize(InterpState &S, CodePtr OpPC, uint64_t NumElems); + enum class ShiftDir { Left, Right }; /// Checks if the shift operation is legal. @@ -3110,6 +3112,9 @@ inline bool AllocN(InterpState &S, CodePtr OpPC, PrimType T, const Expr *Source, } assert(NumElements.isPositive()); + if (!CheckArraySize(S, OpPC, static_cast<uint64_t>(NumElements))) + return false; + DynamicAllocator &Allocator = S.getAllocator(); Block *B = Allocator.allocate(Source, T, static_cast<size_t>(NumElements), @@ -3140,6 +3145,9 @@ inline bool AllocCN(InterpState &S, CodePtr OpPC, const Descriptor *ElementDesc, } assert(NumElements.isPositive()); + if (!CheckArraySize(S, OpPC, static_cast<uint64_t>(NumElements))) + return false; + DynamicAllocator &Allocator = S.getAllocator(); Block *B = Allocator.allocate(ElementDesc, static_cast<size_t>(NumElements), @@ -3246,6 +3254,17 @@ inline bool CheckDestruction(InterpState &S, CodePtr OpPC) { return CheckDestructor(S, OpPC, Ptr); } +inline bool CheckArraySize(InterpState &S, CodePtr OpPC, uint64_t NumElems) { + uint64_t Limit = S.getLangOpts().ConstexprStepLimit; + if (NumElems > Limit) { + S.FFDiag(S.Current->getSource(OpPC), + diag::note_constexpr_new_exceeds_limits) + << NumElems << Limit; + return false; + } + return true; +} + //===----------------------------------------------------------------------===// // Read opcode arguments //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index e3d7632..0b4585a 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -1533,6 +1533,9 @@ static bool interp__builtin_operator_new(InterpState &S, CodePtr OpPC, return false; } + if (!CheckArraySize(S, OpPC, NumElems.getZExtValue())) + return false; + bool IsArray = NumElems.ugt(1); std::optional<PrimType> ElemT = S.getContext().classify(ElemType); DynamicAllocator &Allocator = S.getAllocator(); diff --git a/clang/lib/AST/ByteCode/Opcodes.td b/clang/lib/AST/ByteCode/Opcodes.td index e717902..65a9a0c 100644 --- a/clang/lib/AST/ByteCode/Opcodes.td +++ b/clang/lib/AST/ByteCode/Opcodes.td @@ -414,6 +414,8 @@ def CheckLiteralType : Opcode { let Args = [ArgTypePtr]; } +def CheckArraySize : Opcode { let Args = [ArgUint64]; } + // [] -> [Value] def GetGlobal : AccessOpcode; def GetGlobalUnchecked : AccessOpcode; |