Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
#include "ThrowKeywordMissingCheck.h"
#include "TooSmallLoopVariableCheck.h"
#include "UncheckedOptionalAccessCheck.h"
#include "UncheckedStringToNumberConversionCheck.h"
#include "UndefinedMemoryManipulationCheck.h"
#include "UndelegatedConstructorCheck.h"
#include "UnhandledExceptionAtNewCheck.h"
Expand Down Expand Up @@ -261,6 +262,8 @@ class BugproneModule : public ClangTidyModule {
"bugprone-too-small-loop-variable");
CheckFactories.registerCheck<UncheckedOptionalAccessCheck>(
"bugprone-unchecked-optional-access");
CheckFactories.registerCheck<UncheckedStringToNumberConversionCheck>(
"bugprone-unchecked-string-to-number-conversion");
CheckFactories.registerCheck<UndefinedMemoryManipulationCheck>(
"bugprone-undefined-memory-manipulation");
CheckFactories.registerCheck<UndelegatedConstructorCheck>(
Expand Down
1 change: 1 addition & 0 deletions clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ add_clang_library(clangTidyBugproneModule STATIC
ThrowKeywordMissingCheck.cpp
TooSmallLoopVariableCheck.cpp
UncheckedOptionalAccessCheck.cpp
UncheckedStringToNumberConversionCheck.cpp
UndefinedMemoryManipulationCheck.cpp
UndelegatedConstructorCheck.cpp
UnhandledExceptionAtNewCheck.cpp
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
//===-- StrToNumCheck.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 "StrToNumCheck.h"
#include "UncheckedStringToNumberConversionCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/FormatString.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
Expand All @@ -15,9 +15,10 @@

using namespace clang::ast_matchers;

namespace clang::tidy::cert {
namespace clang::tidy::bugprone {

void StrToNumCheck::registerMatchers(MatchFinder *Finder) {
void UncheckedStringToNumberConversionCheck::registerMatchers(
MatchFinder *Finder) {
// Match any function call to the C standard library string conversion
// functions that do no error checking.
Finder->addMatcher(
Expand Down Expand Up @@ -176,7 +177,8 @@ static StringRef classifyReplacement(ConversionKind K) {
llvm_unreachable("Unknown conversion kind");
}

void StrToNumCheck::check(const MatchFinder::MatchResult &Result) {
void UncheckedStringToNumberConversionCheck::check(
const MatchFinder::MatchResult &Result) {
const auto *Call = Result.Nodes.getNodeAs<CallExpr>("expr");
const FunctionDecl *FuncDecl = nullptr;
ConversionKind Conversion = ConversionKind::None;
Expand Down Expand Up @@ -228,4 +230,4 @@ void StrToNumCheck::check(const MatchFinder::MatchResult &Result) {
<< classifyReplacement(Conversion);
}

} // namespace clang::tidy::cert
} // namespace clang::tidy::bugprone
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//===----------------------------------------------------------------------===//
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is mostly copypaste from StrToNumCheck.h

//
// 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_BUGPRONE_UNCHECKEDSTRINGTONUMBERCONVERSIONCHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNCHECKEDSTRINGTONUMBERCONVERSIONCHECK_H

#include "../ClangTidyCheck.h"

namespace clang::tidy::bugprone {

/// Guards against use of string conversion functions that do not have
/// reasonable error handling for conversion errors.
///
/// For the user-facing documentation see:
/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/unchecked-string-to-number-conversion.html
class UncheckedStringToNumberConversionCheck : public ClangTidyCheck {
public:
UncheckedStringToNumberConversionCheck(StringRef Name,
ClangTidyContext *Context)
: ClangTidyCheck(Name, Context) {}
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
return LangOpts.CPlusPlus || LangOpts.C99;
}
};

} // namespace clang::tidy::bugprone

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNCHECKEDSTRINGTONUMBERCONVERSIONCHECK_H
6 changes: 4 additions & 2 deletions clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "../bugprone/SizeofExpressionCheck.h"
#include "../bugprone/SpuriouslyWakeUpFunctionsCheck.h"
#include "../bugprone/SuspiciousMemoryComparisonCheck.h"
#include "../bugprone/UncheckedStringToNumberConversionCheck.h"
#include "../bugprone/UnhandledSelfAssignmentCheck.h"
#include "../bugprone/UnsafeFunctionsCheck.h"
#include "../bugprone/UnusedReturnValueCheck.h"
Expand All @@ -39,7 +40,6 @@
#include "ProperlySeededRandomGeneratorCheck.h"
#include "SetLongJmpCheck.h"
#include "StaticObjectExceptionCheck.h"
#include "StrToNumCheck.h"
#include "ThrownExceptionTypeCheck.h"
#include "VariadicFunctionDefCheck.h"

Expand Down Expand Up @@ -297,7 +297,9 @@ class CERTModule : public ClangTidyModule {
// ERR
CheckFactories.registerCheck<bugprone::UnusedReturnValueCheck>(
"cert-err33-c");
CheckFactories.registerCheck<StrToNumCheck>("cert-err34-c");
CheckFactories
.registerCheck<bugprone::UncheckedStringToNumberConversionCheck>(
"cert-err34-c");
// EXP
CheckFactories.registerCheck<bugprone::SuspiciousMemoryComparisonCheck>(
"cert-exp42-c");
Expand Down
1 change: 0 additions & 1 deletion clang-tools-extra/clang-tidy/cert/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ add_clang_library(clangTidyCERTModule STATIC
ProperlySeededRandomGeneratorCheck.cpp
SetLongJmpCheck.cpp
StaticObjectExceptionCheck.cpp
StrToNumCheck.cpp
ThrownExceptionTypeCheck.cpp
VariadicFunctionDefCheck.cpp

Expand Down
31 changes: 0 additions & 31 deletions clang-tools-extra/clang-tidy/cert/StrToNumCheck.h

This file was deleted.

5 changes: 5 additions & 0 deletions clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ New checks
New check aliases
^^^^^^^^^^^^^^^^^

- Renamed :doc:`cert-err34-c <clang-tidy/checks/cert/err34-c>` to
:doc:`bugprone-unchecked-string-to-number-conversion
<clang-tidy/checks/bugprone/unchecked-string-to-number-conversion>`
keeping initial check as an alias to the new one.

Changes in existing checks
^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.. title:: clang-tidy - bugprone-unchecked-string-to-number-conversion
Copy link
Contributor Author

@vbvictor vbvictor Sep 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is copy-paste from previous err34-c.rst


bugprone-unchecked-string-to-number-conversion
==============================================

This check flags calls to string-to-number conversion functions that do not
verify the validity of the conversion, such as ``atoi()`` or ``scanf()``. It
does not flag calls to ``strtol()``, or other, related conversion functions that
do perform better error checking.

.. code-block:: c

#include <stdlib.h>

void func(const char *buff) {
int si;

if (buff) {
si = atoi(buff); /* 'atoi' used to convert a string to an integer, but function will
not report conversion errors; consider using 'strtol' instead. */
} else {
/* Handle error */
}
}

References
----------

This check corresponds to the CERT C Coding Standard rule
`ERR34-C. Detect errors when converting a string to a number
<https://www.securecoding.cert.org/confluence/display/c/ERR34-C.+Detect+errors+when+converting+a+string+to+a+number>`_.
28 changes: 5 additions & 23 deletions clang-tools-extra/docs/clang-tidy/checks/cert/err34-c.rst
Original file line number Diff line number Diff line change
@@ -1,28 +1,10 @@
.. title:: clang-tidy - cert-err34-c
.. meta::
:http-equiv=refresh: 5;URL=../bugprone/unchecked-string-to-number-conversion.html

cert-err34-c
============

This check flags calls to string-to-number conversion functions that do not
verify the validity of the conversion, such as ``atoi()`` or ``scanf()``. It
does not flag calls to ``strtol()``, or other, related conversion functions that
do perform better error checking.

.. code-block:: c

#include <stdlib.h>

void func(const char *buff) {
int si;

if (buff) {
si = atoi(buff); /* 'atoi' used to convert a string to an integer, but function will
not report conversion errors; consider using 'strtol' instead. */
} else {
/* Handle error */
}
}

This check corresponds to the CERT C Coding Standard rule
`ERR34-C. Detect errors when converting a string to a number
<https://www.securecoding.cert.org/confluence/display/c/ERR34-C.+Detect+errors+when+converting+a+string+to+a+number>`_.
The cert-err34-c check is an alias, please see
`bugprone-unchecked-string-to-number-conversion <../bugprone/unchecked-string-to-number-conversion.html>`_
for more information.
3 changes: 2 additions & 1 deletion clang-tools-extra/docs/clang-tidy/checks/list.rst
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ Clang-Tidy Checks
:doc:`bugprone-throw-keyword-missing <bugprone/throw-keyword-missing>`,
:doc:`bugprone-too-small-loop-variable <bugprone/too-small-loop-variable>`,
:doc:`bugprone-unchecked-optional-access <bugprone/unchecked-optional-access>`,
:doc:`bugprone-unchecked-string-to-number-conversion <bugprone/unchecked-string-to-number-conversion>`,
:doc:`bugprone-undefined-memory-manipulation <bugprone/undefined-memory-manipulation>`,
:doc:`bugprone-undelegated-constructor <bugprone/undelegated-constructor>`,
:doc:`bugprone-unhandled-exception-at-new <bugprone/unhandled-exception-at-new>`,
Expand All @@ -173,7 +174,6 @@ Clang-Tidy Checks
:doc:`cert-dcl58-cpp <cert/dcl58-cpp>`,
:doc:`cert-env33-c <cert/env33-c>`,
:doc:`cert-err33-c <cert/err33-c>`,
:doc:`cert-err34-c <cert/err34-c>`,
:doc:`cert-err52-cpp <cert/err52-cpp>`,
:doc:`cert-err58-cpp <cert/err58-cpp>`,
:doc:`cert-err60-cpp <cert/err60-cpp>`,
Expand Down Expand Up @@ -437,6 +437,7 @@ Check aliases
:doc:`cert-dcl54-cpp <cert/dcl54-cpp>`, :doc:`misc-new-delete-overloads <misc/new-delete-overloads>`,
:doc:`cert-dcl59-cpp <cert/dcl59-cpp>`, :doc:`google-build-namespaces <google/build-namespaces>`,
:doc:`cert-err09-cpp <cert/err09-cpp>`, :doc:`misc-throw-by-value-catch-by-reference <misc/throw-by-value-catch-by-reference>`,
:doc:`cert-err34-c <cert/err34-c>`, :doc:`bugprone-unchecked-string-to-number-conversion <bugprone/unchecked-string-to-number-conversion>`,
:doc:`cert-err61-cpp <cert/err61-cpp>`, :doc:`misc-throw-by-value-catch-by-reference <misc/throw-by-value-catch-by-reference>`,
:doc:`cert-exp42-c <cert/exp42-c>`, :doc:`bugprone-suspicious-memory-comparison <bugprone/suspicious-memory-comparison>`,
:doc:`cert-fio38-c <cert/fio38-c>`, :doc:`misc-non-copyable-objects <misc/non-copyable-objects>`,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %check_clang_tidy %s cert-err34-c %t -- -- -std=c11
// RUN: %check_clang_tidy %s bugprone-unchecked-string-to-number-conversion %t

typedef __SIZE_TYPE__ size_t;
typedef signed ptrdiff_t;
Expand All @@ -8,9 +8,9 @@ typedef void * FILE;

extern FILE *stdin;

extern int fscanf(FILE * restrict stream, const char * restrict format, ...);
extern int scanf(const char * restrict format, ...);
extern int sscanf(const char * restrict s, const char * restrict format, ...);
extern int fscanf(FILE *stream, const char *format, ...);
extern int scanf(const char *format, ...);
extern int sscanf(const char *s, const char *format, ...);

extern double atof(const char *nptr);
extern int atoi(const char *nptr);
Expand All @@ -28,23 +28,23 @@ void f1(const char *in) {
double d;
long double ld;

// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [bugprone-unchecked-string-to-number-conversion]
sscanf(in, "%d", &i);
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead [cert-err34-c]
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead
fscanf(stdin, "%lld", &ll);
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoul' instead [cert-err34-c]
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoul' instead
sscanf(in, "%u", &ui);
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoull' instead [cert-err34-c]
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoull' instead
fscanf(stdin, "%llu", &ull);
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoimax' instead [cert-err34-c]
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoimax' instead
scanf("%jd", &im);
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoumax' instead [cert-err34-c]
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoumax' instead
fscanf(stdin, "%ju", &uim);
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtof' instead [cert-err34-c]
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtof' instead
sscanf(in, "%f", &f); // to float
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtod' instead [cert-err34-c]
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtod' instead
fscanf(stdin, "%lg", &d);
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtold' instead [cert-err34-c]
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtold' instead
sscanf(in, "%Le", &ld);

// These are conversions with other modifiers
Expand All @@ -70,13 +70,13 @@ void f1(const char *in) {
}

void f2(const char *in) {
// CHECK-MESSAGES: :[[@LINE+1]]:11: warning: 'atoi' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
// CHECK-MESSAGES: :[[@LINE+1]]:11: warning: 'atoi' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead
int i = atoi(in); // to int
// CHECK-MESSAGES: :[[@LINE+1]]:12: warning: 'atol' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
// CHECK-MESSAGES: :[[@LINE+1]]:12: warning: 'atol' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead
long l = atol(in); // to long
// CHECK-MESSAGES: :[[@LINE+1]]:18: warning: 'atoll' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead [cert-err34-c]
// CHECK-MESSAGES: :[[@LINE+1]]:18: warning: 'atoll' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead
long long ll = atoll(in); // to long long
// CHECK-MESSAGES: :[[@LINE+1]]:14: warning: 'atof' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtod' instead [cert-err34-c]
// CHECK-MESSAGES: :[[@LINE+1]]:14: warning: 'atof' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtod' instead
double d = atof(in); // to double
}

Expand Down
Loading