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

Stephan Bergmann (via logerrit) logerrit at kemper.freedesktop.org
Fri Nov 29 21:04:04 UTC 2019


 compilerplugins/clang/test/unnecessaryparen.cxx |   13 +++++++++++++
 compilerplugins/clang/unnecessaryparen.cxx      |   20 ++++++++++++++++++++
 2 files changed, 33 insertions(+)

New commits:
commit 4f8a744c4fcf2c69462af19bd807fee32413158d
Author:     Stephan Bergmann <sbergman at redhat.com>
AuthorDate: Fri Nov 29 17:42:03 2019 +0100
Commit:     Stephan Bergmann <sbergman at redhat.com>
CommitDate: Fri Nov 29 22:02:52 2019 +0100

    Make loplugin:unnecessaryparen treat member expressions consistently
    
    Stumbled across a warning starting to get emitted for some
    
      !(p->x)
    
    when I temporarily changed x from boost::optional (which has a member operator!)
    to std::optional (which instead implicitly uses a member conversion operator to
    bool).  (That is, for the new
    
       static int foo3(Foo2 & foo) {
            (void) !(foo.p);
            (void) !(foo.b);
            (void) !(foo.n);
            return (foo.p) ? 1 : 0;
        }
    
    test, the first, third, and fourth body lines never warned, while the second one
    erroneously warned without this fix.)
    
    Change-Id: I60f6941aaa3a73db0f1373c954e47aa68d703170
    Reviewed-on: https://gerrit.libreoffice.org/84079
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <sbergman at redhat.com>

diff --git a/compilerplugins/clang/test/unnecessaryparen.cxx b/compilerplugins/clang/test/unnecessaryparen.cxx
index fb36052778b5..88ed3650a09a 100644
--- a/compilerplugins/clang/test/unnecessaryparen.cxx
+++ b/compilerplugins/clang/test/unnecessaryparen.cxx
@@ -115,14 +115,27 @@ int main()
     (void)nBits;
 };
 
+struct B { operator bool(); };
+
+struct N { bool operator !(); };
+
 class Foo2
 {
     int* p;
+    B b;
+    N n;
 
     int foo2()
     {
         return (p) ? 1 : 0; // expected-error {{unnecessary parentheses around member expr [loplugin:unnecessaryparen]}}
     }
+
+    static int foo3(Foo2 & foo) {
+        (void) !(foo.p);
+        (void) !(foo.b);
+        (void) !(foo.n);
+        return (foo.p) ? 1 : 0;
+    }
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/compilerplugins/clang/unnecessaryparen.cxx b/compilerplugins/clang/unnecessaryparen.cxx
index f1c17c830207..79085d80027e 100644
--- a/compilerplugins/clang/unnecessaryparen.cxx
+++ b/compilerplugins/clang/unnecessaryparen.cxx
@@ -107,6 +107,26 @@ public:
     bool VisitBinaryConditionalOperator(BinaryConditionalOperator const * expr);
     bool VisitMemberExpr(const MemberExpr *f);
     bool VisitCXXDeleteExpr(const CXXDeleteExpr *);
+
+    bool VisitImplicitCastExpr(ImplicitCastExpr const * expr) {
+        if (ignoreLocation(expr)) {
+            return true;
+        }
+        if (expr->getCastKind() != CK_UserDefinedConversion) {
+            return true;
+        }
+        // Filter out a MemberExpr (resp. a ParenExpr sub-expr, if any, as would be found by
+        // VisitMemberExpr) that is part of a CXXMemberCallExpr which in turn is part of an
+        // ImplicitCastExpr, so that VisitMemberExpr doesn't erroneously pick it up (and note that
+        // CXXMemberCallExpr's getImplicitObjectArgument() skips past the underlying MemberExpr):
+        if (auto const e1 = dyn_cast<CXXMemberCallExpr>(expr->getSubExpr())) {
+            if (auto const e2 = dyn_cast<ParenExpr>(e1->getImplicitObjectArgument())) {
+                handled_.insert(e2);
+            }
+        }
+        return true;
+    }
+
 private:
     void VisitSomeStmt(Stmt const * stmt, const Expr* cond, StringRef stmtName);
 


More information about the Libreoffice-commits mailing list