abelkocsis updated this revision to Diff 306080.
abelkocsis added a comment.

Fixes, `std::atomic` variables add


Repository:
  rCTE Clang Tools Extra

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77493/new/

https://reviews.llvm.org/D77493

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/DoNotReferAtomicTwiceCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/DoNotReferAtomicTwiceCheck.h
  clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-do-not-refer-atomic-twice.rst
  clang-tools-extra/docs/clang-tidy/checks/cert-con40-c.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-do-not-refer-atomic-twice.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-do-not-refer-atomic-twice.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-do-not-refer-atomic-twice.cpp
@@ -0,0 +1,129 @@
+// RUN: %check_clang_tidy %s bugprone-do-not-refer-atomic-twice %t
+#define _Bool bool
+typedef _Atomic _Bool atomic_bool;
+typedef _Atomic int atomic_int;
+#define offsetof(type, member) 0
+
+namespace std {
+template <class T>
+struct atomic {
+  atomic(T t) {}
+  T operator=(const T t) { return t; }
+  T operator+(const T t) { return t; }
+  T operator*(const T t) { return t; }
+  void operator+=(const T t) {}
+  T operator++(const T t) { return t; }
+  operator T() const { return 0; }
+};
+} // namespace std
+
+atomic_bool b = false;
+atomic_int n = 0;
+_Atomic int n2 = 0;
+_Atomic(int) n3 = 0;
+std::atomic<int> n4(0);
+
+struct S {
+  atomic_bool b;
+  atomic_int n;
+  _Atomic int n2;
+  _Atomic(int) n3;
+  std::atomic<int> n4();
+};
+
+void warn1() {
+  n = (n + 1) / 2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: Do not refer to atomic variable 'n' twice in an expression [bugprone-do-not-refer-atomic-twice]
+  n2 = (n2 + 1) / 2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: Do not refer to atomic variable 'n2' twice in an expression [bugprone-do-not-refer-atomic-twice]
+  n3 = (n3 + 1) / 2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: Do not refer to atomic variable 'n3' twice in an expression [bugprone-do-not-refer-atomic-twice]
+  n4 = (n4 + 1) / 2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: Do not refer to atomic variable 'n4' twice in an expression [bugprone-do-not-refer-atomic-twice]
+  b = b && true;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: Do not refer to atomic variable 'b' twice in an expression [bugprone-do-not-refer-atomic-twice]
+}
+
+int warn2_1() {
+  return n * (n + 1) / 2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: Do not refer to atomic variable 'n' twice in an expression [bugprone-do-not-refer-atomic-twice]
+}
+
+int warn2_2() {
+  return n2 * (n2 + 1) / 2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Do not refer to atomic variable 'n2' twice in an expression [bugprone-do-not-refer-atomic-twice]
+}
+
+int warn2_3() {
+  return n3 * (n3 + 1) / 2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Do not refer to atomic variable 'n3' twice in an expression [bugprone-do-not-refer-atomic-twice]
+}
+
+int warn2_4() {
+  return n4 * (n4 + 1) / 2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Do not refer to atomic variable 'n4' twice in an expression [bugprone-do-not-refer-atomic-twice]
+}
+
+int warn2_5() {
+  return (b && true) || b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: Do not refer to atomic variable 'b' twice in an expression [bugprone-do-not-refer-atomic-twice]
+}
+
+void good1() {
+  n = 12;
+  n2 = 12;
+  n3 = 12;
+  n4 = 12;
+  b = true;
+}
+
+int good2_1() {
+  return n;
+}
+
+int good2_2() {
+  return n2;
+}
+
+int good2_3() {
+  return n3;
+}
+
+int good2_4() {
+  return n4;
+}
+
+bool good2_5() {
+  return b;
+}
+
+void good3() {
+  n += 12;
+  n2 += 12;
+  n3 += 12;
+  n4 += 12;
+  b ^= 1;
+}
+
+void good4() {
+  n++;
+  n2++;
+  n3++;
+  n4++;
+}
+
+void good5() {
+  int a = sizeof(atomic_int);
+  int a2 = sizeof(_Atomic int);
+  int a3 = sizeof(_Atomic(int));
+  int a4 = sizeof(std::atomic<int>);
+  int a5 = sizeof(atomic_bool);
+}
+
+void good6() {
+  int a = offsetof(S, b);
+  int a2 = offsetof(S, n);
+  int a3 = offsetof(S, n2);
+  int a4 = offsetof(S, n3);
+  int a5 = offsetof(S, n4);
+}
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===================================================================
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -55,6 +55,7 @@
    `bugprone-branch-clone <bugprone-branch-clone.html>`_,
    `bugprone-copy-constructor-init <bugprone-copy-constructor-init.html>`_, "Yes"
    `bugprone-dangling-handle <bugprone-dangling-handle.html>`_,
+   `bugprone-do-not-refer-atomic-twice <bugprone-do-not-refer-atomic-twice.html>`_,
    `bugprone-dynamic-static-initializers <bugprone-dynamic-static-initializers.html>`_,
    `bugprone-exception-escape <bugprone-exception-escape.html>`_,
    `bugprone-fold-init-type <bugprone-fold-init-type.html>`_,
@@ -103,6 +104,7 @@
    `bugprone-unused-return-value <bugprone-unused-return-value.html>`_,
    `bugprone-use-after-move <bugprone-use-after-move.html>`_,
    `bugprone-virtual-near-miss <bugprone-virtual-near-miss.html>`_, "Yes"
+   `cert-con40-c <cert-con40-c.html>`_,
    `cert-dcl21-cpp <cert-dcl21-cpp.html>`_,
    `cert-dcl50-cpp <cert-dcl50-cpp.html>`_,
    `cert-dcl58-cpp <cert-dcl58-cpp.html>`_,
Index: clang-tools-extra/docs/clang-tidy/checks/cert-con40-c.rst
===================================================================
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/cert-con40-c.rst
@@ -0,0 +1,10 @@
+.. title:: clang-tidy - cert-con40-c
+.. meta::
+   :http-equiv=refresh: 5;URL=bugprone-do-not-refer-atomic-twice.html
+
+cert-con40-c
+============
+
+The cert-con40-c check is an alias, please see
+`bugprone-do-not-refer-atomic-twice <bugprone-do-not-refer-atomic-twice>`_
+for more information.
Index: clang-tools-extra/docs/clang-tidy/checks/bugprone-do-not-refer-atomic-twice.rst
===================================================================
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/bugprone-do-not-refer-atomic-twice.rst
@@ -0,0 +1,17 @@
+.. title:: clang-tidy - bugprone-do-not-refer-atomic-twice
+
+bugprone-do-not-refer-atomic-twice
+==================================
+
+Finds atomic variable which is referred twice in an expression.
+
+.. code-block:: c
+
+    atomic_int n = ATOMIC_VAR_INIT(0);
+    int compute_sum(void) {
+        return n * (n + 1) / 2;
+    }
+
+This check corresponds to the CERT C Coding Standard rule
+`CON40-C. Do not refer to an atomic variable twice in an expression
+<https://wiki.sei.cmu.edu/confluence/display/c/CON40-C.+Do+not+refer+to+an+atomic+variable+twice+in+an+expression>`_.
Index: clang-tools-extra/docs/ReleaseNotes.rst
===================================================================
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -97,6 +97,11 @@
   Finds structs that are inefficiently packed or aligned, and recommends
   packing and/or aligning of said structs as needed.
 
+- New :doc:`bugprone-do-not-refer-atomic-twice
+  <clang-tidy/checks/bugprone-do-not-refer-atomic-twice>` check.
+
+  Finds atomic variables which are referred twice in an expression.
+
 - New :doc:`cppcoreguidelines-prefer-member-initializer
   <clang-tidy/checks/cppcoreguidelines-prefer-member-initializer>` check.
 
@@ -118,6 +123,11 @@
   Finds functions registered as signal handlers that call non asynchronous-safe
   functions.
 
+- New alias :doc:`cert-con40-c
+  <clang-tidy/checks/cert-con40-c>` to
+  :doc:`bugprone-do-not-refer-atomic-twice
+  <clang-tidy/checks/bugprone-do-not-refer-atomic-twice>` was added.
+
 - New :doc:`cert-sig30-c
   <clang-tidy/checks/cert-sig30-c>` check.
 
Index: clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
===================================================================
--- clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
+++ clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
@@ -10,6 +10,7 @@
 #include "../ClangTidyModule.h"
 #include "../ClangTidyModuleRegistry.h"
 #include "../bugprone/BadSignalToKillThreadCheck.h"
+#include "../bugprone/DoNotReferAtomicTwiceCheck.h"
 #include "../bugprone/ReservedIdentifierCheck.h"
 #include "../bugprone/SignalHandlerCheck.h"
 #include "../bugprone/SignedCharMisuseCheck.h"
@@ -89,6 +90,8 @@
     // CON
     CheckFactories.registerCheck<bugprone::SpuriouslyWakeUpFunctionsCheck>(
         "cert-con36-c");
