[cfe-dev] Diagnosing initialization of deprecated data member?

Stephan Bergmann via cfe-dev cfe-dev at lists.llvm.org
Tue May 12 00:48:02 PDT 2020

On 11/05/2020 06:55, Richard Smith wrote:
> On Thu, 7 May 2020 at 01:52, Stephan Bergmann via cfe-dev 
> <cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>> wrote:
>     For
>      > $ cat test.cc
>      > struct S {
>      >     int x;
>      >     [[deprecated]] int y;
>      > };
>      > int main() {
>      >     S s{0, 0};
>      > }
>     Clang emits a diagnostic
>      > $ clang++ test.cc
>      > test.cc:6:12: warning: 'y' is deprecated [-Wdeprecated-declarations]
>      >     S s{0, 0};
>      >            ^
>      > test.cc:3:7: note: 'y' has been explicitly marked deprecated here
>      >     [[deprecated]] int y;
>      >       ^
>      > 1 warning generated.
>     while e.g. GCC and MSVC do not (as checked with godbolt.org
>     <http://godbolt.org>).
>     Is this deliberate behavior on Clang's part, or just a consequence of
>     how the code happens to work?  Are there opinions on whether or not the
>     behavior is useful?
> I think it's probably a bug. The C++11 attribute is documented as 
> deprecating the name, not the existence of the entity, so diagnosing a 
> use that doesn't use the name seems somewhat questionable. (It's not 
> obviously a bad choice, though, since the intent is very likely to catch 
> cases that would break if the field is removed, not only if it's renamed.)
> There are a few other warnings channeled through the same path 
> (`DiagnoseUseOfDecl`), such as "availability" warnings, and it's quite 
> likely that some of those *should* still be issued for such cases.
>     (I came across this issue when seeing a commit in LibreOffice where some
>      > #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
>     were added apparently to silence exactly the above situation in code
>     initializing a PyTypeObject struct from
>     /usr/include/python3.8/cpython/object.h, not even realizing that that
>     pragma would only be needed by Clang and not by GCC.
>     FWIW, the standard's recommended practice is "to produce a diagnostic
>     message in case the program refers to a name or entity other than to
>     declare it", [dcl.attr.deprecated]/4.)
> What was the intent in the LibreOffice case? Would they want a warning 
> on "S s{.x = 0, .y = 0};" but not on "S s{0, 0};"?

That Python/LibreOffice case is a bit complex, the commit message of 
"Fix initialization of Python-3.8--only at-end tp_print member" has the 
details.  The intend on the Python side, where the deprecation attribute 
got added, is apparently to warn about "initialization by assignment" 
cases like

   X.tp_print = 0;

It presumably did not intend to cause warnings in list-initialization 
scenarios as used in the LibreOffice code---I guess the re-addition of 
the dummy tp_print member at the end didn't even take into account the 
-Wmissing-field-initializers for client code using list-initialization, 
which causes client code to silence that warning by adding an 
initializer for the dummy member, but which in turn causes 

For designated initializer scenarios, the warning is apparently also 
useful (and likely intended by the Python authors) in C code, where it 
would warn about legacy code like

   ..., .tp_dealloc=..., .tp_print=..., .tp_getattr=..., ...

that assumes tp_print at its original position in PyTypeObject.  (For 
C++20, such code would cause an error anyway because tp_print has been 
moved relative to the other members.)

So, in short, for the particular scenario at hand, it looks like not 
emitting -Wdeprecated-declarations in the non-designated 
initializer-list scenario would be the most useful behavior.

More information about the cfe-dev mailing list