[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
<https://git.libreoffice.org/core/+/23d9966751566028c50ca95ca203d20f36c64f30%5E%21>
"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
-Wdeprecated-declarations.
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