[clang-tools-extra] [clang-tidy] Catch <cctype> function args in bugprone-signed-char-misuse (PR #211403)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 5 22:45:41 PDT 2026
================
@@ -125,11 +125,38 @@ void SignedCharMisuseCheck::registerMatchers(MatchFinder *Finder) {
.bind("arraySubscript");
Finder->addMatcher(STDArraySubscript, this);
+
+ // Catch signed char values passed to a <cctype>/<ctype.h> classification
+ // or conversion function; any value other than EOF or one representable
+ // as unsigned char is undefined behavior. Unlike the matchers above, this
+ // matches the uncast argument directly instead of going through
+ // charCastExpression(), because hasArgument() strips implicit casts off
+ // the argument before matching it.
+ const auto IntTypedef = qualType(hasDeclaration(typedefDecl(
+ hasAnyName(utils::options::parseStringList(CharTypedefsToIgnoreList)))));
+ const auto CctypeFunctionArgument =
+ callExpr(
+ callee(functionDecl(
+ hasAnyName("isalnum", "std::isalnum", "isalpha", "std::isalpha",
+ "isblank", "std::isblank", "iscntrl", "std::iscntrl",
----------------
cavdarahmet wrote:
Done — the names now live in a `static constexpr StringRef[]` and are fully qualified (`::isalpha` / `::std::isalpha`), which restricts matching to global and `std` declarations. I went with qualified names rather than `isInStdNamespace()` since the global half would still need a separate condition, while the qualified list covers both with one mechanism — happy to switch if you prefer. `hasName()` treats inline namespaces transparently, so libc++'s `std::__1` declarations still match (verified). Added regression tests for `custom::isalpha` and `Classifier::toupper`.
https://github.com/llvm/llvm-project/pull/211403
More information about the cfe-commits
mailing list