Author: Timm Bäder Date: 2022-09-29T12:50:55+02:00 New Revision: df1cc801da05a6436f6dc3062ccd490f236cd7ec
URL: https://github.com/llvm/llvm-project/commit/df1cc801da05a6436f6dc3062ccd490f236cd7ec DIFF: https://github.com/llvm/llvm-project/commit/df1cc801da05a6436f6dc3062ccd490f236cd7ec.diff LOG: [clang][Interp] Record item types in InterpStack The type information is lost when pushing things on the stack. When later pop()ing items of the wrong type, we can instead simply get garbage values and those problems are hard to find. Add another stack to record the type of item we pushed and use that for debugging. Differential Revision: https://reviews.llvm.org/D133941 Added: Modified: clang/lib/AST/Interp/InterpStack.h Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/InterpStack.h b/clang/lib/AST/Interp/InterpStack.h index 2888f88fe6d7..7c338aa3e0ab 100644 --- a/clang/lib/AST/Interp/InterpStack.h +++ b/clang/lib/AST/Interp/InterpStack.h @@ -13,7 +13,9 @@ #ifndef LLVM_CLANG_AST_INTERP_INTERPSTACK_H #define LLVM_CLANG_AST_INTERP_INTERPSTACK_H +#include "PrimType.h" #include <memory> +#include <vector> namespace clang { namespace interp { @@ -29,10 +31,18 @@ class InterpStack final { /// Constructs a value in place on the top of the stack. template <typename T, typename... Tys> void push(Tys &&... Args) { new (grow(aligned_size<T>())) T(std::forward<Tys>(Args)...); +#ifndef NDEBUG + ItemTypes.push_back(toPrimType<T>()); +#endif } /// Returns the value from the top of the stack and removes it. template <typename T> T pop() { +#ifndef NDEBUG + assert(!ItemTypes.empty()); + assert(ItemTypes.back() == toPrimType<T>()); + ItemTypes.pop_back(); +#endif auto *Ptr = &peek<T>(); auto Value = std::move(*Ptr); Ptr->~T(); @@ -42,6 +52,10 @@ class InterpStack final { /// Discards the top value from the stack. template <typename T> void discard() { +#ifndef NDEBUG + assert(ItemTypes.back() == toPrimType<T>()); + ItemTypes.pop_back(); +#endif auto *Ptr = &peek<T>(); Ptr->~T(); shrink(aligned_size<T>()); @@ -108,6 +122,45 @@ class InterpStack final { StackChunk *Chunk = nullptr; /// Total size of the stack. size_t StackSize = 0; + +#ifndef NDEBUG + /// vector recording the type of data we pushed into the stack. + std::vector<PrimType> ItemTypes; + + template <typename T> static constexpr PrimType toPrimType() { + if constexpr (std::is_same_v<T, Pointer>) + return PT_Ptr; + else if constexpr (std::is_same_v<T, bool> || + std::is_same_v<T, Boolean>) + return PT_Bool; + else if constexpr (std::is_same_v<T, int8_t> || + std::is_same_v<T, Integral<8, true>>) + return PT_Sint8; + else if constexpr (std::is_same_v<T, uint8_t> || + std::is_same_v<T, Integral<8, false>>) + return PT_Uint8; + else if constexpr (std::is_same_v<T, int16_t> || + std::is_same_v<T, Integral<16, true>>) + return PT_Sint16; + else if constexpr (std::is_same_v<T, uint16_t> || + std::is_same_v<T, Integral<16, false>>) + return PT_Uint16; + else if constexpr (std::is_same_v<T, int32_t> || + std::is_same_v<T, Integral<32, true>>) + return PT_Sint32; + else if constexpr (std::is_same_v<T, uint32_t> || + std::is_same_v<T, Integral<32, false>>) + return PT_Uint32; + else if constexpr (std::is_same_v<T, int64_t> || + std::is_same_v<T, Integral<64, true>>) + return PT_Sint64; + else if constexpr (std::is_same_v<T, uint64_t> || + std::is_same_v<T, Integral<64, false>>) + return PT_Uint64; + + llvm_unreachable("unknown type push()'ed into InterpStack"); + } +#endif }; } // namespace interp _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits