[clang] [clang][CGRecordLayout] Remove dependency on isZeroSize (PR #96422)

Michael Buch via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 11 08:23:51 PDT 2024


Michael137 wrote:

> Some of the libc++ tests seem to be crashing on the x86_64 bot (can repro locally, on aarch64 too). Looks like they're segfaulting trying to access the member of an empty class. E.g., in
> 
> ```
> Process 1370440 stopped
> * thread #1, name = 't.tmp.exe', stop reason = signal SIGSEGV: invalid address (fault address: 0x20)
>     frame #0: 0x00005555555560c3 t.tmp.exe`std::__1::operator==[abi:se190000](__x=0x00007fffffffdd10, __y=0x00007fffffffdcd0) at error_code.h:97:25
>    94   }
>    95  
>    96   inline _LIBCPP_HIDE_FROM_ABI bool operator==(const error_code& __x, const error_condition& __y) _NOEXCEPT {
> -> 97     return __x.category().equivalent(__x.value(), __y) || __y.category().equivalent(__x, __y.value());
>    98   }
>    99  
>    100  #if _LIBCPP_STD_VER <= 17
> (lldb) dis -pc
> t.tmp.exe`std::__1::operator==[abi:se190000](std::__1::error_code const&, std::__1::error_condition const&):
> ->  0x5555555560c3 <+51>: callq  *0x20(%rax)
>     0x5555555560c6 <+54>: movb   %al, %cl
>     0x5555555560c8 <+56>: movb   $0x1, %al
>     0x5555555560ca <+58>: testb  $0x1, %cl
> (lldb) 
> ```
> 
> Investigating..

Reduced it to:
```
// We only crash if bar::func is virtual and Holder has a constexpr constructor

struct bar {
  virtual void func() const {}
};

struct Holder {
  bar m_bar;
  constexpr explicit Holder() : m_bar() {}
  ~Holder() {}
};

const bar &foo() noexcept {
  static Holder holder;
  return holder.m_bar;
}

int main() {
  foo().func();

  return 0;
}
```
What was happening is that `Holder` was being lowered to:
```
internal global %struct.Holder undef, align 8
```
instead of:
```
internal global %struct.Holder { %struct.bar { ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV3bar, i32 0, i32 0, i32 2) } }, align 8
```

This was happening because `isZeroSize` considers types with virtual bases/functions to not be zero-size (whereas the `isEmptyFieldForLayout` didn't account for that. Fixed this in the latest commit by checking whether the `CXXRecordDecl` is polymorphic

https://github.com/llvm/llvm-project/pull/96422


More information about the cfe-commits mailing list