Page MenuHomePhabricator

[Sema] Add deprecation warnings for some compiler provided __has_* type traits
ClosedPublic

Authored by royjacobson on Jul 5 2022, 9:36 PM.

Details

Summary

Some compiler provided type traits like __has_trivial_constructor have been documented
as deprecated for quite some time.
Still, some people apparently still use them, even though mixing them with concepts
and with deleted functions leads to weird results. There's also disagreement about some
edge cases between GCC (which Clang claims to follow) and MSVC.

This patch adds deprecation warnings for the usage of those builtins, except for __has_trivial_destructor
which doesn't have a GCC alternative.

I made the warning on by default, so I had to silence it for some tests but it's not too many.

Some (decade old) history of issues with those builtins:
https://github.com/llvm/llvm-project/issues/18187
https://github.com/llvm/llvm-project/issues/18559
https://github.com/llvm/llvm-project/issues/22161
https://github.com/llvm/llvm-project/issues/33063

The abseil usage of them that triggered me to add this warning:
https://github.com/abseil/abseil-cpp/issues/1201

Weird interaction of those builtins with C++20's conditionally trivial special member functions:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106085

Diff Detail

Event Timeline

royjacobson created this revision.Jul 5 2022, 9:36 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 5 2022, 9:36 PM
royjacobson requested review of this revision.Jul 5 2022, 9:36 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 5 2022, 9:36 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
royjacobson added reviewers: Restricted Project, sberg, Javier-varez, rsmith.Jul 5 2022, 9:38 PM
cor3ntin added inline comments.
clang/include/clang/Basic/DiagnosticSemaKinds.td
5566

Should we say something like "and will be removed in the future"?

"%0 is deprecated from C++11 onward. Use %1 instead." might be sufficient

clang/lib/Sema/SemaExprCXX.cpp
5432
erichkeane added inline comments.
clang/docs/ReleaseNotes.rst
315
316
clang/include/clang/Basic/DiagnosticSemaKinds.td
5566

Diagnostics arent sentences. Also, we wouldn't say "C++11 onward", we can just say C++11. I might suggest:

builtin %0 is deprecated in C++11, use %1 instead

BUT @aaron.ballman always does great at this level of bikeshedding.

clang/lib/Sema/SemaExprCXX.cpp
5439
aaron.ballman added inline comments.Jul 6 2022, 7:04 AM
clang/include/clang/Basic/DiagnosticGroups.td
191

I wonder if we want to rename this to deprecated-builtins so it applies to any builtin we elect to deprecate, not just ones that start with has. WDYT?

clang/include/clang/Basic/DiagnosticSemaKinds.td
5566

I think we might want to rename this to warn_deprecated_builtin and make it slightly more general. I think we want to drop the mention of C++11 because the documentation says these are deprecated (not deprecated in a specific version) and the replacement APIs are all available pre C++11 anyway (at least in Clang). How about: builtin %0 is deprecated; use %1 instead?

clang/lib/Sema/SemaExprCXX.cpp
5400–5401

I think we should always warn on these, not just in C++11.

5426–5428

This one is not documented as being deprecated (or documented at all). I think it's reasonable to deprecate it, but it should probably be documented in the language extensions page.

5433

I'd like to know how plausible that "might" is -- Clang flags it as being deprecated, so it seems very reasonable to diagnose it as such. These diagnostics won't be triggered from system headers by default anyway, so I'm not certain if this will be too noisy in practice.

Address CR comments.
Make the switch case slightly more concise.

royjacobson marked 9 inline comments as done and 2 inline comments as done.Jul 6 2022, 1:50 PM
royjacobson added inline comments.
clang/include/clang/Basic/DiagnosticGroups.td
191

Sounds good to me, updated it.

clang/include/clang/Basic/DiagnosticSemaKinds.td
5566

Took Aaron's version at the end.

clang/lib/Sema/SemaExprCXX.cpp
5400–5401

I'm not convinced we should. My reasoning is that we need a pretty good reason to start issuing warnings for 20 years old code. The usage of those builtins with deleted functions after C++11 is pretty broken which is a pretty good reason, but for earlier language versions they work 'fine' and if people want to use C++03 I prefer leaving them at peace :)

