<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [C++] Fix generation of __cxa_atexit"
   href="https://bugs.llvm.org/show_bug.cgi?id=48047">48047</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[C++] Fix generation of __cxa_atexit
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>OpenCL
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>anastasia.stulova@arm.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>anastasia.stulova@arm.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Currently global dtor callback registration stub has the prototype that ignores
pointer address spaces

i32 @__cxa_atexit(void (i8*)*, i8*, i8 addrspace(1)*)

The address space of object parameter of destructor and argument of
__cxa_atexit is not taken into account and therefore when address space appears
in the destructor or an object the generated IR is not functional.

Some ideas to fix this is proposed in <a href="https://reviews.llvm.org/D62413#1583079">https://reviews.llvm.org/D62413#1583079</a>.

This suggests that for OpenCL we could generate a custom function (one per each
global object to be destoried). This function will be passed into func ptr
parameter of __cxa_atexit instead of dtor itself how it is done now. The new
function will contain code to invoke dtor on the right object directly i.e. for
the following example

struct S {
  ~S(){};
};

S s;

The proposed IR generated equivalent should be:

void __dtor_s(){ // The naming scheme is to be determined
  ~S(s); // NOTE if address spaces are mismatched we need a conversion. Sema
should already check its validity (?)
}

void @__cxx_global_var_init()
{
  @__cxa_atexit(__dtor_S, null, null);
}

Note that currently clang doesn't generate __dtor_s() and it passes dtor itself
as an argument to @__cxa_atexit, see <a href="https://godbolt.org/z/4soT5r">https://godbolt.org/z/4soT5r</a>

The advantage of the proposed approach is that it can work for any address
space uniformly and it makes implementation of @__cxa_atexit for various addres
spaces very straight forward. There is no need to change default ABI at all.
However it might be good to standardise what clang generates in a long term.
This works for global variables and static local destruction too both in gloabl
and constant address spaces.

The drawback is that we need to generate an extra function for each global
object. To avoid this we could introduce some sort of overloading for 
@__cxa_atexit that could take dtor function with different parameters as well
as  object argument in different address spaces. It seems like a large change
to ABI and potentially not backward compatible. There could also be some hybrid
schemes where only @__cxa_atexit with address spaces is to be mangled. However
both options makes @__cxa_atexit implementation non-trivial.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>