<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/116096>116096</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            lifetime of `trivial_abi` parameters on the caller side
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          zygoloid
      </td>
    </tr>
</table>

<pre>
    Our documentation for `trivial_abi` doesn't specify the lifetime of the version of the parameter on the caller side. This affects a case such as:

```c++
struct __attribute__((trivial_abi)) sso_string {
  int size;
  char *data = is_sso() ? sso : new char[size];
  char sso[24];

  bool is_sso() const { return size < 24; }

  sso_string(const char *str) : size(__builtin_strlen(str)) {
    __builtin_memcpy(data, str, size + 1);
  }
  sso_string(const sso_string &str) : size(str.size) {
    __builtin_memcpy(data, str.data, size + 1);
  }
  ~sso_string() { if (!is_sso()) delete data; }
};
```

This is a classical example of a type that is *not* trivially relocatable. However, (other than `trivial_abi` implying `__is_trivially_relocatable`) this type might still satisfy the rules for `trivial_abi`: when passed into a function, the `data` pointer may point to a *different* object's `sso` buffer, but that's OK so long as the original object is still within its lifetime.

What do we want to happen here? I suppose we have a few options:

- Intentionally support such types. We'd need a way to annotate the above type to say "this is `trivial_abi`, but is *not* trivially-relocatable".
- Somewhat-support such types. This is the status quo, as far as I can tell: the caller-side parameter object exists throughout the call, so calls work. However, we also make `__is_trivially_relocatable(sso_string)` evaluate to `true`, so `std::vector<sso_string>` does *not* work.
- Intentionally do not support such types. Document that the caller-side parameter's lifetime ends *before* the call.

I think the third option is probably best. While the above is "clever", I don't think it's the kind of thing we intended for `trivial_abi` to support.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUVk1v4zYQ_TX0ZRBDomLZPvjgxA0a9LCHFtijQEkjiw1FquTIXu-hv70YSnaUjReLAkGsD87wzXtvhlIh6KNF3InVk1gdFmqg1vnd98vRGafrRenqy-7L4KF21dChJUXaWWicB5En5PVJK1OoUos8gdphsEKuCUKPlW4uQC2C0Q2S7hBcE-9P6APnmG575VWHhB6cjQ8qZQx6CLrGJfzV6gCqabCiAAoqFRDCULWggsj2IjmI5Po_T8a_Ssgn_otPA_mhIigKReR1ORAWhZAbITdz7HIr5BZCcEUgr-0RxHqKB9CWIOjvKLLbo6pVHoTc14oUiOwAOhQhuJh3CyJ74VQgsj1YPMfVYvUUc6wOP6bhuNWTfJy_ui4onTMfc1fOBmJ04JEGbyMyENkzyEeRPYFYHz6meK9JyM0YfUUfyI9w92N9clMU5aANacshBq2Qm3FRXPdOCcD7yg67qr8IuWEyhHyGGPE8AZNPkHL8e9E3hHexzSWQ-WeEgfxyvPxfgJa361-j-vcDrGkj0A3Eu3QuB7-s0SAhxA0-CLCe6Xm15lyb6GwdTW24CytlAL-prjexUxTQpUegVhGvEnJvHQm5h8m35gIejasUqdLgEn53ZzxhpF7IjaMWPQfbO22qu95cIsV5UhQ6FLeUxSwlw5VbIIYZoXT62BIE0sZAUKTD1N9-MBjuTwRW7tyihV6FgDX3kgMFzWArHiMMljOIPIn85Qn0TlueBZ26jNcQI7jZdNOgRxtJcOXfWJGQ68DBLEieQDnwCk5aDhSZiwu-_AHBgXH2CCrE_ZzXR22VmdIwv2NZZ02ttqAp3KbWcq7ZV1ajdnBGOKsRW6v6Hi206JEb_xXC0PcuIK9p1Qm5XDyD67ngH2fWA7xaQsuvoqIx1tM44Zj0sISvKOS6BotYg4KzukRGrHWkCGM5qnQnnOziIKgLCClpstdnTSZ-7pvqYe4AKZdXnH-6Ds-tood7EK9WZjCBFA0B_hkcb6QCNMrzzytUygKhMWyK9zn_wHN-fgiMkuA3HYgzejccWxf1HENiG7t4GeDs_NsH758RlAkOOvWGv_C33Mw7fcsOwpMyQ6TVjcQNODEW4oNANSuY7U9YkfMie56lyH67noEzYiPA-2LXDqyju5ofpsN2bP-fkhXtfTte0dZx5xIb5zGqOgV-8PArt7R9iy-p1b6evMkC9t6VqjQXKDHQEr622swtFi0jKzOSLZmXV6jdeOSPWfXYcxzzpm09HvI8a87I3Y-2xvonXw_s3ZGL5aLeZfU226oF7tJ1lq7kapNki3aHmKXbfLVWZb5KtukmrZu8wnW-3qSbKisfF3onE_mYpmmWbmUms6XKSpWhrNbYpOVqnYvHBDulzdKYU7d0_rjQIQy4S9M82eYLo0o0IX4NScmnd3zLxa4OC7_joIdyOAbxmBh26Hsa0mRwN__Y-VziTblw52NnMXiza4n6OCXki5AvR03tUC4r1wn5wjtNPw-9d-MAfIn4gpAvUwGnnfwvAAD__3trLuQ">