[PATCH] D155165: [clang][Interp] Fully serialize Floatings to bytes

Timm Bäder via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 13 02:29:21 PDT 2023


tbaeder created this revision.
tbaeder added reviewers: aaron.ballman, erichkeane, shafik, cor3ntin.
Herald added a project: All.
tbaeder requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This commit is a bit ugly at the moment since I'm gathering feedback.

The APFloats we use to implement the `Floating` type might heap-allocate stuff to represent large values. When we then later write those to bytecode (via `BytecodeEmitter`, not `EvalEmitter`), that heap allocation is dangling.

So, for code like

  constexpr long double f() {
    const long double L = __LDBL_MAX__;
  
    return L;
  };
  static_assert(f() == __LDBL_MAX__);

asan would complain:

  READ of size 8 at 0x602000001610 thread T0
      #0 0x7f525300b911 in llvm::APInt::tcAssign(unsigned long*, unsigned long const*, unsigned int) /home/tbaeder/code/llvm-project/llvm/lib/Support/APInt.cpp:2331:14
      #1 0x7f5252f3f640 in llvm::detail::IEEEFloat::copySignificand(llvm::detail::IEEEFloat const&) /home/tbaeder/code/llvm-project/llvm/lib/Support/APFloat.cpp:878:3
      #2 0x7f5252f3f42c in llvm::detail::IEEEFloat::assign(llvm::detail::IEEEFloat const&) /home/tbaeder/code/llvm-project/llvm/lib/Support/APFloat.cpp:871:5
      #3 0x7f5252f46828 in llvm::detail::IEEEFloat::IEEEFloat(llvm::detail::IEEEFloat const&) /home/tbaeder/code/llvm-project/llvm/lib/Support/APFloat.cpp:1143:3
      #4 0x7f5295e12913 in llvm::APFloat::Storage::Storage(llvm::APFloat::Storage const&) /home/tbaeder/code/llvm-project/llvm/include/llvm/ADT/APFloat.h:805:20
      #5 0x7f5295e01d3a in llvm::APFloat::APFloat(llvm::APFloat const&) /home/tbaeder/code/llvm-project/llvm/include/llvm/ADT/APFloat.h:928:3
      #6 0x7f5297d56584 in clang::interp::Floating::Floating(clang::interp::Floating const&) /home/tbaeder/code/llvm-project/clang/lib/AST/Interp/Floating.h:27:7
      #7 0x7f5297ea1fa0 in clang::interp::Floating llvm::support::endian::read<clang::interp::Floating, 1ul>(void const*, llvm::support::endianness) /home/tbaeder/code/llvm-project/llvm/include/llvm/Support/Endian.h:70:32
      #8 0x7f5297ea1e14 in clang::interp::Floating llvm::support::endian::read<clang::interp::Floating, (llvm::support::endianness)2, 1ul>(void const*) /home/tbaeder/code/llvm-project/llvm/include/llvm/Support/Endian.h:77:10
      #9 0x7f5297ea1d06 in std::enable_if<!std::is_pointer<clang::interp::Floating>::value, clang::interp::Floating>::type clang::interp::CodePtr::read<clang::interp::Floating>() /home/tbaeder/code/llvm-project/clang/lib/AST/Interp/Source.h:53:15
      #10 0x7f52981e7601 in clang::interp::Floating clang::interp::ReadArg<clang::interp::Floating>(clang::interp::InterpState&, clang::interp::CodePtr&) /home/tbaeder/code/llvm-project/clang/lib/AST/Interp/Interp.h:1894:17
  [...]
  
  freed by thread T0 here:
      #0 0x3d2511 in operator delete[](void*) (/home/tbaeder/code/llvm-project/build/bin/clang-17+0x3d2511) (BuildId: 88c1d01099b49a9ebf7bd913e201002fedf14f9b)
      #1 0x7f5252f3eff9 in llvm::detail::IEEEFloat::freeSignificand() /home/tbaeder/code/llvm-project/llvm/lib/Support/APFloat.cpp:861:5
      #2 0x7f5252f46968 in llvm::detail::IEEEFloat::~IEEEFloat() /home/tbaeder/code/llvm-project/llvm/lib/Support/APFloat.cpp:1150:27
      #3 0x7f5295e11ad1 in llvm::APFloat::Storage::~Storage() /home/tbaeder/code/llvm-project/llvm/include/llvm/ADT/APFloat.h:793:14
      #4 0x7f5295e01d9c in llvm::APFloat::~APFloat() /home/tbaeder/code/llvm-project/llvm/include/llvm/ADT/APFloat.h:931:22
      #5 0x7f5297d5ddb8 in clang::interp::Floating::~Floating() /home/tbaeder/code/llvm-project/clang/lib/AST/Interp/Floating.h:27:7
      #6 0x7f5297ea1fe7 in clang::interp::Floating llvm::support::endian::read<clang::interp::Floating, 1ul>(void const*, llvm::support::endianness) /home/tbaeder/code/llvm-project/llvm/include/llvm/Support/Endian.h:71:1
  [...]
  
  previously allocated by thread T0 here:
      #0 0x3d1cb1 in operator new[](unsigned long) (/home/tbaeder/code/llvm-project/build/bin/clang-17+0x3d1cb1) (BuildId: 88c1d01099b49a9ebf7bd913e201002fedf14f9b)
      #1 0x7f5252f3ed6a in llvm::detail::IEEEFloat::initialize(llvm::fltSemantics const*) /home/tbaeder/code/llvm-project/llvm/lib/Support/APFloat.cpp:856:25
      #2 0x7f5252f467e7 in llvm::detail::IEEEFloat::IEEEFloat(llvm::detail::IEEEFloat const&) /home/tbaeder/code/llvm-project/llvm/lib/Support/APFloat.cpp:1142:3
      #3 0x7f5295e12913 in llvm::APFloat::Storage::Storage(llvm::APFloat::Storage const&) /home/tbaeder/code/llvm-project/llvm/include/llvm/ADT/APFloat.h:805:20
      #4 0x7f5295e01d3a in llvm::APFloat::APFloat(llvm::APFloat const&) /home/tbaeder/code/llvm-project/llvm/include/llvm/ADT/APFloat.h:928:3
      #5 0x7f5297d56584 in clang::interp::Floating::Floating(clang::interp::Floating const&) /home/tbaeder/code/llvm-project/clang/lib/AST/Interp/Floating.h:27:7
      #6 0x7f5297d17f93 in void emit<clang::interp::Floating>(clang::interp::Program&, std::__debug::vector<std::byte, std::allocator<std::byte>>&, clang::interp::Floating const&, bool&) /home/tbaeder/code/llvm-project/clang/lib/AST/Interp/ByteCodeEmitter.cpp:202:32

So, this patch adds specialized `readArg()` and `emit()` versions for `Floating` that serializes the `APFloat`.

I'm not really sure if this is the best way to go though.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D155165

Files:
  clang/lib/AST/Interp/ByteCodeEmitter.cpp
  clang/lib/AST/Interp/Floating.h
  clang/lib/AST/Interp/Interp.h
  clang/lib/AST/Interp/Source.h
  clang/test/AST/Interp/floats.cpp

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D155165.539905.patch
Type: text/x-patch
Size: 3140 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230713/a81693e0/attachment-0001.bin>


More information about the cfe-commits mailing list