<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 - Debugger stops twice for delegating (complete -> base) constructors"
   href="https://bugs.llvm.org/show_bug.cgi?id=38338">38338</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Debugger stops twice for delegating (complete -> base) constructors
          </td>
        </tr>

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

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

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

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

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>LLVM Codegen
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>labath@google.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>aprantl@apple.com, brock.wyma@intel.com, dblaikie@gmail.com, echristo@gmail.com, jdevlieghere@apple.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Under some circumstances(*) clang will emit the complete (C1) constructor
variant as a delegate call to the base (C2) variant. In this case the C1
variant doesn't really do anything, and is probably uniteresting for most
people. However, from a debugger POV, these are separate functions, and both of
them have line numbers associated with them.

So if a user sets a breakpoint at the "right line" in the constructor, this
breakpoint will resolve to both functions, and will be hit twice (once for each
variant), even though there is only one object being constructed. This behavior
can be confusing/annoying to the user.

Fixing this from the debugger side is tricky, because the debugger doesn't know
that the C1 variant is just a shim around C2. Theoretically, we could
disassemble the C1 function and check for calls to C2, but things could quickly
get messy(**).

Therefore, I think it's best to fix this from the compiler side. I think the
best solution is to not emit line table entries for the C1 shim constructor (or
even better emit them as line 0, reserved for compiler-generated code). I think
this would make sense, as there really is no user code in that function. I've
tried implementing this idea, and it seemed achievable, though the patch ended
up being fairly messy, because I needed to duplicate the logic for detecting
when a constructor will delegate. I also don't know if there is anything else
which might be depending on the current behavior.



(*) I think this used to be limited to apple targets, which don't set the
-mconstructor-aliases cc1 option. However, after r337456 (which tries to solve
a different debug info problem), it started happening in other cases too. This
means another option would be to revert that commit, which would restore the
previous behavior for elf, but it wouldn't help the apple targets. It also
might be possible to rework that patch to emit C1->C2 aliases (instead of
shims) in more cases, but that also won't work on apple, as it cannot use
aliases for some reason.



(**) A convoluted example:

struct A { A(...); };

struct B: public A {
  B() __attribute__((always_inline)) : A() {}
};

bool rand();

inline A::A(...) { if(rand()) B(); }

A a;

Here the C1 variant for class A will contain a call to the C2 variant. However,
it would be wrong to skip setting a breakpoint in C1 because this is not a shim
constructor (we cannot emit delegating shims for varargs constructors).</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>