People on C++03 are also probably using pretty old versions of libstdc++ and/or boost type_traits, so this could have some impact.

WDYT?

5426–5428

It's the __has_trivial_constructor builtin that unfortunately has a different enum name (it's named after the internal CXXRecordDecl it calls, I think).

5433

It's used in libstdc++'s type_traits and in boost's type_traits (but we will start warning on boost's type_traits anyway). So it's even if by default people are not going to see it I think it's used widely enough to be problematic and we shouldn't warn on this for now.

I added the libstdc++ part to the comment as well.

erichkeane added inline comments.Jul 6 2022, 1:55 PM
clang/lib/Sema/SemaExprCXX.cpp
5400–5401

warnings don't get emitted for code in header files, so at least that part isn't a concern.

royjacobson marked 3 inline comments as done.Jul 7 2022, 2:18 AM
royjacobson added inline comments.
clang/lib/Sema/SemaExprCXX.cpp
5400–5401

Any header files, or just system headers?

erichkeane added inline comments.Jul 7 2022, 6:01 AM
clang/lib/Sema/SemaExprCXX.cpp
5400–5401

Sorry, yes, Phab is a mess on a cell phone... in things included as System Headers.

aaron.ballman added inline comments.Jul 7 2022, 12:49 PM
clang/lib/Sema/SemaExprCXX.cpp
5400–5401

Agreed with Erich -- warnings in system headers (but not regular headers) are silenced by default, you need to pass -Wsystem-headers to enable them.

5433

My feeling is: if it's deprecated and we don't warn on it, it's not actually deprecated. I'd rather see us warn uniformly on all the deprecated interfaces. System headers are free to keep using these interfaces (system headers are long lived), but any user code using this needs some sort of notification that they're using something we don't want them to use, or we will never be able to get rid of these interfaces (at which point, we should undeprecate them because we need to keep them working).

royjacobson added inline comments.Jul 8 2022, 3:16 AM
clang/lib/Sema/SemaExprCXX.cpp
5400–5401

To clarify my position, I think about those builtins as an unofficial part of the C++03 standard and I think we should support them as long as we support C++03.

Do you think that's reasonable?

I agree we should update the documentation in this case.

aaron.ballman added inline comments.Jul 8 2022, 8:29 AM
clang/lib/Sema/SemaExprCXX.cpp
5400–5401

I still don't see the benefit of undeprecating these in C++03. The replacement interfaces are available for use in C++03 mode, so there's nothing that prevents a user from being pushed to use the supported interfaces instead, right? To me, the older interfaces were not clean/correct and the replacement interfaces are the ones that we want people to use, and that's language mode agnostic.

Warn on <=C++03 as well, warn on __has_trivial_destructor.

clang/lib/Sema/SemaExprCXX.cpp
5400–5401

I think they're

  1. Clean enough under C++03 semantics - without the extra complications of move semantics, defaulted/deleted functions etc.
  2. Potentially pretty widely used in code that needs C++03, though I have no idea how to check that.

But you convinced me that it's probably not that of a big deal to add those warnings anyway, so let's add them and think about actual deprecation in a few years :)

5433

Ok, added it to the warnings.

aaron.ballman accepted this revision.Jul 12 2022, 4:00 AM

LGTM, thank you!

This revision is now accepted and ready to land.Jul 12 2022, 4:00 AM
This revision was landed with ongoing or failed builds.Jul 12 2022, 9:24 AM
This revision was automatically updated to reflect the committed changes.
glandium added a subscriber: glandium.EditedJul 13 2022, 8:33 PM

From the commit message:

This patch adds deprecation warnings for the usage of those builtins, except for __has_trivial_destructor which doesn't have a GCC alternative.

The exception for __has_trivial_destructor doesn't seem to be true, FWIW.

From the commit message:

This patch adds deprecation warnings for the usage of those builtins, except for __has_trivial_destructor which doesn't have a GCC alternative.

The exception for __has_trivial_destructor doesn't seem to be true, FWIW.

Oh, I'm really sorry for that :/ It was changed because Aaron asked me to add it as well, but I forgot to update the summary.