llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) <details> <summary>Changes</summary> This can happen when the base pointer is an unknown size array, where !isOnePastEnd(), but isPastEnd(). Fixes #<!-- -->153990 --- Full diff: https://github.com/llvm/llvm-project/pull/154689.diff 2 Files Affected: - (modified) clang/lib/AST/ByteCode/Interp.h (+20-2) - (modified) clang/test/AST/ByteCode/arrays.cpp (+20) ``````````diff diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 149ce3b1042db..86fca7f652a47 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -1640,6 +1640,9 @@ bool InitField(InterpState &S, CodePtr OpPC, uint32_t I) { const Pointer &Ptr = S.Stk.peek<Pointer>(); if (!CheckRange(S, OpPC, Ptr, CSK_Field)) return false; + if (!CheckArray(S, OpPC, Ptr)) + return false; + const Pointer &Field = Ptr.atField(I); Field.deref<T>() = Value; Field.initialize(); @@ -1652,6 +1655,9 @@ bool InitFieldActivate(InterpState &S, CodePtr OpPC, uint32_t I) { const Pointer &Ptr = S.Stk.peek<Pointer>(); if (!CheckRange(S, OpPC, Ptr, CSK_Field)) return false; + if (!CheckArray(S, OpPC, Ptr)) + return false; + const Pointer &Field = Ptr.atField(I); Field.deref<T>() = Value; Field.activate(); @@ -1663,7 +1669,13 @@ template <PrimType Name, class T = typename PrimConv<Name>::T> bool InitBitField(InterpState &S, CodePtr OpPC, const Record::Field *F) { assert(F->isBitField()); const T &Value = S.Stk.pop<T>(); - const Pointer &Field = S.Stk.peek<Pointer>().atField(F->Offset); + const Pointer &Ptr = S.Stk.peek<Pointer>(); + if (!CheckRange(S, OpPC, Ptr, CSK_Field)) + return false; + if (!CheckArray(S, OpPC, Ptr)) + return false; + + const Pointer &Field = Ptr.atField(F->Offset); if constexpr (needsAlloc<T>()) { T Result = S.allocAP<T>(Value.bitWidth()); @@ -1689,7 +1701,13 @@ bool InitBitFieldActivate(InterpState &S, CodePtr OpPC, const Record::Field *F) { assert(F->isBitField()); const T &Value = S.Stk.pop<T>(); - const Pointer &Field = S.Stk.peek<Pointer>().atField(F->Offset); + const Pointer &Ptr = S.Stk.peek<Pointer>(); + if (!CheckRange(S, OpPC, Ptr, CSK_Field)) + return false; + if (!CheckArray(S, OpPC, Ptr)) + return false; + + const Pointer &Field = Ptr.atField(F->Offset); if constexpr (needsAlloc<T>()) { T Result = S.allocAP<T>(Value.bitWidth()); diff --git a/clang/test/AST/ByteCode/arrays.cpp b/clang/test/AST/ByteCode/arrays.cpp index 68102b42f3820..22a4b41041eb3 100644 --- a/clang/test/AST/ByteCode/arrays.cpp +++ b/clang/test/AST/ByteCode/arrays.cpp @@ -800,3 +800,23 @@ namespace ZeroSizeArrayRead { static_assert(s[0] == '0', ""); // both-error {{not an integral constant expression}} \ // both-note {{read of dereferenced one-past-the-end pointer}} } + +namespace FAM { + char *strchr(const char *, int); + + struct A { + char n, a[2]; + }; + struct B { + int n; + struct A a[]; // both-note {{here}} + }; + + const struct B b = {0, {{1, {2, 3}}, {4, {5, 6}}}}; + void foo(void) { int sch = 0 != strchr(b.a[1].a, '\0'); } + + int foo2() { + struct B b = {0, {{1, {2, 3}}, {4, {5, 6}}}}; // both-error {{initialization of flexible array member is not allowed}} + return 1; + } +} `````````` </details> https://github.com/llvm/llvm-project/pull/154689 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits