Author: malcolm.parsons Date: Tue Nov 27 08:23:39 2018 New Revision: 347671
URL: http://llvm.org/viewvc/llvm-project?rev=347671&view=rev Log: [clang-tidy] Ignore bool -> single bit bitfield conversion in readability-implicit-bool-conversion Summary: There is no ambiguity / information loss in this conversion Reviewers: alexfh, aaron.ballman, hokein Reviewed By: alexfh Subscribers: xazax.hun, cfe-commits Differential Revision: https://reviews.llvm.org/D54941 Modified: clang-tools-extra/trunk/clang-tidy/readability/ImplicitBoolConversionCheck.cpp clang-tools-extra/trunk/docs/clang-tidy/checks/readability-implicit-bool-conversion.rst clang-tools-extra/trunk/test/clang-tidy/readability-implicit-bool-conversion.cpp Modified: clang-tools-extra/trunk/clang-tidy/readability/ImplicitBoolConversionCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/ImplicitBoolConversionCheck.cpp?rev=347671&r1=347670&r2=347671&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/readability/ImplicitBoolConversionCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/readability/ImplicitBoolConversionCheck.cpp Tue Nov 27 08:23:39 2018 @@ -306,6 +306,11 @@ void ImplicitBoolConversionCheck::regist auto boolOpAssignment = binaryOperator(anyOf(hasOperatorName("|="), hasOperatorName("&=")), hasLHS(expr(hasType(booleanType())))); + auto bitfieldAssignment = binaryOperator( + hasLHS(memberExpr(hasDeclaration(fieldDecl(hasBitWidth(1)))))); + auto bitfieldConstruct = cxxConstructorDecl(hasDescendant(cxxCtorInitializer( + withInitializer(equalsBoundNode("implicitCastFromBool")), + forField(hasBitWidth(1))))); Finder->addMatcher( implicitCastExpr( implicitCastFromBool, @@ -313,14 +318,15 @@ void ImplicitBoolConversionCheck::regist // in such context: // bool_expr_a == bool_expr_b // bool_expr_a != bool_expr_b - unless(hasParent(binaryOperator( - anyOf(boolComparison, boolXor, boolOpAssignment)))), + unless(hasParent(binaryOperator(anyOf( + boolComparison, boolXor, boolOpAssignment, bitfieldAssignment)))), + implicitCastExpr().bind("implicitCastFromBool"), + unless(hasParent(bitfieldConstruct)), // Check also for nested casts, for example: bool -> int -> float. anyOf(hasParent(implicitCastExpr().bind("furtherImplicitCast")), anything()), unless(isInTemplateInstantiation()), - unless(hasAncestor(functionTemplateDecl()))) - .bind("implicitCastFromBool"), + unless(hasAncestor(functionTemplateDecl()))), this); } Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/readability-implicit-bool-conversion.rst URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/readability-implicit-bool-conversion.rst?rev=347671&r1=347670&r2=347671&view=diff ============================================================================== --- clang-tools-extra/trunk/docs/clang-tidy/checks/readability-implicit-bool-conversion.rst (original) +++ clang-tools-extra/trunk/docs/clang-tidy/checks/readability-implicit-bool-conversion.rst Tue Nov 27 08:23:39 2018 @@ -74,7 +74,8 @@ In general, the following conversion typ - pointer/pointer to member/``nullptr``/``NULL`` to boolean, -- boolean expression/literal to integer, +- boolean expression/literal to integer (conversion from boolean to a single + bit bitfield is explicitly allowed), - boolean expression/literal to floating. Modified: clang-tools-extra/trunk/test/clang-tidy/readability-implicit-bool-conversion.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/readability-implicit-bool-conversion.cpp?rev=347671&r1=347670&r2=347671&view=diff ============================================================================== --- clang-tools-extra/trunk/test/clang-tidy/readability-implicit-bool-conversion.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/readability-implicit-bool-conversion.cpp Tue Nov 27 08:23:39 2018 @@ -444,14 +444,27 @@ struct S { int a; int b : 1; int c : 2; + + S(bool a, bool b, bool c) : a(a), b(b), c(c) {} + // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion bool -> 'int' + // CHECK-MESSAGES: :[[@LINE-2]]:45: warning: implicit conversion bool -> 'int' + // CHECK-FIXES: S(bool a, bool b, bool c) : a(static_cast<int>(a)), b(b), c(static_cast<int>(c)) {} }; -bool f(const S& s) { +bool f(S& s) { functionTaking<bool>(s.a); // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool // CHECK-FIXES: functionTaking<bool>(s.a != 0); functionTaking<bool>(s.b); // CHECK-FIXES: functionTaking<bool>(s.b); + s.a = true; + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicit conversion bool -> 'int' + // CHECK-FIXES: s.a = 1; + s.b = true; + // CHECK-FIXES: s.b = true; + s.c = true; + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicit conversion bool -> 'int' + // CHECK-FIXES: s.c = 1; functionTaking<bool>(s.c); // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool // CHECK-FIXES: functionTaking<bool>(s.c != 0); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits