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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits