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

    <tr>
        <th>Summary</th>
        <td>
            [analyzer] Support forbidding given functions from being called unless explicitly marked as allowed
        </td>
    </tr>

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

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

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

<pre>
    Sometimes in large codebases there may be a desire to forbid certain functions from being called. Now, this may be easy when the function being described is in your own code, simply mark it as [[deprecated]] or = delete it to prevent it from being called. This approach becomes unusable when the function is _not_ in your own code however, such as when it is from an external library, where you'll end up having to redeclare the functions from that library to add the deprecated attribute, something which you would ideally not want to do, or worse, when the function you want to forbid is _from the C or C\+\+ Standard Library_. There, it is unwieldy to forbid them as you have to [write troublesome code that could break at any moment the compiler or platform header files are upgraded](https://github.com/openjdk/jdk/pull/24608/files). It would be nice if there was static analyzer support for forbidding a function from being called, with a tunable switch to allow calling that function in situations where it really has to be called, as this is after all, more appropriate of a job for a static analyzer. For instance, if the compiler is given the declaration of

```cpp
void *malloc(size_t) throw();
```

to forbid, the analyzer should ideally complain any time the malloc function is called

```cpp
int main() {
    void *ptr = ::malloc(1); // Error: Call to forbidden function malloc (Or something along those lines)
 ::free(ptr);
}
```

Unless some explicit pragma or attribute is placed at the callsite to indicate the developer has thought it through and arrived at the conclusion that there is no way other than to call the forbidden function. Perhaps something like the following could be added to the function call to let it pass through the analyzer:

```cpp
#pragma clang permit_call
[[clang::permit_call]]
```

Note that I marked this as analyzer, but this may not actually need to be implemented as part of the static analyzer and might be better off as part of the compiler itself. I'm not exactly sure which this should be under, so analyzer it is for now. If this is already part of the compiler or analyzer, feel free to ignore this, but I'd appreciate it if I could be pointed to how to use it in that case.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJx8Vt2O4jwSfRpzU_oQGGjggov-WaSWVrMr9ex1q2JXiKcdO7IdMszTr8oOHfpHI7VATeyqU6dOnQrGaE6O6CA2D2LzNMM-NT4cfjb00lBo0f1E90ZhVnl9Obz4lpJpKYJxYDGcCJTXVGGkCKmhQNDiBSoCBE3RBILkofahMhoUhYTGQd07lYx3EergW6jIuBMotJb0HH74QchHSI2J11CE8QJDQ44zvN8e72mKKpiKNJgM6uL7AH5wGRdHiqbt7AVaDG9gEmCEXOiDpi6QwkRabJ7E5gl8ALF6Ak2WEvHR5KELdCaX-L9vsP5kkNh1waNqoCLlmZne9RErS99ANhFenU-vX4BC4wc6U8iAe9UwzHzdJL6Uc6MD-p0oOLRgTRUwXPj4kFm_-F7IrbVATkPfQYNnRpo8BNKkLHInbqCMMVOD6RqMD6PW-dhEDmBKwVR9KmRy_xuOPDRGNZwWBt9bDUYTWnsB5xMM6DJ72vMdH2DwIdII9hMlOcJ4ftQJszSiI8j3H8XmUciH8gkvCZ3GoOHfBfgrd4JCTlD46t1gyOrLTdDUUMuscr4Gz1mXYvMwBJMIUvB9ZYmrK-3IvKhcWBUI3wAToLtA61uWAwNTvu2MpcD4Ooup9qGFhlBTgNpYisCc990poC4ak7smpS6K1b2QRyGPJ5Oavpor3wp59B25X_pNyGP57HprhTzK9d1iJ-QxRxRyP4fnNDJeETijCEw9Tt6AEWLCZBSgQ3v5QwFi33U-JGZhZEJz93BqwBdd5z6Z1ABC6l1WchxMUk0WiLV-yAezvJimSd0Ookk9Fn0VXZoEoQijwcgBKrpJwz_xDPEY1YkCh-ffWx-oDFYXDCYCXwPCL1_lOvBzlXM4-gDGxYROFRnUH3tkIpzMedRemYcME3wtFvf8d7cof6rrxOL-7I0GIe9brlcJuYvmD70mIfeQmsAWtRNyL1YPt1dLpHfJFRujm140HyaFwVn2QxYWm2o-XTJ-sIyRr-9wGpegReMKHhBbBgQAcC2gS8XVWHSrqZxlQQ9FiPCvEHwQq3t4RGunodE0mfUVmJC7_4QbH0DrsxB8JLDGZZEyhpKwDkRC7roUJrq2T19J-5-zFGMOC_S7s0aZBF3AU4s8X-8exHR0FlX2pdJitDbmGfZgnDZsWmOXz2R9R6Eor_H9qclGzg3sTw2g04AhmPNNMO-U7SOXm6Vd5spEcB4GvIDnH_iR43Qqk8Vm9oWtOfyXQoNdvGHKmrfRgz0PUR646yCj1qQ55gdvVGM3LGXgHcb4jv5WWcz1d-oQcjVyqCy6E3QUWpNeOSw_zWswPynNun2cV-LXPv3waTTH57xRGXRegnECIx-h6tO0wXkjoEp9WQ9U6qwIeC8T2ynzH6HDkHjOubDPLsatag33ryKoKLFV-Lr-fG0a9xTJ1nN4FnLbZgD0G1WyF4g9G2XeXRngOJMVQe_0uH_9lHhcvz6A88McnuvJr2wg1Jfv87Nkb-ioiSzwKGSRnpzPy9jEK1UMU2e_I5XtjtPW8Dzpo_Mm85Q8vynwVx_LsVGpCiPNZ_qw0vvVHmd0WG7Xd3K5kNv9rDmst3dK1csF7ja00dvdWm2pkuu60vuVWko1Mwe5kJvFZiGXO7le7ed6u6mWtaa7GtfV3UqK9YJaNHZu7bmd-3CamRh7OixXu5VczCxWZGN-hZTS0QD5qZCS3yjDgS_9U_WnKNYLa2KKU5hkks3vnu-EbZ7gZdpa141V7Psvr47QFw-52sf4zlfEldcW6Vkf7OEvS5hRjV__dMH_IpWEPOZaopDHsdjzQf4_AAD__3hz3jw">