Skip to content

Commit 0c55ad1

Browse files
authored
[clang-tidy] fix false positive that floating point variable only used in increment expr in cert-flp30-c (#108706)
Fixes: #108049 cert-flp30-c only provides non-compliant example with normal loop. Essentially it wants to avoid that floating point variables are used as loop counters which are checked in condition expr and modified in increment expr. This patch wants to give more precise matcheres to identify this cases.
1 parent 61ff1cb commit 0c55ad1

File tree

3 files changed

+39
-10
lines changed

3 files changed

+39
-10
lines changed

clang-tools-extra/clang-tidy/cert/FloatLoopCounter.cpp

+19-3
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,38 @@
99
#include "FloatLoopCounter.h"
1010
#include "clang/AST/ASTContext.h"
1111
#include "clang/ASTMatchers/ASTMatchFinder.h"
12+
#include "clang/ASTMatchers/ASTMatchers.h"
1213

1314
using namespace clang::ast_matchers;
1415

1516
namespace clang::tidy::cert {
1617

1718
void FloatLoopCounter::registerMatchers(MatchFinder *Finder) {
1819
Finder->addMatcher(
19-
forStmt(hasIncrement(expr(hasType(realFloatingPointType())))).bind("for"),
20+
forStmt(hasIncrement(forEachDescendant(
21+
declRefExpr(hasType(realFloatingPointType()),
22+
to(varDecl().bind("var")))
23+
.bind("inc"))),
24+
hasCondition(forEachDescendant(
25+
declRefExpr(hasType(realFloatingPointType()),
26+
to(varDecl(equalsBoundNode("var"))))
27+
.bind("cond"))))
28+
.bind("for"),
2029
this);
2130
}
2231

2332
void FloatLoopCounter::check(const MatchFinder::MatchResult &Result) {
2433
const auto *FS = Result.Nodes.getNodeAs<ForStmt>("for");
2534

26-
diag(FS->getInc()->getExprLoc(), "loop induction expression should not have "
27-
"floating-point type");
35+
diag(FS->getInc()->getBeginLoc(), "loop induction expression should not have "
36+
"floating-point type")
37+
<< Result.Nodes.getNodeAs<DeclRefExpr>("inc")->getSourceRange()
38+
<< Result.Nodes.getNodeAs<DeclRefExpr>("cond")->getSourceRange();
39+
40+
if (!FS->getInc()->getType()->isRealFloatingType())
41+
if (const auto *V = Result.Nodes.getNodeAs<VarDecl>("var"))
42+
diag(V->getBeginLoc(), "floating-point type loop induction variable",
43+
DiagnosticIDs::Note);
2844
}
2945

3046
} // namespace clang::tidy::cert

clang-tools-extra/docs/ReleaseNotes.rst

+4
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ Changes in existing checks
111111
<clang-tidy/checks/bugprone/casting-through-void>` check to suggest replacing
112112
the offending code with ``reinterpret_cast``, to more clearly express intent.
113113

114+
- Improved :doc:`cert-flp30-c<clang-tidy/checks/cert/flp30-c>` check to
115+
fix false positive that floating point variable is only used in increment
116+
expression.
117+
114118
- Improved :doc:`cppcoreguidelines-prefer-member-initializer
115119
<clang-tidy/checks/cppcoreguidelines/prefer-member-initializer>` check to avoid
116120
false positive when member initialization depends on a structured binging
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,28 @@
11
// RUN: %check_clang_tidy %s cert-flp30-c %t
22

33
float g(void);
4+
int c(float);
5+
float f = 1.0f;
6+
7+
void match(void) {
48

5-
void func(void) {
69
for (float x = 0.1f; x <= 1.0f; x += 0.1f) {}
7-
// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: loop induction expression should not have floating-point type [cert-flp30-c]
10+
// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: loop induction expression should not have floating-point type [cert-flp30-c]
811

9-
float f = 1.0f;
1012
for (; f > 0; --f) {}
11-
// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: loop induction expression
13+
// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: loop induction expression should not have floating-point type [cert-flp30-c]
1214

13-
for (;;g()) {}
14-
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: loop induction expression
15+
for (float x = 0.0f; c(x); x = g()) {}
16+
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: loop induction expression should not have floating-point type [cert-flp30-c]
1517

16-
for (int i = 0; i < 10; i += 1.0f) {}
18+
for (int i=0; i < 10 && f < 2.0f; f++, i++) {}
19+
// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: loop induction expression should not have floating-point type [cert-flp30-c]
20+
// CHECK-MESSAGES: :5:1: note: floating-point type loop induction variable
21+
}
1722

23+
void not_match(void) {
24+
for (int i = 0; i < 10; i += 1.0f) {}
1825
for (int i = 0; i < 10; ++i) {}
26+
for (int i = 0; i < 10; ++i, f++) {}
27+
for (int i = 0; f < 10.f; ++i) {}
1928
}

0 commit comments

Comments
 (0)