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

    <tr>
        <th>Summary</th>
        <td>
            UBSan vptr check nuisance reports when calling member functions of COM interfaces
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            compiler-rt:ubsan,
            platform:windows,
            compiler-rt:sanitizer
      </td>
    </tr>

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

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

<pre>
    When calling member functions of COM interfaces, the vptr check gets triggered. Demo:

```c++
#include <windows.h>
#include <shlobj.h>

int main(int argc, char *argv[]) {
    CoInitialize(nullptr);
 IShellLinkW *shell_link;
    CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, __uuidof(IShellLinkW), (void **)&shell_link);
 shell_link->SetPath(L"C:\\");
    IPersistFile *persist_file;
 shell_link->QueryInterface(__uuidof(IPersistFile), (void **)&persist_file);
    wchar_t path[4096];
 GetFullPathNameW(L"vptr_test.lnk", 4096, path, nullptr);
 persist_file->Save(path, false);
    return 0;
}
```

Using [llvm-mingw](https://github.com/mstorsjo/llvm-mingw):

```console
> clang++ -fsanitize=undefined,vptr vptr_test.cpp -o vptr_test.exe -lole32

> vptr_test.exe
vptr_test.cpp:8:17: runtime error: member call on address 0x0255481a1ca0 which does not point to an object of type 'IShellLinkW'
0x0255481a1ca0: note: object has a possibly invalid vptr: abs(offset to top) too big
 fe 7f 00 00  c8 8a 59 2f fe 7f 00 00  88 8a 59 2f fe 7f 00 00  68 8a 59 2f fe 7f 00 00  20 8a 59 2f
 ^~~~~~~~~~~~~~~~~~~~~~~
              possibly invalid vptr
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior vptr_test.cpp:8:17
vptr_test.cpp:10:17: runtime error: member call on address 0x0255481a1ca0 which does not point to an object of type 'IUnknown'
0x0255481a1ca0: note: object has a possibly invalid vptr: abs(offset to top) too big
 fe 7f 00 00  c8 8a 59 2f fe 7f 00 00  88 8a 59 2f fe 7f 00 00  68 8a 59 2f fe 7f 00 00  20 8a 59 2f
 ^~~~~~~~~~~~~~~~~~~~~~~
              possibly invalid vptr
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior vptr_test.cpp:10:17
vptr_test.cpp:13:19: runtime error: member call on address 0x0255481a1cb8 which does not point to an object of type 'IPersistFile'
0x0255481a1cb8: note: object has a possibly invalid vptr: abs(offset to top) too big
 fe 7f 00 00  20 8a 59 2f fe 7f 00 00  00 8a 59 2f fe 7f 00 00  c0 89 59 2f fe 7f 00 00  88 89 59 2f
 ^~~~~~~~~~~~~~~~~~~~~~~
              possibly invalid vptr
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior vptr_test.cpp:13:19
```

Maybe the reports are correct in the strictest sense, but this is fundamentally how COM works on Windows. This practically makes the `vptr` check unusable if any code uses any native APIs that are accessed through COM interfaces. Could it be possible for UBSan to detect that these types are COM interfaces (say, checks that the type inherits `IUnknown`) and suppress the check?
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsV09v4roW_zRmc1QUHAhhwYKm8ITUzvSV6et7K-Q4J4kHx45sB4ZZvM9-5RBomFtGmrsY3cVFVtr4-Pz9_ewcM2tFoRDnZHJPJg8D1rhSmzmTe6FKzctGDVKdHedvJSrgTEqhCqiwStFA3ijuhFYWdA7J5ycQyqHJGUdLaAKuRNjXzgAvke-gQGfBGVEUaDAbwgNWmoQLEjyQ4PyMgtPghN77cZqloVBcNhkCCZODUJk-2GFJwuVHcltKnX7ti9unUA4qJhShsf-XmYL7GHnJDBC6YKbYnypA6AzItHMNAJDotRJOMCm-I6GxaqSsnSF0RsLzqvWmRCkfhdq9eWPWv22lULv3Ja2hxCBzuFbWMcW9seRxs37YXrR9RBf7CSSPm-TLf7frT88vn5PtZvnyn-WLn99um0ZkOic07nn2EdEECI33WmQ-jnbMCI16AfXDfp--I-Fyg-6ZuZLQ-JFQmnhoJokflF5pAcD6GY0V1q2ERO-oPr1ucyHxlvl_N2iO6zNBCI37WfTs_SSNKzc_hHTwSG4d1D6Fyf04mEUezMuSf6FbNVL6DD-xCt-6ND0_tw6tG0pfHOpdt7o0OZnqI9Lz2A-lLR7b-5zOKjmT9k8hGnSNURBcJsn04Qfe9xn7av1WI5N7KffVXSVUcWjpGZfO1dbDQ1eErgrhyiYdcl0Ruqqs08Z-1YSuelo-jhv7TCurJXaz4RK4ZKo4bT64yy3zzP-OJHxoVIa5UJgRmrSb-r1yvK7hTvcm8BvCndQSQ3rlNVxeLzpNXxki4SIm4WI0JeECTKOcqBDQGG38RHfu-GMItAKWZQatheBbQCeTcTxiI84COJSCl5BptKC0g1r7De80MAU6_Yrc-ePKHWtP3enVBpqeIrq25x0r7dD_7fRLZoFBra0VqTyCUHsmRdYm51ex1BIa6zy32Dp2uvanitMaUlF0hMgRpjkEgR_AY4gZTGZA82tBfEsQ3RLQ4CLoPJHJ8v8f_t6p-f77OKl24eb16Wnx8j-f4euZDfdYsr3QZtMxpc3_wpW7tBPDDZA_JMAo-L0MeFU7pQ_qH_h_H_xniD_GP_SP2V_FP41_Ef-rj88HHEjj38GBHnDXguCWgAcQz26xZvb350AH8-0v4BM7pti2kQZrbZwFZhC4NsYjIFQrss4I7s2CReU_ugmkjQNXCgvC-h41YxUqx6Q8QqkPbaN60GZnPYHeum4Svvj1tWHcCd4urdgObeuBREFbgSjoOtlGNZalEkHkwNQRuM4QGou2fVPMiT3C4nnt1Zlrg2aco7WYgSuNboryh3Z5CIluZAbCQYpnABBybeD1fsOUp1CGzqfdmnQlWmwZfKrJtTXfPFl2PPW3yHf2onQivVAlGuGsz-xy-kWBJyhTGdimrttd5RVaAyRcDbJ5mM3CGRvgfDSllEZREMSDcp5Hk1GcjWnGRuk0ZjyLozhMJxjxKMTRlA3EnAZ0HEzpbDQZhXQ8pNNxymdpGkSMUcYoGQdYMSGHvmUZalMMhLUNzkfBKKDRQLIUpW3vJ5RyXdVCorkzjoSLJrVMnbo2Qmktmcu1qUi46C4JF9G1mr0wlVJ_5zHztllKm8KScSCFdfY9FiecxPkJhd5tRjXC-ib-Qs3Dr12QBo2R8590ct7_uYurjfZnDqGrtjCW0FVXm_2c_hEAAP__PghPvA">