Author: Timm Bäder Date: 2024-07-13T07:25:47+02:00 New Revision: 66e6df22b5a509c16e50364d72b1a40bacaea91a
URL: https://github.com/llvm/llvm-project/commit/66e6df22b5a509c16e50364d72b1a40bacaea91a DIFF: https://github.com/llvm/llvm-project/commit/66e6df22b5a509c16e50364d72b1a40bacaea91a.diff LOG: [clang][Interp] Fix one-past-end pointers going back into the block Added: Modified: clang/lib/AST/Interp/Interp.h clang/test/AST/Interp/records.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 83c7e98c2dda0..1df8d65c80445 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -1844,6 +1844,15 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset, else Result = WideIndex - WideOffset; + // When the pointer is one-past-end, going back to index 0 is the only + // useful thing we can do. Any other index has been diagnosed before and + // we don't get here. + if (Result == 0 && Ptr.isOnePastEnd()) { + S.Stk.push<Pointer>(Ptr.asBlockPointer().Pointee, + Ptr.asBlockPointer().Base); + return true; + } + S.Stk.push<Pointer>(Ptr.atIndex(static_cast<uint64_t>(Result))); return true; } diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp index adc3799a20ce4..4b06fc7522d45 100644 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -1500,3 +1500,15 @@ namespace LocalWithThisPtrInit { } static_assert(foo() == 2, ""); } + +namespace OnePastEndAndBack { + struct Base { + constexpr Base() {} + int n = 0; + }; + + constexpr Base a; + constexpr const Base *c = &a + 1; + constexpr const Base *d = c - 1; + static_assert(d == &a, ""); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits