This is an archive of the discontinued LLVM Phabricator instance.

[clang][Interp] Fully serialize Floatings to bytes
ClosedPublic

Authored by tbaeder on Jul 13 2023, 2:29 AM.

Details

Summary

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.

Diff Detail

Event Timeline

tbaeder created this revision.Jul 13 2023, 2:29 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 13 2023, 2:29 AM
tbaeder requested review of this revision.Jul 13 2023, 2:29 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 13 2023, 2:29 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
aaron.ballman accepted this revision.Jul 28 2023, 8:33 AM

LGTM aside from some small nits.

clang/lib/AST/Interp/Source.h
64–65

Any chance we can use friendship here as well, rather than exposing the data member directly?

clang/test/AST/Interp/floats.cpp
146–172

Probably makes sense to add a __float128 test as well given that it's also a pretty large float type: https://godbolt.org/z/n8roa96jc

This revision is now accepted and ready to land.Jul 28 2023, 8:33 AM
tbaeder updated this revision to Diff 545353.Jul 29 2023, 2:51 AM
tbaeder marked 2 inline comments as done.
tbaeder added inline comments.Jul 29 2023, 6:43 AM
clang/lib/AST/Interp/Source.h
64–65

added a operator* to CodePtr.

This revision was landed with ongoing or failed builds.Aug 17 2023, 3:44 AM
This revision was automatically updated to reflect the committed changes.