-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[clang-tidy] Add avoid-pragma-once. #140388
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
✅ With the latest revision this PR passed the C/C++ code formatter. |
clang-tools-extra/test/clang-tidy/checkers/portability/avoid-pragma-once.cpp
Outdated
Show resolved
Hide resolved
@llvm/pr-subscribers-clang-tidy Author: Tommy Chen (dl8sd11) Changes#139618 Full diff: https://github.com/llvm/llvm-project/pull/140388.diff 9 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPragmaOnceCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPragmaOnceCheck.cpp
new file mode 100644
index 0000000000000..9a835efd4b9e7
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/portability/AvoidPragmaOnceCheck.cpp
@@ -0,0 +1,49 @@
+//===--- AvoidPragmaOnceCheck.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 "AvoidPragmaOnceCheck.h"
+
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang::tidy::portability {
+
+class PragmaOnceCallbacks : public PPCallbacks {
+public:
+ PragmaOnceCallbacks(AvoidPragmaOnceCheck *Check, const SourceManager &SM)
+ : Check(Check), SM(SM) {}
+ void PragmaDirective(SourceLocation Loc,
+ PragmaIntroducerKind Introducer) override {
+ auto Str = llvm::StringRef(SM.getCharacterData(Loc));
+ if (!Str.consume_front("#")) {
+ return;
+ }
+ Str = Str.trim();
+ if (!Str.consume_front("pragma")) {
+ return;
+ }
+ Str = Str.trim();
+ if (Str.starts_with("once")) {
+ Check->diag(Loc, "Avoid pragma once.");
+ }
+ }
+
+private:
+ AvoidPragmaOnceCheck *Check;
+ const SourceManager &SM;
+};
+
+void AvoidPragmaOnceCheck::registerPPCallbacks(const SourceManager &SM,
+ Preprocessor *PP,
+ Preprocessor *ModuleExpanderPP) {
+ PP->addPPCallbacks(std::make_unique<PragmaOnceCallbacks>(this, SM));
+}
+
+} // namespace clang::tidy::portability
diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPragmaOnceCheck.h b/clang-tools-extra/clang-tidy/portability/AvoidPragmaOnceCheck.h
new file mode 100644
index 0000000000000..7208872d416b4
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/portability/AvoidPragmaOnceCheck.h
@@ -0,0 +1,34 @@
+//===--- AvoidPragmaOnceCheck.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_PORTABILITY_AVOIDPRAGMAONCECHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PORTABILITY_AVOIDPRAGMAONCECHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::portability {
+
+/// FIXME: Write a short description.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/portability/avoid-pragma-once.html
+class AvoidPragmaOnceCheck : public ClangTidyCheck {
+public:
+ AvoidPragmaOnceCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+ return LangOpts.CPlusPlus;
+ }
+
+ void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+ Preprocessor *ModuleExpanderPP) override;
+};
+
+} // namespace clang::tidy::portability
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PORTABILITY_AVOIDPRAGMAONCECHECK_H
diff --git a/clang-tools-extra/clang-tidy/portability/CMakeLists.txt b/clang-tools-extra/clang-tidy/portability/CMakeLists.txt
index 5a38722a61481..73d74a550afc0 100644
--- a/clang-tools-extra/clang-tidy/portability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/portability/CMakeLists.txt
@@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS
)
add_clang_library(clangTidyPortabilityModule STATIC
+ AvoidPragmaOnceCheck.cpp
PortabilityTidyModule.cpp
RestrictSystemIncludesCheck.cpp
SIMDIntrinsicsCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp
index 316b98b46cf3f..a15cb36dfdaff 100644
--- a/clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp
@@ -9,6 +9,7 @@
#include "../ClangTidy.h"
#include "../ClangTidyModule.h"
#include "../ClangTidyModuleRegistry.h"
+#include "AvoidPragmaOnceCheck.h"
#include "RestrictSystemIncludesCheck.h"
#include "SIMDIntrinsicsCheck.h"
#include "StdAllocatorConstCheck.h"
@@ -20,6 +21,8 @@ namespace portability {
class PortabilityModule : public ClangTidyModule {
public:
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+ CheckFactories.registerCheck<AvoidPragmaOnceCheck>(
+ "portability-avoid-pragma-once");
CheckFactories.registerCheck<RestrictSystemIncludesCheck>(
"portability-restrict-system-includes");
CheckFactories.registerCheck<SIMDIntrinsicsCheck>(
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 9b29ab12e1bfa..2b8d37054716b 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -142,6 +142,11 @@ New checks
Finds potentially erroneous calls to ``reset`` method on smart pointers when
the pointee type also has a ``reset`` method.
+- New :doc:`portability-avoid-pragma-once
+ <clang-tidy/checks/portability/avoid-pragma-once>` check.
+
+ A check that catches pragma once.
+
New check aliases
^^^^^^^^^^^^^^^^^
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 1ec476eef3420..607c526621cdf 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -351,6 +351,7 @@ Clang-Tidy Checks
:doc:`performance-type-promotion-in-math-fn <performance/type-promotion-in-math-fn>`, "Yes"
:doc:`performance-unnecessary-copy-initialization <performance/unnecessary-copy-initialization>`, "Yes"
:doc:`performance-unnecessary-value-param <performance/unnecessary-value-param>`, "Yes"
+ :doc:`portability-avoid-pragma-once <portability/avoid-pragma-once>`, "Yes"
:doc:`portability-restrict-system-includes <portability/restrict-system-includes>`, "Yes"
:doc:`portability-simd-intrinsics <portability/simd-intrinsics>`,
:doc:`portability-std-allocator-const <portability/std-allocator-const>`,
diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-pragma-once.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-pragma-once.rst
new file mode 100644
index 0000000000000..721511bf395c1
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-pragma-once.rst
@@ -0,0 +1,12 @@
+.. title:: clang-tidy - portability-avoid-pragma-once
+
+portability-avoid-pragma-once
+=============================
+
+This check catches pragma once usage.
+
+For example:
+
+```
+#pragma once // Bad: Avoid pragma once.
+```
diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/Inputs/avoid-pragma-once/lib.h b/clang-tools-extra/test/clang-tidy/checkers/portability/Inputs/avoid-pragma-once/lib.h
new file mode 100644
index 0000000000000..6f70f09beec22
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/portability/Inputs/avoid-pragma-once/lib.h
@@ -0,0 +1 @@
+#pragma once
diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-pragma-once.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-pragma-once.cpp
new file mode 100644
index 0000000000000..e84ad10cb1d93
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-pragma-once.cpp
@@ -0,0 +1,5 @@
+// RUN: %check_clang_tidy %s portability-avoid-pragma-once %t \
+// RUN: -- --header-filter='.*' -- -I%S/Inputs/avoid-pragma-once
+
+#include "lib.h"
+// CHECK-MESSAGES: lib.h:1:1: warning: Avoid pragma once.
\ No newline at end of file
|
@llvm/pr-subscribers-clang-tools-extra Author: Tommy Chen (dl8sd11) Changes#139618 Full diff: https://github.com/llvm/llvm-project/pull/140388.diff 9 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPragmaOnceCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPragmaOnceCheck.cpp
new file mode 100644
index 0000000000000..9a835efd4b9e7
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/portability/AvoidPragmaOnceCheck.cpp
@@ -0,0 +1,49 @@
+//===--- AvoidPragmaOnceCheck.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 "AvoidPragmaOnceCheck.h"
+
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang::tidy::portability {
+
+class PragmaOnceCallbacks : public PPCallbacks {
+public:
+ PragmaOnceCallbacks(AvoidPragmaOnceCheck *Check, const SourceManager &SM)
+ : Check(Check), SM(SM) {}
+ void PragmaDirective(SourceLocation Loc,
+ PragmaIntroducerKind Introducer) override {
+ auto Str = llvm::StringRef(SM.getCharacterData(Loc));
+ if (!Str.consume_front("#")) {
+ return;
+ }
+ Str = Str.trim();
+ if (!Str.consume_front("pragma")) {
+ return;
+ }
+ Str = Str.trim();
+ if (Str.starts_with("once")) {
+ Check->diag(Loc, "Avoid pragma once.");
+ }
+ }
+
+private:
+ AvoidPragmaOnceCheck *Check;
+ const SourceManager &SM;
+};
+
+void AvoidPragmaOnceCheck::registerPPCallbacks(const SourceManager &SM,
+ Preprocessor *PP,
+ Preprocessor *ModuleExpanderPP) {
+ PP->addPPCallbacks(std::make_unique<PragmaOnceCallbacks>(this, SM));
+}
+
+} // namespace clang::tidy::portability
diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPragmaOnceCheck.h b/clang-tools-extra/clang-tidy/portability/AvoidPragmaOnceCheck.h
new file mode 100644
index 0000000000000..7208872d416b4
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/portability/AvoidPragmaOnceCheck.h
@@ -0,0 +1,34 @@
+//===--- AvoidPragmaOnceCheck.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_PORTABILITY_AVOIDPRAGMAONCECHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PORTABILITY_AVOIDPRAGMAONCECHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::portability {
+
+/// FIXME: Write a short description.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/portability/avoid-pragma-once.html
+class AvoidPragmaOnceCheck : public ClangTidyCheck {
+public:
+ AvoidPragmaOnceCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+ return LangOpts.CPlusPlus;
+ }
+
+ void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+ Preprocessor *ModuleExpanderPP) override;
+};
+
+} // namespace clang::tidy::portability
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PORTABILITY_AVOIDPRAGMAONCECHECK_H
diff --git a/clang-tools-extra/clang-tidy/portability/CMakeLists.txt b/clang-tools-extra/clang-tidy/portability/CMakeLists.txt
index 5a38722a61481..73d74a550afc0 100644
--- a/clang-tools-extra/clang-tidy/portability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/portability/CMakeLists.txt
@@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS
)
add_clang_library(clangTidyPortabilityModule STATIC
+ AvoidPragmaOnceCheck.cpp
PortabilityTidyModule.cpp
RestrictSystemIncludesCheck.cpp
SIMDIntrinsicsCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp
index 316b98b46cf3f..a15cb36dfdaff 100644
--- a/clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp
@@ -9,6 +9,7 @@
#include "../ClangTidy.h"
#include "../ClangTidyModule.h"
#include "../ClangTidyModuleRegistry.h"
+#include "AvoidPragmaOnceCheck.h"
#include "RestrictSystemIncludesCheck.h"
#include "SIMDIntrinsicsCheck.h"
#include "StdAllocatorConstCheck.h"
@@ -20,6 +21,8 @@ namespace portability {
class PortabilityModule : public ClangTidyModule {
public:
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+ CheckFactories.registerCheck<AvoidPragmaOnceCheck>(
+ "portability-avoid-pragma-once");
CheckFactories.registerCheck<RestrictSystemIncludesCheck>(
"portability-restrict-system-includes");
CheckFactories.registerCheck<SIMDIntrinsicsCheck>(
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 9b29ab12e1bfa..2b8d37054716b 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -142,6 +142,11 @@ New checks
Finds potentially erroneous calls to ``reset`` method on smart pointers when
the pointee type also has a ``reset`` method.
+- New :doc:`portability-avoid-pragma-once
+ <clang-tidy/checks/portability/avoid-pragma-once>` check.
+
+ A check that catches pragma once.
+
New check aliases
^^^^^^^^^^^^^^^^^
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 1ec476eef3420..607c526621cdf 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -351,6 +351,7 @@ Clang-Tidy Checks
:doc:`performance-type-promotion-in-math-fn <performance/type-promotion-in-math-fn>`, "Yes"
:doc:`performance-unnecessary-copy-initialization <performance/unnecessary-copy-initialization>`, "Yes"
:doc:`performance-unnecessary-value-param <performance/unnecessary-value-param>`, "Yes"
+ :doc:`portability-avoid-pragma-once <portability/avoid-pragma-once>`, "Yes"
:doc:`portability-restrict-system-includes <portability/restrict-system-includes>`, "Yes"
:doc:`portability-simd-intrinsics <portability/simd-intrinsics>`,
:doc:`portability-std-allocator-const <portability/std-allocator-const>`,
diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-pragma-once.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-pragma-once.rst
new file mode 100644
index 0000000000000..721511bf395c1
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-pragma-once.rst
@@ -0,0 +1,12 @@
+.. title:: clang-tidy - portability-avoid-pragma-once
+
+portability-avoid-pragma-once
+=============================
+
+This check catches pragma once usage.
+
+For example:
+
+```
+#pragma once // Bad: Avoid pragma once.
+```
diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/Inputs/avoid-pragma-once/lib.h b/clang-tools-extra/test/clang-tidy/checkers/portability/Inputs/avoid-pragma-once/lib.h
new file mode 100644
index 0000000000000..6f70f09beec22
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/portability/Inputs/avoid-pragma-once/lib.h
@@ -0,0 +1 @@
+#pragma once
diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-pragma-once.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-pragma-once.cpp
new file mode 100644
index 0000000000000..e84ad10cb1d93
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-pragma-once.cpp
@@ -0,0 +1,5 @@
+// RUN: %check_clang_tidy %s portability-avoid-pragma-once %t \
+// RUN: -- --header-filter='.*' -- -I%S/Inputs/avoid-pragma-once
+
+#include "lib.h"
+// CHECK-MESSAGES: lib.h:1:1: warning: Avoid pragma once.
\ No newline at end of file
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good check!
Mostly docs/phrasing comments from me.
clang-tools-extra/test/clang-tidy/checkers/portability/Inputs/avoid-pragma-once/lib.h
Outdated
Show resolved
Hide resolved
clang-tools-extra/test/clang-tidy/checkers/portability/avoid-pragma-once.cpp
Outdated
Show resolved
Hide resolved
clang-tools-extra/docs/clang-tidy/checks/portability/avoid-pragma-once.rst
Outdated
Show resolved
Hide resolved
clang-tools-extra/docs/clang-tidy/checks/portability/avoid-pragma-once.rst
Outdated
Show resolved
Hide resolved
clang-tools-extra/docs/clang-tidy/checks/portability/avoid-pragma-once.rst
Show resolved
Hide resolved
clang-tools-extra/clang-tidy/portability/AvoidPragmaOnceCheck.h
Outdated
Show resolved
Hide resolved
clang-tools-extra/clang-tidy/portability/AvoidPragmaOnceCheck.cpp
Outdated
Show resolved
Hide resolved
clang-tools-extra/clang-tidy/portability/AvoidPragmaOnceCheck.cpp
Outdated
Show resolved
Hide resolved
clang-tools-extra/docs/clang-tidy/checks/portability/avoid-pragma-once.rst
Outdated
Show resolved
Hide resolved
Fixed! First time adding a clang-tidy check! Apologies for missing the conventions, and huge thanks for your time reviewing. |
clang-tools-extra/docs/clang-tidy/checks/portability/avoid-pragma-once.rst
Outdated
Show resolved
Hide resolved
clang-tools-extra/docs/clang-tidy/checks/portability/avoid-pragma-once.rst
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some more nit changes.
If you want to contribute further, reading https://clang.llvm.org/extra/clang-tidy/Contributing.html may help you.
Particularly "Making your check robust" and "Documenting your check". Although, most of it already covered in comments.
clang-tools-extra/clang-tidy/portability/AvoidPragmaOnceCheck.cpp
Outdated
Show resolved
Hide resolved
clang-tools-extra/clang-tidy/portability/AvoidPragmaOnceCheck.cpp
Outdated
Show resolved
Hide resolved
clang-tools-extra/clang-tidy/portability/AvoidPragmaOnceCheck.cpp
Outdated
Show resolved
Hide resolved
clang-tools-extra/docs/clang-tidy/checks/portability/avoid-pragma-once.rst
Outdated
Show resolved
Hide resolved
clang-tools-extra/docs/clang-tidy/checks/portability/avoid-pragma-once.rst
Outdated
Show resolved
Hide resolved
clang-tools-extra/docs/clang-tidy/checks/portability/avoid-pragma-once.rst
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documentation may require some improvements, but overall looks fine.
#139618