Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 19c3713

Browse filesBrowse files
committed
[clang-tidy] false positive narrowing conversion
Let's consider the following code from the issue #139467: void test(int cond, char c) { char ret = cond > 0 ? ':' : c; } Initializer of 'ret' looks the following: -ImplicitCastExpr 'char' <IntegralCast> `-ConditionalOperator 'int' |-BinaryOperator 'int' '>' | |-ImplicitCastExpr 'int' <LValueToRValue> | | `-DeclRefExpr 'int' lvalue ParmVar 'cond' 'int' | `-IntegerLiteral 'int' 0 |-CharacterLiteral 'int' 58 `-ImplicitCastExpr 'int' <IntegralCast> `-ImplicitCastExpr 'char' <LValueToRValue> `-DeclRefExpr 'char' lvalue ParmVar 'c' 'char' So it could be seen that 'RHS' of the conditional operator is DeclRefExpr 'c' which is casted to 'int' and then the whole conditional expression is casted to 'char'. But this last conversion is not narrowing, because 'RHS' was 'char' _initially_. We should just remove the cast from 'char' to 'int' before the narrowing conversion check.
1 parent 3e393d9 commit 19c3713
Copy full SHA for 19c3713

File tree

3 files changed

+20
-4
lines changed
Filter options

3 files changed

+20
-4
lines changed

‎clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp

Copy file name to clipboardExpand all lines: clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp
+12-4
Original file line numberDiff line numberDiff line change
@@ -554,15 +554,23 @@ bool NarrowingConversionsCheck::handleConditionalOperator(
554554
// We have an expression like so: `output = cond ? lhs : rhs`
555555
// From the point of view of narrowing conversion we treat it as two
556556
// expressions `output = lhs` and `output = rhs`.
557-
handleBinaryOperator(Context, CO->getLHS()->getExprLoc(), Lhs,
558-
*CO->getLHS());
559-
handleBinaryOperator(Context, CO->getRHS()->getExprLoc(), Lhs,
560-
*CO->getRHS());
557+
handleConditionalOperatorArgument(Context, Lhs, CO->getLHS());
558+
handleConditionalOperatorArgument(Context, Lhs, CO->getRHS());
561559
return true;
562560
}
563561
return false;
564562
}
565563

564+
void NarrowingConversionsCheck::handleConditionalOperatorArgument(
565+
const ASTContext &Context, const Expr &Lhs, const Expr *Arg) {
566+
if (const auto *ICE = llvm::dyn_cast<ImplicitCastExpr>(Arg)) {
567+
if (!Arg->getIntegerConstantExpr(Context)) {
568+
Arg = ICE->getSubExpr();
569+
}
570+
}
571+
handleBinaryOperator(Context, Arg->getExprLoc(), Lhs, *Arg);
572+
}
573+
566574
void NarrowingConversionsCheck::handleImplicitCast(
567575
const ASTContext &Context, const ImplicitCastExpr &Cast) {
568576
if (Cast.getExprLoc().isMacroID())

‎clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.h

Copy file name to clipboardExpand all lines: clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.h
+2
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ class NarrowingConversionsCheck : public ClangTidyCheck {
8585
bool handleConditionalOperator(const ASTContext &Context, const Expr &Lhs,
8686
const Expr &Rhs);
8787

88+
void handleConditionalOperatorArgument(const ASTContext &Context, const Expr &Lhs,
89+
const Expr *Arg);
8890
void handleImplicitCast(const ASTContext &Context,
8991
const ImplicitCastExpr &Cast);
9092

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// RUN: %check_clang_tidy %s bugprone-narrowing-conversions %t -- --
2+
3+
char test(int cond, char c) {
4+
char ret = cond > 0 ? ':' : c;
5+
return ret;
6+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.