+    CheckFactories.registerCheck<bugprone::DoNotReferAtomicTwiceCheck>(
+        "cert-con40-c");
     // DCL
     CheckFactories.registerCheck<misc::StaticAssertCheck>("cert-dcl03-c");
     CheckFactories.registerCheck<readability::UppercaseLiteralSuffixCheck>(
Index: clang-tools-extra/clang-tidy/bugprone/DoNotReferAtomicTwiceCheck.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/bugprone/DoNotReferAtomicTwiceCheck.h
@@ -0,0 +1,34 @@
+//===--- DoNotReferAtomicTwiceCheck.h - clang-tidy --------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_DONOTREFERATOMICTWICECHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_DONOTREFERATOMICTWICECHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace bugprone {
+
+/// Finds atomic variable which is referred twice in an expression.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone-do-not-refer-atomic-twice.html
+class DoNotReferAtomicTwiceCheck : public ClangTidyCheck {
+public:
+  DoNotReferAtomicTwiceCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace bugprone
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_DONOTREFERATOMICTWICECHECK_H
Index: clang-tools-extra/clang-tidy/bugprone/DoNotReferAtomicTwiceCheck.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/bugprone/DoNotReferAtomicTwiceCheck.cpp
@@ -0,0 +1,62 @@
+//===--- DoNotReferAtomicTwiceCheck.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 "DoNotReferAtomicTwiceCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace bugprone {
+
+const auto BinOp = anyOf(
+    hasAncestor(cxxOperatorCallExpr(allOf(
+        anyOf(hasOverloadedOperatorName("+"), hasOverloadedOperatorName("-"),
+              hasOverloadedOperatorName("*"), hasOverloadedOperatorName("/"),
+              hasOverloadedOperatorName("%"), hasOverloadedOperatorName("="),
+              hasOverloadedOperatorName("&&"), hasOverloadedOperatorName("||"),
+              hasOverloadedOperatorName("&"), hasOverloadedOperatorName("|"),
+              hasOverloadedOperatorName("^")),
+        unless(hasDescendant(atomicExpr())),
+        hasArgument(
+            1, hasDescendant(declRefExpr(to(varDecl(equalsBoundNode("atomic"))))
+                                 .bind("rhs")))
+
+            ))),
+    hasAncestor(binaryOperator(
+        unless(hasDescendant(atomicExpr())),
+        hasRHS(hasDescendant(declRefExpr(to(varDecl(equalsBoundNode("atomic"))))
+                                 .bind("rhs"))))));
+
+void DoNotReferAtomicTwiceCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+      declRefExpr(
+
+          anyOf(hasType(hasUnqualifiedDesugaredType(atomicType())),
+                hasType(recordDecl(hasName("::std::atomic")))),
+          to(varDecl().bind("atomic")),
+
+          BinOp, unless(equalsBoundNode("rhs"))),
+      this);
+}
+
+void DoNotReferAtomicTwiceCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *MatchedVar = Result.Nodes.getNodeAs<VarDecl>("atomic");
+  const auto *MatchedRef = Result.Nodes.getNodeAs<DeclRefExpr>("rhs");
+  if (!MatchedRef || !MatchedVar)
+    return;
+  diag(MatchedRef->getExprLoc(),
+       "Do not refer to atomic variable '%0' twice in an expression")
+      << MatchedVar->getName();
+}
+
+} // namespace bugprone
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
@@ -12,6 +12,7 @@
   BugproneTidyModule.cpp
   CopyConstructorInitCheck.cpp
   DanglingHandleCheck.cpp
+  DoNotReferAtomicTwiceCheck.cpp
   DynamicStaticInitializersCheck.cpp
   ExceptionEscapeCheck.cpp
   FoldInitTypeCheck.cpp
Index: clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
===================================================================
--- clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
+++ clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -17,6 +17,7 @@
 #include "BranchCloneCheck.h"
 #include "CopyConstructorInitCheck.h"
 #include "DanglingHandleCheck.h"
+#include "DoNotReferAtomicTwiceCheck.h"
 #include "DynamicStaticInitializersCheck.h"
 #include "ExceptionEscapeCheck.h"
 #include "FoldInitTypeCheck.h"
@@ -87,6 +88,8 @@
         "bugprone-copy-constructor-init");
     CheckFactories.registerCheck<DanglingHandleCheck>(
         "bugprone-dangling-handle");
+    CheckFactories.registerCheck<DoNotReferAtomicTwiceCheck>(
+        "bugprone-do-not-refer-atomic-twice");
     CheckFactories.registerCheck<DynamicStaticInitializersCheck>(
         "bugprone-dynamic-static-initializers");
     CheckFactories.registerCheck<ExceptionEscapeCheck>(
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to