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

    <tr>
        <th>Summary</th>
        <td>
            Unexpected reference to sugar type through constructor call in include-cleaner
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang-include-cleaner
      </td>
    </tr>

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

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

<pre>
    a minimal repro looks like:
```cpp
struct Foo { Foo(int); };
using Bar = Foo;
void bar(Bar);
void foo() {
  bar({3}); // Here we've a reference to Bar, not to Foo.
}
```

Despite things look like expected above, a real world scenario looks like:
```cpp
// mytype.h
struct MyType { MyType(int); };

// container_base.h
template <typename T> struct ContainerBase {
  using ElementT = T;
};

// container.h
#include "container_base.h"
template <typename T> struct Container : public ContainerBase<T> {
void insert(const typename ContainerBase<T>::ElementT&);
};

// foo.cc
#include "container.h"
#include "mytype.h"

void foo() {
 Container<MyType> T;
  T.insert({42}); // Here we've got a reference to ElementT, not MyType.
}
```

In the real world example, it's completely unexpected (at least to me) that we need to depend on "container_base.h".
but unfortunately this goes both ways, there are certainly cases that look like first one, a more realistic example could be:

```cpp
template <typename T> struct basic_string { basic_string (const T*); };
using string = basic_string<char>;
void foo(const string&);
void bar() {
   foo({nullptr}); // here i'd rather have a reference to string rather than basic_string.
}
```

So far attributing constructor calls to the sugared type seemed to be working in practice, but i think we'll definitely have more encounters with cases that look suspicious.

I can't see any heuristics with the current examples we have (hopefully we'll accumulate more soon), but one alternative without any heuristics could be to treat all constructor calls as ambiguous references to the sugar type.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUVsFy4jgQ_Rpx6QoFcsBw4BDCULuHPW32PNWWG1sbWXJJrWT4-y3JhuBkMpOtSkGQpX79nt5rwBB0Y4l2YrUXq8MMI7fO756x1l4RzypXn3cInba6QwOeeu_AOPccwOhnEsWDWBzE4kGsF8Of6vthJbCPiuHoHIhyn96F3GjLQm5FsQdRHkSxH7bGoG0De_QgikPeeXny4nQNFXohN_v0up0-OeWiQm4TxLAO43ZR7ouEMaLJo5BH-IM8wSsJWb4QIHg6kSerCNhBrv8I1nH6dHRuPjIrD-8ojh_z64FCr5mAW22bkJXJwgD96Ekx1YCVe6FUOeGhgVfnTQ1BkUWvv6jl2H535nNP83Yi8F_np3NPWePh309lntRSzjJqS_57heFak6nrDTKBKB4TlsWO4EkU32BEe7wc22OgW9WHO_xmqCPLT_kin96Qf9vFpQEhC22ViTWBkPJDk1L-3z5BFA_Qx8poNW1eFI_5wJVDdpS2gTwLuVHOBoZr7Z8dTRdWPFwoC7m-9eenlE_OzZX6JdsbotMdVwNcH_86C9euRfE4mqP4dnMvAE_zK2NR7u_lryPTOH4fmzf6Q3YGmC9l508L3NJtKugHdr3JadEsZBlAubTAZM4Q7TVTQm6QwRCGHNaOEm1ukeGVwBLVabWmnmwNzn7ipLHHKjJEe3Keo8UMxK0O0DgKUDlu4RXPIXXEbZICPYEin4qZMygMFAbkt-iftA8Mzo6p75wfSOrAWl04gnLR1FDdxP6T8P_W6xUGrb4H9imBaQ5MFy5efhLy4dPhe9lcHCanRfGoWvTZ7B8H71B33Dm1_83gfjeeL0Yt9zYa07P_YLmssxayrMFjUh1a_Divx47HHdyinXT-JQf-7eCEHpDZ6ypyqpc5JVmdB4XGhISVbBpigz45K03bQNQNLqsoefc5HdUWeo-Ktco3n4yl8xfD8xAgY6Cmk7Y6uyxzyt4gq1y0TD7Aq-b2g6lCDL1W2sUwn8QHFFohS07dANoztBR9NtlYKLWtovdk-WK7kBKSoYXctK6nUzTmfO0PlYpdzG7LrQXnbLqckY6zBGiYvEXWL5RRXOT34BdrZ-k8IQMa8xNlMQB2lW6ii-HtcqeKZ73ns3pX1NtiizPaLdflerVal5v1rN2tqtV2UcuyOK3kZluftrhYLu83lVSnUq3rcqZ3ciGLhVyul_fLYrGel8tNsV4gLpVcLrfrQtwvqENt5sa8dHPnm5kOIdJuvdgs5cxgRSbkX0dSKoO2uRvn8Z0yhGm0Spl-OPldOn9XxSaI-0XKeniryJoN7f55G2BTJ195Arfexab9oFXy1jvcWfRm1zL3IU2QnJxGcxuruXKdkMcEPr7d9d79S4qFPGZuQchjpvdfAAAA__-YUybO">