https://github.com/localspook created https://github.com/llvm/llvm-project/pull/152401
`modernize-replace-auto-ptr`, `modernize-use-equals-delete`, and `modernize-use-auto` use `std::unique_ptr`, `= delete`, and `auto` respectively, which are all C++11 features. The interesting bit is `modernize-use-nullptr`'s tests: - Some relied on int-to-pointer conversions that were removed in C++11. I just deleted these cases; if they're ill-formed, we're not losing anything, right? - Uncovered some cases that are false negatives in C++11 mode. >From f09e05a1aee29d94e908c3ef73d422bad65a3b34 Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <chernyakin.victo...@outlook.com> Date: Wed, 6 Aug 2025 15:31:55 -0700 Subject: [PATCH] [clang-tidy] Raise minimum standard level for several checks from C++98 to C++11 --- .../modernize/ReplaceAutoPtrCheck.h | 2 +- .../clang-tidy/modernize/UseAutoCheck.h | 2 +- .../modernize/UseEqualsDeleteCheck.h | 2 +- .../clang-tidy/modernize/UseNullptrCheck.h | 4 +- .../checkers/modernize/use-nullptr-basic.cpp | 102 +++++------------- 5 files changed, 29 insertions(+), 83 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.h b/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.h index 636481300d730..c91f5f580c524 100644 --- a/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.h @@ -42,7 +42,7 @@ class ReplaceAutoPtrCheck : public ClangTidyCheck { public: ReplaceAutoPtrCheck(StringRef Name, ClangTidyContext *Context); bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { - return LangOpts.CPlusPlus; + return LangOpts.CPlusPlus11; } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; diff --git a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.h b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.h index 76c52b2d28139..7a9bbbe1cdf77 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.h @@ -17,7 +17,7 @@ class UseAutoCheck : public ClangTidyCheck { public: UseAutoCheck(StringRef Name, ClangTidyContext *Context); bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { - return LangOpts.CPlusPlus; + return LangOpts.CPlusPlus11; } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; diff --git a/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.h b/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.h index 64f60351c0657..dc3e712482c21 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.h @@ -23,7 +23,7 @@ class UseEqualsDeleteCheck : public ClangTidyCheck { public: UseEqualsDeleteCheck(StringRef Name, ClangTidyContext *Context); bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { - return LangOpts.CPlusPlus; + return LangOpts.CPlusPlus11; } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; diff --git a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.h b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.h index f1591bae44657..4c02f8ccdf303 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.h @@ -17,9 +17,7 @@ class UseNullptrCheck : public ClangTidyCheck { public: UseNullptrCheck(StringRef Name, ClangTidyContext *Context); bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { - // FIXME this should be CPlusPlus11 but that causes test cases to - // erroneously fail. - return LangOpts.CPlusPlus || LangOpts.C23; + return LangOpts.CPlusPlus11 || LangOpts.C23; } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-basic.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-basic.cpp index 2579099148e3a..4f69ec5aeeb4c 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-basic.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-basic.cpp @@ -1,9 +1,4 @@ -// RUN: %check_clang_tidy -std=c++98 %s modernize-use-nullptr %t -- -- -Wno-non-literal-null-conversion -// -// Some parts of the test (e.g. assignment of `const int` to `int *`) fail in -// C++11, so we need to run the test in C++98 mode. -// -// FIXME: Make the test work in all language modes. +// RUN: %check_clang_tidy %s modernize-use-nullptr %t -- -- -Wno-non-literal-null-conversion const unsigned int g_null = 0; #define NULL 0 @@ -23,11 +18,7 @@ void test_assignment() { p2 = p1; // CHECK-FIXES: p2 = p1; - const int null = 0; - int *p3 = null; - // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr - // CHECK-FIXES: int *p3 = nullptr; - + int *p3; p3 = NULL; // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use nullptr // CHECK-FIXES: p3 = nullptr; @@ -35,14 +26,11 @@ void test_assignment() { int *p4 = p3; // CHECK-FIXES: int *p4 = p3; - p4 = null; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use nullptr - // CHECK-FIXES: p4 = nullptr; - int i1 = 0; int i2 = NULL; + const int null = 0; int i3 = null; int *p5, *p6, *p7; @@ -70,33 +58,30 @@ int *Foo::m_p2 = NULL; // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr // CHECK-FIXES: int *Foo::m_p2 = nullptr; +// FIXME: all these DISABLED-* cases should trigger the warning. template <typename T> struct Bar { Bar(T *p) : m_p(p) { m_p = static_cast<T*>(NULL); - // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use nullptr - // CHECK-FIXES: m_p = static_cast<T*>(nullptr); + // DISABLED-CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use nullptr + // DISABLED-CHECK-FIXES: m_p = static_cast<T*>(nullptr); m_p = static_cast<T*>(reinterpret_cast<int*>((void*)NULL)); // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use nullptr // CHECK-FIXES: m_p = static_cast<T*>(nullptr); - m_p = static_cast<T*>(p ? p : static_cast<void*>(g_null)); - // CHECK-MESSAGES: :[[@LINE-1]]:54: warning: use nullptr - // CHECK-FIXES: m_p = static_cast<T*>(p ? p : static_cast<void*>(nullptr)); - T *p2 = static_cast<T*>(reinterpret_cast<int*>((void*)NULL)); // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use nullptr // CHECK-FIXES: T *p2 = static_cast<T*>(nullptr); m_p = NULL; - // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use nullptr - // CHECK-FIXES: m_p = nullptr; + // DISABLED-CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use nullptr + // DISABLED-CHECK-FIXES: m_p = nullptr; int i = static_cast<int>(0.f); T *i2 = static_cast<int>(0.f); - // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr - // CHECK-FIXES: T *i2 = nullptr; + // DISABLED-CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr + // DISABLED-CHECK-FIXES: T *i2 = nullptr; } T *m_p; @@ -108,9 +93,7 @@ struct Baz { }; void test_cxx_cases() { - Foo f(g_null); - // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr - // CHECK-FIXES: Foo f(nullptr); + Foo f; f.bar(NULL); // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr @@ -122,10 +105,6 @@ void test_cxx_cases() { // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr // CHECK-FIXES: f.m_p1 = nullptr; - Bar<int> b(g_null); - // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use nullptr - // CHECK-FIXES: Bar<int> b(nullptr); - Baz b2; int Baz::*memptr(0); // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use nullptr @@ -144,10 +123,6 @@ void test_function_default_param2(void *p = NULL); // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use nullptr // CHECK-FIXES: void test_function_default_param2(void *p = nullptr); -void test_function_default_param3(void *p = g_null); -// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use nullptr -// CHECK-FIXES: void test_function_default_param3(void *p = nullptr); - void test_function(int *p) {} void test_function_no_ptr_param(int i) {} @@ -161,10 +136,6 @@ void test_function_call() { // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use nullptr // CHECK-FIXES: test_function(nullptr); - test_function(g_null); - // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use nullptr - // CHECK-FIXES: test_function(nullptr); - test_function_no_ptr_param(0); } @@ -180,51 +151,33 @@ void *test_function_return2() { // CHECK-FIXES: return nullptr; } -long *test_function_return3() { - return g_null; - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr - // CHECK-FIXES: return nullptr; -} - -int test_function_return4() { +int test_function_return3() { return 0; } -int test_function_return5() { +int test_function_return4() { return NULL; } -int test_function_return6() { +int test_function_return5() { return g_null; } -int *test_function_return_cast1() { - return(int)0; - // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr - // CHECK-FIXES: return nullptr; -} - -int *test_function_return_cast2() { +int *test_function_return_cast() { #define RET return - RET(int)0; - // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use nullptr + RET 0; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use nullptr // CHECK-FIXES: RET nullptr; #undef RET } // Test parentheses expressions resulting in a nullptr. -int *test_parentheses_expression1() { +int *test_parentheses_expression() { return(0); // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr // CHECK-FIXES: return(nullptr); } -int *test_parentheses_expression2() { - return(int(0.f)); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr - // CHECK-FIXES: return(nullptr); -} - int *test_nested_parentheses_expression() { return((((0)))); // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr @@ -243,10 +196,11 @@ void *test_parentheses_explicit_cast_sequence1() { // CHECK-FIXES: return(static_cast<void*>(nullptr)); } +// FIXME: this case should trigger the warning. void *test_parentheses_explicit_cast_sequence2() { return(static_cast<void*>(reinterpret_cast<int*>((float*)int(0.f)))); - // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use nullptr - // CHECK-FIXES: return(static_cast<void*>(nullptr)); + // DISABLED-CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use nullptr + // DISABLED-CHECK-FIXES: return(static_cast<void*>(nullptr)); } // Test explicit cast expressions resulting in nullptr. @@ -313,19 +267,13 @@ void test_const_pointers() { const int *const_p2 = NULL; // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr // CHECK-FIXES: const int *const_p2 = nullptr; - const int *const_p3 = (int)0; - // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr - // CHECK-FIXES: const int *const_p3 = nullptr; - const int *const_p4 = (int)0.0f; - // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr - // CHECK-FIXES: const int *const_p4 = nullptr; - const int *const_p5 = (int*)0; + const int *const_p3 = (int*)0; // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use nullptr - // CHECK-FIXES: const int *const_p5 = (int*)nullptr; + // CHECK-FIXES: const int *const_p3 = (int*)nullptr; int *t; - const int *const_p6 = static_cast<int*>(t ? t : static_cast<int*>(0)); + const int *const_p4 = static_cast<int*>(t ? t : static_cast<int*>(0)); // CHECK-MESSAGES: :[[@LINE-1]]:69: warning: use nullptr - // CHECK-FIXES: const int *const_p6 = static_cast<int*>(t ? t : static_cast<int*>(nullptr)); + // CHECK-FIXES: const int *const_p4 = static_cast<int*>(t ? t : static_cast<int*>(nullptr)); } void test_nested_implicit_cast_expr() { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits