[Libreoffice-commits] core.git: compilerplugins/clang

Stephan Bergmann (via logerrit) logerrit at kemper.freedesktop.org
Wed Dec 11 18:52:40 UTC 2019


 compilerplugins/clang/test/unusedmember.cxx |   40 ++++++++++++++++++++++++++++
 compilerplugins/clang/unusedmember.cxx      |   28 ++++++++++++++++++-
 2 files changed, 67 insertions(+), 1 deletion(-)

New commits:
commit 2157160b2665de61517973089b3bcd2a59416c1e
Author:     Stephan Bergmann <sbergman at redhat.com>
AuthorDate: Wed Dec 11 16:36:42 2019 +0100
Commit:     Stephan Bergmann <sbergman at redhat.com>
CommitDate: Wed Dec 11 19:51:31 2019 +0100

    Recursively include unnamed inner classes in "layout heuristic"
    
    This covers both cases where the inner class is defined in the declaration of a
    non-static data member, as needed by clang-cl for
    
    > bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx(799,19): error: unused class member [loplugin:unusedmember]
    >             PVOID pExceptionObject;
    >             ~~~~~~^~~~~~~~~~~~~~~~
    > bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx(801,19): error: unused class member [loplugin:unusedmember]
    >             PVOID pThrowImageBase;
    >             ~~~~~~^~~~~~~~~~~~~~~
    
    as well as anonymous structs (even if there appears to be no need for that
    across the LO code base; they are part of C11 and a widely supported C++
    extension).
    
    The newly added TODO will eventually need fixing, but I didn't find a way in
    Clang to tell whether a RecordDecl is defined as part of a FieldDecl, and the
    issue appears to be of no practical relevance for the current LO code base.
    
    Change-Id: I08cecddb9b4a70c3ca480d2d2ab1ea4f198011b2
    Reviewed-on: https://gerrit.libreoffice.org/84967
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <sbergman at redhat.com>

diff --git a/compilerplugins/clang/test/unusedmember.cxx b/compilerplugins/clang/test/unusedmember.cxx
index d40d87b2d29b..00b136249aca 100644
--- a/compilerplugins/clang/test/unusedmember.cxx
+++ b/compilerplugins/clang/test/unusedmember.cxx
@@ -164,6 +164,45 @@ struct S3 : S2
 void f() { (void)sizeof(S3); }
 }
 
+namespace Unnamed
+{
+namespace
+{
+struct S
+{
+    struct
+    {
+        struct
+        {
+            int i;
+        } s2;
+        struct // anonymous struct extension (widely supported)
+        {
+            int j;
+        };
+        int k;
+    } s1;
+#if false //TODO: see corresponding TODO in compilerplugins/clang/unusedmember.cxx
+    static constexpr struct
+    {
+        int l; // expected-error {{unused class member [loplugin:unusedmember]}}
+    } s = {};
+#endif
+    typedef struct
+    {
+        int m; // expected-error {{unused class member [loplugin:unusedmember]}}
+    } t; // expected-error {{unused class member [loplugin:unusedmember]}}
+};
+}
+void f()
+{
+    (void)sizeof(S);
+#if false //TODO: see corresponding TODO in compilerplugins/clang/unusedmember.cxx
+    (void)S::s; // avoid "unused variable 's'" (non-loplugin) warning
+#endif
+}
+}
+
 int main()
 {
     (void)&Enum::f;
@@ -173,6 +212,7 @@ int main()
     (void)&Alignof::f;
     (void)&Aligned::f;
     (void)&Bases::f;
+    (void)&Unnamed::f;
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/compilerplugins/clang/unusedmember.cxx b/compilerplugins/clang/unusedmember.cxx
index ed7096ecbc1e..214d66556e40 100644
--- a/compilerplugins/clang/unusedmember.cxx
+++ b/compilerplugins/clang/unusedmember.cxx
@@ -352,7 +352,33 @@ public:
         {
             if (auto const d1 = dyn_cast<FieldDecl>(d))
             {
-                if (layout_.find(d1->getParent()->getCanonicalDecl()) != layout_.end())
+                bool layout = false;
+                for (auto d2 = d1->getParent();;)
+                {
+                    if (layout_.find(d2->getCanonicalDecl()) != layout_.end())
+                    {
+                        layout = true;
+                        break;
+                    }
+                    // Heuristic to recursivley check parent RecordDecl if given RecordDecl is
+                    // unnamed and either an anonymous struct (or union, but which are already
+                    // filtered out anyway), or defined in a non-static data member declaration
+                    // (TODO: which is erroneously approximated here with getTypedefNameForAnonDecl
+                    // for now, which fails to filter out RecordDecls in static data member
+                    // declarations):
+                    if (!(d2->getDeclName().isEmpty()
+                          && (d2->isAnonymousStructOrUnion()
+                              || d2->getTypedefNameForAnonDecl() == nullptr)))
+                    {
+                        break;
+                    }
+                    d2 = dyn_cast<RecordDecl>(d2->getParent());
+                    if (d2 == nullptr)
+                    {
+                        break;
+                    }
+                }
+                if (layout)
                 {
                     continue;
                 }


More information about the Libreoffice-commits mailing list