================
@@ -0,0 +1,49 @@
+//===--- VirtualArithmeticCheck.cpp - 
clang-tidy---------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "VirtualArithmeticCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::bugprone {
+
+void VirtualArithmeticCheck::registerMatchers(MatchFinder *Finder) {
+  const auto PointerExprWithVirtualMethod =
+      expr(hasType(pointerType(pointee(hasDeclaration(
+               cxxRecordDecl(hasMethod(isVirtualAsWritten())))))))
+          .bind("pointer");
+
+  const auto ArraySubscript =
+      arraySubscriptExpr(hasBase(PointerExprWithVirtualMethod));
+
+  const auto BinaryOperators =
+      binaryOperator(hasAnyOperatorName("+", "-", "+=", "-="),
+                     hasEitherOperand(PointerExprWithVirtualMethod));
+
+  const auto UnaryOperators =
+      unaryOperator(hasAnyOperatorName("++", "--"),
+                    hasUnaryOperand(PointerExprWithVirtualMethod));
+
+  Finder->addMatcher(
+      expr(anyOf(ArraySubscript, BinaryOperators, UnaryOperators)), this);
----------------
5chmidti wrote:

The check does not diagnose a few cases that IMO should be:

### Inheritance
Diagnose expressions with a pointer type, where the class either directly 
declares a virtual method (current matcher), or it inherits a pure virtual 
function that was not yet overridden in the inheritance chain.

This can be fixed by using
```c++
  const auto VirtualRecord =
      cxxRecordDecl(anyOf(isAbstract(), hasMethod(isVirtualAsWritten())));

  const auto PointerExprWithVirtualMethod =
      expr(hasType(pointerType(pointee(hasDeclaration(VirtualRecord)))))
          .bind("pointer");
```

### Type Aliases
Secondly, the matcher does not check the underlying type of type aliases.
The 
```c++
expr(hasType(pointerType(pointee(hasDeclaration(
               cxxRecordDecl(hasMethod(isVirtualAsWritten())))))))
          .bind("pointer")
```
matcher should have a `hasCanonicalType` after the `hasType` and after the 
`pointee` to fix this.

E.g.:

```c++
using BaseAlias = Base;
using DerivedAlias = Derived;

using BasePtr = BaseAlias*;
using DerivedPtr = DerivedAlias*;

void foo(Derived* p1, BaseAlias* p2, DerivedAlias* p3, BasePtr p4, DerivedPtr 
p5,
         BasePtr* p6, DerivedPtr* p7) {
    ++p1;
    ++p2;
    ++p3;
    ++p4;
    ++p5;
    ++p6;
    ++p7;
}

class PureBase {
  virtual void foo()=0;
};
class PureDerived : public PureBase {};

using PureBaseAlias = PureBase;
using PureDerivedAlias = PureDerived;

using PureBasePtr = PureBaseAlias*;
using PureDerivedPtr = PureDerivedAlias*;

void pure_foo(PureDerived* p1, PureBaseAlias* p2, PureDerivedAlias* p3, 
PureBasePtr p4, PureDerivedPtr p5,
         PureBasePtr* p6, PureDerivedPtr* p7) {
    ++p1;
    ++p2;
    ++p3;
    ++p4;
    ++p5;
    ++p6;
    ++p7;
}
```

pure1-pure5 should be diagnosed, but they currently are not.

https://github.com/llvm/llvm-project/pull/91951
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to