https://github.com/zeyi2 created https://github.com/llvm/llvm-project/pull/184015
This PR adds testcases for untested Options in `bugprone` module for better test coverage, specifically: - `bugprone-implicit-widening-of-multiplication-result`: `UseCXXHeadersInCppSources` and `IncludeStyle`. - `bugprone-not-null-terminated-result`: `WantToUseSafeFunctions` - `bugprone-signed-char-misuse`: `DiagnoseSignedUnsignedCharComparisons` - `bugprone-sizeof-expression`: `WarnOnSizeOfConstant`, `WarnOnSizeOfThis`, `WarnOnSizeOfCompareToConstant`, `WarnOnSizeOfInLoopTermination`. - `bugprone-string-constructor`: `WarnOnLargeLength`, `LargeLengthThreshold`, `StringNames`. - `bugprone-suspicious-missing-comma`: `SizeThreshold`, `RatioThreshold`, `MaxConcatenatedTokens`. - `bugprone-suspicious-string-compare`: `StringCompareLikeFunctions` - `bugprone-suspicious-stringview-data-usage`: `StringViewTypes`, `AllowedCallees` As of AI Usage: Assisted by Gemini 3 and Claude (Writing part of the testcases and pre-commit reviewing). >From 00bfcb9d826a75d89c11c2dba1dbddb7685c62b6 Mon Sep 17 00:00:00 2001 From: mtx <[email protected]> Date: Sun, 1 Mar 2026 22:48:29 +0800 Subject: [PATCH] [clang-tidy][NFC] Add missing Option tests in `bugprone` --- ...ening-of-multiplication-result-options.cpp | 19 ++++++ ...null-terminated-result-no-safe-functions.c | 17 +++++ .../signed-char-misuse-no-comparison.cpp | 18 ++++++ .../sizeof-expression-disable-options.cpp | 33 ++++++++++ .../bugprone/string-constructor-options.cpp | 64 +++++++++++++++++++ .../suspicious-missing-comma-options.cpp | 32 ++++++++++ ...icious-string-compare-custom-functions.cpp | 26 ++++++++ ...spicious-stringview-data-usage-options.cpp | 42 ++++++++++++ ...used-return-value-checked-return-types.cpp | 36 +++++++++++ 9 files changed, 287 insertions(+) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/implicit-widening-of-multiplication-result-options.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-no-safe-functions.c create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/signed-char-misuse-no-comparison.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression-disable-options.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/string-constructor-options.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-missing-comma-options.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-string-compare-custom-functions.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-stringview-data-usage-options.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-return-value-checked-return-types.cpp diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/implicit-widening-of-multiplication-result-options.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/implicit-widening-of-multiplication-result-options.cpp new file mode 100644 index 0000000000000..86476d9bac0bb --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/implicit-widening-of-multiplication-result-options.cpp @@ -0,0 +1,19 @@ +// RUN: %check_clang_tidy %s bugprone-implicit-widening-of-multiplication-result %t -- \ +// RUN: -config="{CheckOptions: { \ +// RUN: bugprone-implicit-widening-of-multiplication-result.UseCXXHeadersInCppSources: false, \ +// RUN: bugprone-implicit-widening-of-multiplication-result.IncludeStyle: google \ +// RUN: }}" -- -target x86_64-unknown-unknown -x c++ + +long mul(int a, int b) { + return a * b; + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: performing an implicit widening conversion to type 'long' of a multiplication performed in type 'int' [bugprone-implicit-widening-of-multiplication-result] + // CHECK-MESSAGES: :[[@LINE-2]]:10: note: make conversion explicit to silence this warning + // CHECK-MESSAGES: :[[@LINE-3]]:10: note: perform multiplication in a wider type +} + +long ptr_off(int a, int b, char *p) { + return p[a * b]; + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: result of multiplication in type 'int' is used as a pointer offset after an implicit widening conversion to type 'ptrdiff_t' [bugprone-implicit-widening-of-multiplication-result] + // CHECK-MESSAGES: :[[@LINE-2]]:12: note: make conversion explicit to silence this warning + // CHECK-MESSAGES: :[[@LINE-3]]:12: note: perform multiplication in a wider type +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-no-safe-functions.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-no-safe-functions.c new file mode 100644 index 0000000000000..0372edbdb468a --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-no-safe-functions.c @@ -0,0 +1,17 @@ +// RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \ +// RUN: -config="{CheckOptions: { \ +// RUN: bugprone-not-null-terminated-result.WantToUseSafeFunctions: false \ +// RUN: }}" -- -I %S/Inputs/not-null-terminated-result + +#include "not-null-terminated-result-c.h" + +#define __STDC_LIB_EXT1__ 1 +#define __STDC_WANT_LIB_EXT1__ 1 + +void test_memcpy_no_safe(const char *src) { + char dest[13]; + memcpy(dest, src, strlen(src)); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result] + // CHECK-FIXES: char dest[14]; + // CHECK-FIXES-NEXT: strcpy(dest, src); +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/signed-char-misuse-no-comparison.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/signed-char-misuse-no-comparison.cpp new file mode 100644 index 0000000000000..0b31608c133ca --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/signed-char-misuse-no-comparison.cpp @@ -0,0 +1,18 @@ +// RUN: %check_clang_tidy %s bugprone-signed-char-misuse %t -- \ +// RUN: -config="{CheckOptions: { \ +// RUN: bugprone-signed-char-misuse.DiagnoseSignedUnsignedCharComparisons: false \ +// RUN: }}" + +int SignedToIntConversion() { + signed char CCharacter = -5; + int NCharacter = CCharacter; + // CHECK-MESSAGES: [[@LINE-1]]:20: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse] + return NCharacter; +} + +int SignedUnsignedCharComparison(signed char SCharacter) { + unsigned char USCharacter = 'a'; + if (SCharacter == USCharacter) + return 1; + return 0; +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression-disable-options.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression-disable-options.cpp new file mode 100644 index 0000000000000..b454caf4c99c0 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression-disable-options.cpp @@ -0,0 +1,33 @@ +// RUN: %check_clang_tidy %s bugprone-sizeof-expression %t -- \ +// RUN: -config="{CheckOptions: { \ +// RUN: bugprone-sizeof-expression.WarnOnSizeOfConstant: false, \ +// RUN: bugprone-sizeof-expression.WarnOnSizeOfThis: false, \ +// RUN: bugprone-sizeof-expression.WarnOnSizeOfCompareToConstant: false, \ +// RUN: bugprone-sizeof-expression.WarnOnSizeOfInLoopTermination: false \ +// RUN: }}" + +#define LEN 8 + +class C { + int size() { return sizeof(this); } +}; + +int Test() { + int A = sizeof(LEN); + int B = sizeof(LEN + 1); + int C = sizeof(1); + + if (sizeof(A) < 0x100000) + return 0; + if (sizeof(A) <= 0) + return 0; + + int arr[10]; + for (int i = 0; sizeof(arr) < i; ++i) {} + while (sizeof(arr) < 10) {} + + int x = sizeof(A, 1); + // CHECK-MESSAGES: [[@LINE-1]]:19: warning: suspicious usage of 'sizeof(..., ...)' [bugprone-sizeof-expression] + + return A + B + C + x; +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/string-constructor-options.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/string-constructor-options.cpp new file mode 100644 index 0000000000000..3e18b0d09407e --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/string-constructor-options.cpp @@ -0,0 +1,64 @@ +// RUN: %check_clang_tidy %s bugprone-string-constructor %t -- \ +// RUN: -config="{CheckOptions: { \ +// RUN: bugprone-string-constructor.WarnOnLargeLength: true, \ +// RUN: bugprone-string-constructor.LargeLengthThreshold: 10, \ +// RUN: bugprone-string-constructor.StringNames: '::std::basic_string;::std::basic_string_view;::custom::String' \ +// RUN: }}" + +namespace std { +template <typename T> +class allocator {}; +template <typename T> +class char_traits {}; +template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C>> +struct basic_string { + basic_string(); + basic_string(const C *, unsigned int size, const A &a = A()); + basic_string(const C *, const A &allocator = A()); + basic_string(unsigned int size, C c, const A &a = A()); +}; +typedef basic_string<char> string; + +template <typename C, typename T = std::char_traits<C>> +struct basic_string_view { + basic_string_view(); + basic_string_view(const C *, unsigned int size); + basic_string_view(const C *); +}; +typedef basic_string_view<char> string_view; +} // namespace std + +namespace custom { +struct String { + String(const char *, unsigned int size); + String(const char *); +}; +} // namespace custom + +extern const char *kPtr; + +void TestLargeLengthThreshold() { + std::string s1(kPtr, 11); + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter [bugprone-string-constructor] + + std::string s2(kPtr, 9); + + std::string_view sv1(kPtr, 11); + // CHECK-MESSAGES: [[@LINE-1]]:20: warning: suspicious large length parameter [bugprone-string-constructor] + + std::string s3(kPtr, 0x1000000); + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter [bugprone-string-constructor] +} + +void TestWarnOnLargeLengthAndThreshold() { + std::string s1(kPtr, 0x1000000); + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter [bugprone-string-constructor] + + std::string s2(20, 'x'); + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter [bugprone-string-constructor] +} + +void TestStringNames() { + custom::String cs1(nullptr); + // CHECK-MESSAGES: [[@LINE-1]]:18: warning: constructing string from nullptr is undefined behaviour [bugprone-string-constructor] +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-missing-comma-options.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-missing-comma-options.cpp new file mode 100644 index 0000000000000..192efc24dba82 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-missing-comma-options.cpp @@ -0,0 +1,32 @@ +// RUN: %check_clang_tidy -check-suffixes=THRESHOLD %s bugprone-suspicious-missing-comma %t -- \ +// RUN: -config="{CheckOptions: { \ +// RUN: bugprone-suspicious-missing-comma.SizeThreshold: 3, \ +// RUN: bugprone-suspicious-missing-comma.RatioThreshold: '.5', \ +// RUN: bugprone-suspicious-missing-comma.MaxConcatenatedTokens: 3 \ +// RUN: }}" + +const char *SmallArray[] = { + "hello" "world", + "foo", + "bar", +}; +// CHECK-MESSAGES-THRESHOLD: :[[@LINE-4]]:5: warning: suspicious string literal, probably missing a comma [bugprone-suspicious-missing-comma] + +const char *ManyTokensArray[] = { + "a" "b" "c", + "d", + "e", +}; + +const char *TwoTokensArray[] = { + "a" "b", + "c", + "d", +}; +// CHECK-MESSAGES-THRESHOLD: :[[@LINE-4]]:5: warning: suspicious string literal, probably missing a comma [bugprone-suspicious-missing-comma] + +const char *HighRatioArray[] = { + "a" "b", + "c" "d", + "e", +}; diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-string-compare-custom-functions.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-string-compare-custom-functions.cpp new file mode 100644 index 0000000000000..4346e458c75c4 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-string-compare-custom-functions.cpp @@ -0,0 +1,26 @@ +// RUN: %check_clang_tidy %s bugprone-suspicious-string-compare %t -- \ +// RUN: -config="{CheckOptions: { \ +// RUN: bugprone-suspicious-string-compare.StringCompareLikeFunctions: 'my_strcmp;my_strncmp' \ +// RUN: }}" + +int my_strcmp(const char *, const char *); +int my_strncmp(const char *, const char *, unsigned long); + +void TestCustomCompareFunctions() { + if (my_strcmp("a", "b")) + return; + // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'my_strcmp' is called without explicitly comparing result [bugprone-suspicious-string-compare] + // CHECK-FIXES: if (my_strcmp("a", "b") != 0) + + if (my_strncmp("a", "b", 1)) + return; + // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'my_strncmp' is called without explicitly comparing result [bugprone-suspicious-string-compare] + // CHECK-FIXES: if (my_strncmp("a", "b", 1) != 0) + + if (my_strcmp("a", "b") == 1) + return; + // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'my_strcmp' is compared to a suspicious constant [bugprone-suspicious-string-compare] + + if (my_strcmp("a", "b") == 0) + return; +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-stringview-data-usage-options.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-stringview-data-usage-options.cpp new file mode 100644 index 0000000000000..64ec7432a9ddd --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-stringview-data-usage-options.cpp @@ -0,0 +1,42 @@ +// RUN: %check_clang_tidy -std=c++17-or-later %s bugprone-suspicious-stringview-data-usage %t -- \ +// RUN: -config="{CheckOptions: { \ +// RUN: bugprone-suspicious-stringview-data-usage.StringViewTypes: '::custom::StrView', \ +// RUN: bugprone-suspicious-stringview-data-usage.AllowedCallees: '::safe_func;SafeClass' \ +// RUN: }}" -- -isystem %clang_tidy_headers +#include <string> + +namespace custom { +struct StrView { + const char *data(); + unsigned size(); +}; +} // namespace custom + +void unsafe_func(const char *); +void safe_func(const char *); +struct SafeClass { + SafeClass(const char *); +}; +struct UnsafeClass { + UnsafeClass(const char *); +}; + +void TestStringViewTypes(custom::StrView sv) { + unsafe_func(sv.data()); + // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: result of a `data()` call may not be null terminated, provide size information to the callee to prevent potential issues [bugprone-suspicious-stringview-data-usage] +} + +void TestAllowedCallees(custom::StrView sv) { + safe_func(sv.data()); + SafeClass sc(sv.data()); + // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: result of a `data()` call may not be null terminated, provide size information to the callee to prevent potential issues [bugprone-suspicious-stringview-data-usage] +} + +void TestNotAllowed(custom::StrView sv) { + UnsafeClass uc(sv.data()); + // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: result of a `data()` call may not be null terminated, provide size information to the callee to prevent potential issues [bugprone-suspicious-stringview-data-usage] +} + +void TestStdStringViewNotMatched(std::string_view sv) { + unsafe_func(sv.data()); +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-return-value-checked-return-types.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-return-value-checked-return-types.cpp new file mode 100644 index 0000000000000..a4acd4880bbfd --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-return-value-checked-return-types.cpp @@ -0,0 +1,36 @@ +// RUN: %check_clang_tidy %s bugprone-unused-return-value %t -- \ +// RUN: -config="{CheckOptions: { \ +// RUN: bugprone-unused-return-value.CheckedReturnTypes: '::CustomError;::ns::Result', \ +// RUN: bugprone-unused-return-value.CheckedFunctions: '' \ +// RUN: }}" + +struct CustomError { + int code; +}; + +namespace ns { +struct Result { + bool ok; +}; +} // namespace ns + +struct NotChecked { + int value; +}; + +CustomError makeError(); +ns::Result doWork(); +NotChecked other(); + +void TestCheckedReturnTypes() { + makeError(); + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: the value returned by this function should not be disregarded; neglecting it may lead to errors [bugprone-unused-return-value] + + doWork(); + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: the value returned by this function should not be disregarded; neglecting it may lead to errors [bugprone-unused-return-value] + + other(); + + CustomError e = makeError(); + ns::Result r = doWork(); +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
