Issue |
134425
|
Summary |
[clang] Deprecation warnings in system headers are silenced when the deprecated entity is used indirectly
|
Labels |
clang
|
Assignees |
|
Reporter |
ldionne
|
A while back, we marked `std::char_traits<not-a-character-type>` as deprecated (see #72694 and the related history). We then removed it in LLVM 19 after thinking we had provided users with a reasonable deprecation period of 6 months for such a small thing. And that was the case, with a major caveat.
Indeed, Clang <= 17 failed to surface deprecation warnings for things in system headers, so that the following would actually not issue any diagnostic:
```c++
#include <string> // assume char_traits<long> is deprecated in that header
int main() {
std::char_traits<long> traits;
}
```
That was fixed in Clang 18 in #70353 (thanks to @cor3ntin!). In Clang 18 and above, the code above does warn. Based on that, we went ahead and removed `std::char_traits<not-a-character-type>` in LLVM 19, thinking we had provided one release of deprecation. However, the following code never warned and still doesn't warn:
```c++
#include <string> // assume char_traits<long> is deprecated in that header
int main() {
std::basic_string<long> s;
}
```
Even though `basic_string<long>` instantiates `char_traits<long>`, I guess the issue is that the instantiation of `char_traits<long>` itself is happening from a system header, not user code, and as a result we don't warn on it.
IMO, that's broken. That means that we effectively shipped #72694 without giving any advance notice to people because nobody instantiates `char_traits` directly, everybody instantiates `basic_string` and `basic_string_view`. When I did my sanity testing before landing #72694, I must have used `char_traits` (because that's what we were deprecating and that's what didn't work before @cor3ntin 's fix), but that wasn't enough.
I'm not sure how to best fix that, but at the moment we seem to basically not have a good story for deprecating things located in system headers. I'm going to throw a few potential solutions out there:
- Actually allow full-on deprecation warnings in system headers -- don't attempt to suppress those. I'm not certain whether that's reasonable, but I know in libc++ that we make sure not to use deprecated things (we run our test suite by including headers as *not* system headers to see everything, and we fix it). So I think that would be realistic for libc++.
- Perhaps we can have a `pragma` that allows headers to change Clang's behavior diagnostics-wise? It always felt like a big hammer to disallow any and all warnings coming from system headers without giving them the choice to decide for themselves.
- Add another attribute that allows producing deprecation warnings from system headers no matter where the point of use came from. If we're OK with doing that, though, then I'm not certain why we wouldn't just allow all deprecation warnings in system headers.
- I'd also be willing to consider that perhaps the root cause of the problem is not that Clang didn't surface the deprecation warning, but that libc++ didn't mark the right APIs as deprecated. For example, one could argue that libc++ should have marked `basic_string<long>`, `basic_string_view<long>`, `basic_istream<long>` and the other 150 APIs that can end up instantiating `char_traits<long>` as deprecated. I think that would be really challenging and error prone, but I could imagine the argument being made. If that's the direction we want to take, then we'd need a way to easily mark specializations of things as being deprecated. Today the only way to do this would be to provide an explicit instantiation of all the types that we want to deprecate (e.g. `basic_istream<long>`, `basic_istream<unsigned char>`, etc.) and duplicate their implementation while marking them as deprecated. So if we think that's philosophically the right way to go, we should try to find a way that makes it technically feasible.
I'm eager to see what other folks think!
CC @AaronBallman for awareness
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs