-
Notifications
You must be signed in to change notification settings - Fork 15k
[clang-tidy] Teach modernize-deprecated-headers about more no-op headers
#165674
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
|
@llvm/pr-subscribers-clang-tidy @llvm/pr-subscribers-clang-tools-extra Author: Victor Chernyakin (localspook) ChangesFirst, this PR adds some more no-op C++ headers: Full diff: https://github.com/llvm/llvm-project/pull/165674.diff 11 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.cpp
index 1de9e136c5719..aa27cfd5ce81d 100644
--- a/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.cpp
@@ -115,9 +115,9 @@ void DeprecatedHeadersCheck::check(
// Emit all the remaining reports.
for (const IncludeMarker &Marker : IncludesToBeProcessed) {
if (Marker.Replacement.empty()) {
- diag(Marker.DiagLoc,
- "including '%0' has no effect in C++; consider removing it")
- << Marker.FileName
+ diag(Marker.DiagLoc, "including '%0' has no effect %select{since C23|in "
+ "C++}1; consider removing it")
+ << Marker.FileName << getLangOpts().CPlusPlus
<< FixItHint::CreateRemoval(Marker.ReplacementRange);
} else {
diag(Marker.DiagLoc, "inclusion of deprecated C++ header "
@@ -147,7 +147,9 @@ IncludeModernizePPCallbacks::IncludeModernizePPCallbacks(
{"string.h", "cstring"}, {"time.h", "ctime"},
{"wchar.h", "cwchar"}, {"wctype.h", "cwctype"},
};
- CStyledHeaderToCxx.insert(std::begin(CXX98Headers), std::end(CXX98Headers));
+
+ if (LangOpts.CPlusPlus)
+ CStyledHeaderToCxx.insert(std::begin(CXX98Headers), std::end(CXX98Headers));
static constexpr std::pair<StringRef, StringRef> CXX11Headers[] = {
{"fenv.h", "cfenv"}, {"stdint.h", "cstdint"},
@@ -157,9 +159,16 @@ IncludeModernizePPCallbacks::IncludeModernizePPCallbacks(
if (LangOpts.CPlusPlus11)
CStyledHeaderToCxx.insert(std::begin(CXX11Headers), std::end(CXX11Headers));
- static constexpr StringRef HeadersToDelete[] = {"stdalign.h", "stdbool.h",
- "iso646.h"};
- DeleteHeaders.insert_range(HeadersToDelete);
+ static constexpr StringRef CXXHeadersToDelete[] = {"stdalign.h", "cstdalign",
+ "stdbool.h", "cstdbool",
+ "iso646.h", "ciso646"};
+ if (LangOpts.CPlusPlus)
+ DeleteHeaders.insert_range(CXXHeadersToDelete);
+
+ static constexpr StringRef C23HeadersToDelete[] = {"stdalign.h", "stdbool.h",
+ "stdnoreturn.h"};
+ if (LangOpts.C23)
+ DeleteHeaders.insert_range(C23HeadersToDelete);
}
void IncludeModernizePPCallbacks::InclusionDirective(
diff --git a/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.h b/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.h
index badb2b41f164f..1b7c1821fb19c 100644
--- a/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.h
@@ -34,7 +34,7 @@ class DeprecatedHeadersCheck : public ClangTidyCheck {
public:
DeprecatedHeadersCheck(StringRef Name, ClangTidyContext *Context);
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
- return LangOpts.CPlusPlus;
+ return LangOpts.CPlusPlus || LangOpts.C23;
}
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 33cc401bcb78f..c2ed8b643c590 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -346,6 +346,10 @@ Changes in existing checks
<clang-tidy/checks/modernize/avoid-c-arrays>` to not diagnose array types
which are part of an implicit instantiation of a template.
+- Improved :doc:`modernize-deprecated-headers
+ <clang-tidy/checks/modernize/deprecated-headers>` to diagnose more
+ deprecated headers, in both C++ and (for the first time) in C.
+
- Improved :doc:`modernize-use-constraints
<clang-tidy/checks/modernize/use-constraints>` check by fixing a crash on
uses of non-standard ``enable_if`` with a signature different from
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/deprecated-headers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/deprecated-headers.rst
index 6c35cd4e53d87..8dcc8580b2ccc 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/deprecated-headers.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/deprecated-headers.rst
@@ -3,12 +3,55 @@
modernize-deprecated-headers
============================
-Some headers from C library were deprecated in C++ and are no longer welcome in
-C++ codebases. Some have no effect in C++. For more details refer to the C++14
-Standard [depr.c.headers] section.
-
-This check replaces C standard library headers with their C++ alternatives and
-removes redundant ones.
+There exist headers that produce no effect when included, which are there
+solely to ease migrating code. The check will suggest removing them.
+In C++, they are:
+
+* ``stdalign.h`` / ``cstdalign``
+* ``stdbool.h`` / ``cstdbool``
+* ``iso646.h`` / ``ciso646``
+
+And in C they are:
+
+* ``stdalign.h`` // No-op since C23
+* ``stdbool.h`` // No-op since C23
+* ``stdnoreturn.h`` // No-op since C23
+
+In C++, there is additionally a number of headers intended for
+interoperability with C, which should not be used in pure C++ code.
+The check will suggest replacing them with their C++ counterparts
+(e.g. replacing ``<signal.h>`` with ``<csignal>``). These headers are:
+
+* ``<assert.h>``
+* ``<complex.h>``
+* ``<ctype.h>``
+* ``<errno.h>``
+* ``<fenv.h>`` // deprecated since C++11
+* ``<float.h>``
+* ``<inttypes.h>``
+* ``<limits.h>``
+* ``<locale.h>``
+* ``<math.h>``
+* ``<setjmp.h>``
+* ``<signal.h>``
+* ``<stdarg.h>``
+* ``<stddef.h>``
+* ``<stdint.h>``
+* ``<stdio.h>``
+* ``<stdlib.h>``
+* ``<string.h>``
+* ``<tgmath.h>`` // deprecated since C++11
+* ``<time.h>``
+* ``<uchar.h>`` // deprecated since C++11
+* ``<wchar.h>``
+* ``<wctype.h>``
+
+Important note: the C++ headers are not identical to their C counterparts.
+The C headers provide names in the global namespace (e.g. ``<stdio.h>``
+provides ``printf``), but the C++ headers might provide them only in the
+``std`` namespace (e.g. ``<cstdio>`` provides ``std::printf``, but not
+necessarily ``printf``). The check can break code that uses the unqualified
+names.
.. code-block:: c++
@@ -21,46 +64,9 @@ removes redundant ones.
#include <cassert>
// No 'stdbool.h' here.
-Important note: the Standard doesn't guarantee that the C++ headers declare all
-the same functions in the global namespace. The check in its current form can
-break the code that uses library symbols from the global namespace.
-
-* `<assert.h>`
-* `<complex.h>`
-* `<ctype.h>`
-* `<errno.h>`
-* `<fenv.h>` // deprecated since C++11
-* `<float.h>`
-* `<inttypes.h>`
-* `<limits.h>`
-* `<locale.h>`
-* `<math.h>`
-* `<setjmp.h>`
-* `<signal.h>`
-* `<stdarg.h>`
-* `<stddef.h>`
-* `<stdint.h>`
-* `<stdio.h>`
-* `<stdlib.h>`
-* `<string.h>`
-* `<tgmath.h>` // deprecated since C++11
-* `<time.h>`
-* `<uchar.h>` // deprecated since C++11
-* `<wchar.h>`
-* `<wctype.h>`
-
-If the specified standard is older than C++11 the check will only replace
-headers deprecated before C++11, otherwise -- every header that appeared in
-the previous list.
-
-These headers don't have effect in C++:
-
-* `<iso646.h>`
-* `<stdalign.h>`
-* `<stdbool.h>`
-
-The checker ignores `include` directives within `extern "C" { ... }` blocks,
-since a library might want to expose some API for C and C++ libraries.
+The check will ignore `include` directives within `extern "C" { ... }`
+blocks, under the assumption that such code is an API meant to compile as
+both C and C++:
.. code-block:: c++
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/deprecated-headers/ciso646 b/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/deprecated-headers/ciso646
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/deprecated-headers/cstdalign b/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/deprecated-headers/cstdalign
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/deprecated-headers/cstdbool b/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/deprecated-headers/cstdbool
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/deprecated-headers/stdnoreturn.h b/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/deprecated-headers/stdnoreturn.h
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/deprecated-headers-c23.c b/clang-tools-extra/test/clang-tidy/checkers/modernize/deprecated-headers-c23.c
new file mode 100644
index 0000000000000..f81f9981abaa6
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/deprecated-headers-c23.c
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy -std=c23-or-later %s modernize-deprecated-headers %t -- -extra-arg-before=-isystem%S/Inputs/deprecated-headers
+
+#include <stdalign.h> // <stdalign.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdalign.h' has no effect since C23; consider removing it
+// CHECK-FIXES: // <stdalign.h>
+#include <stdbool.h> // <stdbool.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdbool.h' has no effect since C23; consider removing it
+// CHECK-FIXES: // <stdbool.h>
+#include <stdnoreturn.h> // <stdnoreturn.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdnoreturn.h' has no effect since C23; consider removing it
+// CHECK-FIXES: // <stdnoreturn.h>
+
+#include <stdio.h> // OK, not deprecated
+
+#include "stdalign.h" // "stdalign.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdalign.h' has no effect since C23; consider removing it
+// CHECK-FIXES: // "stdalign.h"
+#include "stdbool.h" // "stdbool.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdbool.h' has no effect since C23; consider removing it
+// CHECK-FIXES: // "stdbool.h"
+#include "stdnoreturn.h" // "stdnoreturn.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdnoreturn.h' has no effect since C23; consider removing it
+// CHECK-FIXES: // "stdnoreturn.h"
+
+#include "stdio.h" // OK, not deprecated
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/deprecated-headers-cxx03.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/deprecated-headers-cxx03.cpp
index b02dfd1ce976f..01bb62e99f16f 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/deprecated-headers-cxx03.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/deprecated-headers-cxx03.cpp
@@ -59,12 +59,21 @@
#include <stdalign.h> // <stdalign.h>
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdalign.h' has no effect in C++; consider removing it
// CHECK-FIXES: // <stdalign.h>
+#include <cstdalign> // <cstdalign>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'cstdalign' has no effect in C++; consider removing it
+// CHECK-FIXES: // <cstdalign>
#include <stdbool.h> // <stdbool.h>
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdbool.h' has no effect in C++; consider removing it
// CHECK-FIXES: // <stdbool.h>
+#include <cstdbool> // <cstdbool>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'cstdbool' has no effect in C++; consider removing it
+// CHECK-FIXES: // <cstdbool>
#include <iso646.h> // <iso646.h>
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'iso646.h' has no effect in C++; consider removing it
// CHECK-FIXES: // <iso646.h>
+#include <ciso646> // <ciso646>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'ciso646' has no effect in C++; consider removing it
+// CHECK-FIXES: // <ciso646>
// Headers deprecated since C++11: expect no diagnostics.
#include <fenv.h>
@@ -133,12 +142,21 @@
#include "stdalign.h" // "stdalign.h"
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdalign.h' has no effect in C++; consider removing it
// CHECK-FIXES: // "stdalign.h"
+#include "cstdalign" // "cstdalign"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'cstdalign' has no effect in C++; consider removing it
+// CHECK-FIXES: // "cstdalign"
#include "stdbool.h" // "stdbool.h"
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdbool.h' has no effect in C++; consider removing it
// CHECK-FIXES: // "stdbool.h"
+#include "cstdbool" // "cstdbool"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'cstdbool' has no effect in C++; consider removing it
+// CHECK-FIXES: // "cstdbool"
#include "iso646.h" // "iso646.h"
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'iso646.h' has no effect in C++; consider removing it
// CHECK-FIXES: // "iso646.h"
+#include "ciso646" // "ciso646"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'ciso646' has no effect in C++; consider removing it
+// CHECK-FIXES: // "ciso646"
// Headers deprecated since C++11; expect no diagnostics
#include "fenv.h"
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/deprecated-headers-cxx11.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/deprecated-headers-cxx11.cpp
index 99ef506276a66..d4af364f0a844 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/deprecated-headers-cxx11.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/deprecated-headers-cxx11.cpp
@@ -74,12 +74,21 @@
#include <stdalign.h> // <stdalign.h>
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdalign.h' has no effect in C++; consider removing it
// CHECK-FIXES: // <stdalign.h>
+#include <cstdalign> // <cstdalign>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'cstdalign' has no effect in C++; consider removing it
+// CHECK-FIXES: // <cstdalign>
#include <stdbool.h> // <stdbool.h>
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdbool.h' has no effect in C++; consider removing it
// CHECK-FIXES: // <stdbool.h>
+#include <cstdbool> // <cstdbool>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'cstdbool' has no effect in C++; consider removing it
+// CHECK-FIXES: // <cstdbool>
#include <iso646.h> // <iso646.h>
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'iso646.h' has no effect in C++; consider removing it
// CHECK-FIXES: // <iso646.h>
+#include <ciso646> // <ciso646>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'ciso646' has no effect in C++; consider removing it
+// CHECK-FIXES: // <ciso646>
#include "assert.h"
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'assert.h'; consider using 'cassert' instead
@@ -155,9 +164,18 @@
#include "stdalign.h" // "stdalign.h"
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdalign.h' has no effect in C++; consider removing it
// CHECK-FIXES: // "stdalign.h"
+#include "cstdalign" // "cstdalign"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'cstdalign' has no effect in C++; consider removing it
+// CHECK-FIXES: // "cstdalign"
#include "stdbool.h" // "stdbool.h"
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdbool.h' has no effect in C++; consider removing it
// CHECK-FIXES: // "stdbool.h"
+#include "cstdbool" // "cstdbool"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'cstdbool' has no effect in C++; consider removing it
+// CHECK-FIXES: // "cstdbool"
#include "iso646.h" // "iso646.h"
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'iso646.h' has no effect in C++; consider removing it
// CHECK-FIXES: // "iso646.h"
+#include "ciso646" // "ciso646"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'ciso646' has no effect in C++; consider removing it
+// CHECK-FIXES: // "ciso646"
|
First, this PR adds some more no-op C++ headers:
<cstdbool>,<cstdalign>, and<ciso646>. Second, it adds some headers that are no-ops in C23:<stdbool.h>,<stdnoreturn.h>, and<stdalign.h>. Up until now, this was a C++-only check, so adding support for C headers required somewhat invasive changes. In particular, the current docs are written from a C++ point of view, so I had to rework them to make it clear that the check is relevant for C as well.