Skip to content

Commit b0b491d

Browse files
authored
[clang-tidy] Fix handling of functional cast in google-readability-casting (#71650)
Fix issue with constructor call being interpreted as functional cast and considered for a replacement with static cast or being removed as redundant. Closes #57959
1 parent 5b7bb56 commit b0b491d

File tree

4 files changed

+19
-15
lines changed

4 files changed

+19
-15
lines changed

clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,16 @@ void AvoidCStyleCastsCheck::registerMatchers(
2323
// Filter out (EnumType)IntegerLiteral construct, which is generated
2424
// for non-type template arguments of enum types.
2525
// FIXME: Remove this once this is fixed in the AST.
26-
unless(hasParent(substNonTypeTemplateParmExpr())),
27-
// Avoid matches in template instantiations.
28-
unless(isInTemplateInstantiation()))
26+
unless(hasParent(substNonTypeTemplateParmExpr())))
2927
.bind("cast"),
3028
this);
29+
3130
Finder->addMatcher(
32-
cxxFunctionalCastExpr(unless(hasDescendant(cxxConstructExpr())),
33-
unless(hasDescendant(initListExpr())))
31+
cxxFunctionalCastExpr(
32+
hasDestinationType(hasCanonicalType(anyOf(
33+
builtinType(), references(qualType()), pointsTo(qualType())))),
34+
unless(
35+
hasSourceExpression(anyOf(cxxConstructExpr(), initListExpr()))))
3436
.bind("cast"),
3537
this);
3638
}

clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ class AvoidCStyleCastsCheck : public ClangTidyCheck {
3131
: ClangTidyCheck(Name, Context) {}
3232
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
3333
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
34+
std::optional<TraversalKind> getCheckTraversalKind() const override {
35+
return TK_IgnoreUnlessSpelledInSource;
36+
}
3437
};
3538

3639
} // namespace clang::tidy::google::readability

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,10 @@ Changes in existing checks
370370
to ignore unused parameters when they are marked as unused and parameters of
371371
deleted functions and constructors.
372372

373+
- Improved :doc:`google-readability-casting
374+
<clang-tidy/checks/google/readability-casting>` check to ignore constructor
375+
calls disguised as functional casts.
376+
373377
- Improved :doc:`llvm-namespace-comment
374378
<clang-tidy/checks/llvm/namespace-comment>` check to provide fixes for
375379
``inline`` namespaces in the same format as :program:`clang-format`.

clang-tools-extra/test/clang-tidy/checkers/google/readability-casting.cpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -322,17 +322,10 @@ void conversions() {
322322
}
323323

324324
template <class T>
325-
T functional_cast_template_used_by_class(float i) {
325+
T functional_cast_template(float i) {
326326
return T(i);
327327
}
328328

329-
template <class T>
330-
T functional_cast_template_used_by_int(float i) {
331-
return T(i);
332-
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: C-style casts are discouraged; use static_cast
333-
// CHECK-FIXES: return static_cast<T>(i);
334-
}
335-
336329
struct S2 {
337330
S2(float);
338331
};
@@ -356,8 +349,8 @@ void functional_casts() {
356349
auto s = S(str);
357350

358351
// Functional casts in template functions
359-
functional_cast_template_used_by_class<S2>(x);
360-
functional_cast_template_used_by_int<int>(x);
352+
functional_cast_template<S2>(x);
353+
functional_cast_template<int>(x);
361354

362355
// New expressions are not functional casts
363356
auto w = new int(x);
@@ -366,4 +359,6 @@ void functional_casts() {
366359
S2 t = T(x); // OK, constructor call
367360
S2 u = U(x); // NOK, it's a reinterpret_cast in disguise
368361
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: C-style casts are discouraged; use static_cast/const_cast/reinterpret_cast
362+
363+
throw S2(5.0f);
369364
}

0 commit comments

Comments
 (0)