// RUN: %check_clang_tidy %s bugprone-redundant-branch-condition %t \ // RUN: -- -- -fblocks extern unsigned peopleInTheBuilding; extern unsigned fireFighters; bool isBurning(); bool isReallyBurning(); bool isCollapsing(); bool tryToExtinguish(bool&); bool tryToExtinguishByVal(bool); void tryPutFireOut(); bool callTheFD(); void scream(); bool someOtherCondition(); //===--- Basic Positives --------------------------------------------------===// void positive_direct() { bool onFire = isBurning(); if (onFire) { if (onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } // CHECK-FIXES: {{^\ *$}} } } void positive_indirect() { bool onFire = isBurning(); if (onFire) { if (someOtherCondition()) { if (onFire) // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } } } void positive_direct_inner_and_lhs() { bool onFire = isBurning(); if (onFire) { if (onFire && peopleInTheBuilding > 0) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: if ( peopleInTheBuilding > 0) { scream(); } } } void positive_indirect_inner_and_lhs() { bool onFire = isBurning(); if (onFire) { if (someOtherCondition()) { if (onFire && peopleInTheBuilding > 0) { // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: if ( peopleInTheBuilding > 0) { scream(); } } } } void positive_direct_inner_and_rhs() { bool onFire = isBurning(); if (onFire) { if (peopleInTheBuilding > 0 && onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: if (peopleInTheBuilding > 0 ) { scream(); } } } void positive_indirect_inner_and_rhs() { bool onFire = isBurning(); if (onFire) { if (someOtherCondition()) { if (peopleInTheBuilding > 0 && onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: if (peopleInTheBuilding > 0 ) { scream(); } } } } void positive_direct_inner_or_lhs() { bool onFire = isBurning(); if (onFire) { if (onFire || isCollapsing()) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } // CHECK-FIXES: {{^\ *$}} } } void positive_indirect_inner_or_lhs() { bool onFire = isBurning(); if (onFire) { if (someOtherCondition()) { if (onFire || isCollapsing()) { // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } // CHECK-FIXES: {{^\ *$}} } } } void positive_direct_inner_or_rhs() { bool onFire = isBurning(); if (onFire) { if (isCollapsing() || onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } // CHECK-FIXES: {{^\ *$}} } } void positive_indirect_inner_or_rhs() { bool onFire = isBurning(); if (onFire) { if (someOtherCondition()) { if (isCollapsing() || onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } // CHECK-FIXES: {{^\ *$}} } } } void positive_direct_outer_and_lhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { if (onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } // CHECK-FIXES: {{^\ *$}} } } void positive_indirect_outer_and_lhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { if (someOtherCondition()) { if (onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } // CHECK-FIXES: {{^\ *$}} } } } void positive_direct_outer_and_lhs_inner_and_lhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { if (onFire && peopleInTheBuilding > 0) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: if ( peopleInTheBuilding > 0) { scream(); } } } void positive_indirect_outer_and_lhs_inner_and_lhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { if (someOtherCondition()) { if (onFire && peopleInTheBuilding > 0) { // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: if ( peopleInTheBuilding > 0) { scream(); } } } } void positive_direct_outer_and_lhs_inner_and_rhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { if (peopleInTheBuilding > 0 && onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: if (peopleInTheBuilding > 0 ) { scream(); } } } void positive_indirect_outer_and_lhs_inner_and_rhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { if (someOtherCondition()) { if (peopleInTheBuilding > 0 && onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: if (peopleInTheBuilding > 0 ) { scream(); } } } } void positive_direct_outer_and_lhs_inner_or_lhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { if (onFire || isCollapsing()) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } // CHECK-FIXES: {{^\ *$}} } } void positive_indirect_outer_and_lhs_inner_or_lhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { if (someOtherCondition()) { if (onFire || isCollapsing()) { // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } // CHECK-FIXES: {{^\ *$}} } } } void positive_direct_outer_and_lhs_inner_or_rhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { if (isCollapsing() || onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } // CHECK-FIXES: {{^\ *$}} } } void positive_indirect_outer_and_lhs_inner_or_rhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { if (someOtherCondition()) { if (isCollapsing() || onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } // CHECK-FIXES: {{^\ *$}} } } } void positive_direct_outer_and_rhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { if (onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } // CHECK-FIXES: {{^\ *$}} } } void positive_indirect_outer_and_rhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { if (someOtherCondition()) { if (onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } // CHECK-FIXES: {{^\ *$}} } } } void positive_direct_outer_and_rhs_inner_and_lhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { if (onFire && peopleInTheBuilding > 0) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: if ( peopleInTheBuilding > 0) { scream(); } } } void positive_indirect_outer_and_rhs_inner_and_lhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { if (someOtherCondition()) { if (onFire && peopleInTheBuilding > 0) { // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: if ( peopleInTheBuilding > 0) { scream(); } } } } void positive_direct_inner_outer_and_rhs_and_rhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { if (peopleInTheBuilding > 0 && onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: if (peopleInTheBuilding > 0 ) { scream(); } } } void positive_indirect_outer_and_rhs_inner_and_rhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { if (someOtherCondition()) { if (peopleInTheBuilding > 0 && onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: if (peopleInTheBuilding > 0 ) { scream(); } } } } void positive_direct_outer_and_rhs_inner_or_lhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { if (onFire || isCollapsing()) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } // CHECK-FIXES: {{^\ *$}} } } void positive_indirect_outer_and_rhs_inner_or_lhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { if (someOtherCondition()) { if (onFire || isCollapsing()) { // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } // CHECK-FIXES: {{^\ *$}} } } } void positive_direct_outer_and_rhs_inner_or_rhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { if (isCollapsing() || onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } // CHECK-FIXES: {{^\ *$}} } } void positive_indirect_outer_and_rhs_inner_or_rhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { if (someOtherCondition()) { if (isCollapsing() || onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } // CHECK-FIXES: {{^\ *$}} } } } //===--- Basic Negatives --------------------------------------------------===// void negative_direct() { bool onFire = isBurning(); if (onFire) { tryToExtinguish(onFire); if (onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } void negative_indirect() { bool onFire = isBurning(); if (onFire) { tryToExtinguish(onFire); if (someOtherCondition()) { if (onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_indirect2() { bool onFire = isBurning(); if (onFire) { if (someOtherCondition()) { tryToExtinguish(onFire); if (onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_direct_inner_and_lhs() { bool onFire = isBurning(); if (onFire) { tryToExtinguish(onFire); if (onFire && peopleInTheBuilding > 0) { // NO-MESSAGE: fire may have been extinguished scream(); } } } void negative_indirect_inner_and_lhs() { bool onFire = isBurning(); if (onFire) { tryToExtinguish(onFire); if (someOtherCondition()) { if (onFire && peopleInTheBuilding > 0) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_indirect2_inner_and_lhs() { bool onFire = isBurning(); if (onFire) { if (someOtherCondition()) { tryToExtinguish(onFire); if (onFire && peopleInTheBuilding > 0) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_direct_inner_and_rhs() { bool onFire = isBurning(); if (onFire) { tryToExtinguish(onFire); if (peopleInTheBuilding > 0 && onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } void negative_indirect_inner_and_rhs() { bool onFire = isBurning(); if (onFire) { tryToExtinguish(onFire); if (someOtherCondition()) { if (peopleInTheBuilding > 0 && onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_indirect2_inner_and_rhs() { bool onFire = isBurning(); if (onFire) { if (someOtherCondition()) { tryToExtinguish(onFire); if (peopleInTheBuilding > 0 && onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_direct_inner_or_lhs() { bool onFire = isBurning(); if (onFire) { tryToExtinguish(onFire); if (onFire || isCollapsing()) { // NO-MESSAGE: fire may have been extinguished scream(); } } } void negative_indirect_inner_or_lhs() { bool onFire = isBurning(); if (onFire) { tryToExtinguish(onFire); if (someOtherCondition()) { if (onFire || isCollapsing()) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_indirect2_inner_or_lhs() { bool onFire = isBurning(); if (onFire) { if (someOtherCondition()) { tryToExtinguish(onFire); if (onFire || isCollapsing()) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_direct_inner_or_rhs() { bool onFire = isBurning(); if (onFire) { tryToExtinguish(onFire); if (isCollapsing() || onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } void negative_indirect_inner_or_rhs() { bool onFire = isBurning(); if (onFire) { tryToExtinguish(onFire); if (someOtherCondition()) { if (isCollapsing() || onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_indirect2_inner_or_rhs() { bool onFire = isBurning(); if (onFire) { if (someOtherCondition()) { tryToExtinguish(onFire); if (isCollapsing() || onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_direct_outer_and_lhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { tryToExtinguish(onFire); if (onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } void negative_indirect_outer_and_lhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { tryToExtinguish(onFire); if (someOtherCondition()) { if (onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_indirect2_outer_and_lhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { if (someOtherCondition()) { tryToExtinguish(onFire); if (onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_direct_outer_and_lhs_inner_and_lhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { tryToExtinguish(onFire); if (onFire && peopleInTheBuilding > 0) { // NO-MESSAGE: fire may have been extinguished scream(); } } } void negative_indirect_outer_and_lhs_inner_and_lhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { tryToExtinguish(onFire); if (someOtherCondition()) { if (onFire && peopleInTheBuilding > 0) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_indirect2_outer_and_lhs_inner_and_lhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { if (someOtherCondition()) { tryToExtinguish(onFire); if (onFire && peopleInTheBuilding > 0) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_direct_outer_and_lhs_inner_and_rhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { tryToExtinguish(onFire); if (peopleInTheBuilding > 0 && onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } void negative_indirect_outer_and_lhs_inner_and_rhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { tryToExtinguish(onFire); if (someOtherCondition()) { if (peopleInTheBuilding > 0 && onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_indirect2_outer_and_lhs_inner_and_rhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { if (someOtherCondition()) { tryToExtinguish(onFire); if (peopleInTheBuilding > 0 && onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_direct_outer_and_lhs_inner_or_lhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { tryToExtinguish(onFire); if (onFire || isCollapsing()) { // NO-MESSAGE: fire may have been extinguished scream(); } } } void negative_indirect_outer_and_lhs_inner_or_lhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { tryToExtinguish(onFire); if (someOtherCondition()) { if (onFire || isCollapsing()) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_indirect2_outer_and_lhs_inner_or_lhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { if (someOtherCondition()) { tryToExtinguish(onFire); if (onFire || isCollapsing()) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_direct_outer_and_lhs_inner_or_rhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { tryToExtinguish(onFire); if (isCollapsing() || onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } void negative_indirect_outer_and_lhs_inner_or_rhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { tryToExtinguish(onFire); if (someOtherCondition()) { if (isCollapsing() || onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_indirect2_outer_and_lhs_inner_or_rhs() { bool onFire = isBurning(); if (onFire && fireFighters < 10) { if (someOtherCondition()) { tryToExtinguish(onFire); if (isCollapsing() || onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_direct_outer_and_rhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { tryToExtinguish(onFire); if (onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } void negative_indirect_outer_and_rhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { tryToExtinguish(onFire); if (someOtherCondition()) { if (onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_indirect2_outer_and_rhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { if (someOtherCondition()) { tryToExtinguish(onFire); if (onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_direct_outer_and_rhs_inner_and_lhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { tryToExtinguish(onFire); if (onFire && peopleInTheBuilding > 0) { // NO-MESSAGE: fire may have been extinguished scream(); } } } void negative_indirect_outer_and_rhs_inner_and_lhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { tryToExtinguish(onFire); if (someOtherCondition()) { if (onFire && peopleInTheBuilding > 0) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_indirect2_outer_and_rhs_inner_and_lhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { if (someOtherCondition()) { tryToExtinguish(onFire); if (onFire && peopleInTheBuilding > 0) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_direct_inner_outer_and_rhs_and_rhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { tryToExtinguish(onFire); if (peopleInTheBuilding > 0 && onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } void negative_indirect_outer_and_rhs_inner_and_rhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { tryToExtinguish(onFire); if (someOtherCondition()) { if (peopleInTheBuilding > 0 && onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_indirect2_outer_and_rhs_inner_and_rhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { if (someOtherCondition()) { tryToExtinguish(onFire); if (peopleInTheBuilding > 0 && onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_direct_outer_and_rhs_inner_or_lhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { tryToExtinguish(onFire); if (onFire || isCollapsing()) { // NO-MESSAGE: fire may have been extinguished scream(); } } } void negative_indirect_outer_and_rhs_inner_or_lhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { tryToExtinguish(onFire); if (someOtherCondition()) { if (onFire || isCollapsing()) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_indirect2_outer_and_rhs_inner_or_lhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { if (someOtherCondition()) { tryToExtinguish(onFire); if (onFire || isCollapsing()) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_direct_outer_and_rhs_inner_or_rhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { tryToExtinguish(onFire); if (isCollapsing() || onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } void negative_indirect_outer_and_rhs_inner_or_rhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { tryToExtinguish(onFire); if (someOtherCondition()) { if (isCollapsing() || onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_indirect2_outer_and_rhs_inner_or_rhs() { bool onFire = isBurning(); if (fireFighters < 10 && onFire) { if (someOtherCondition()) { tryToExtinguish(onFire); if (isCollapsing() || onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } } void negative_by_ref(bool onFire) { if (tryToExtinguish(onFire) && onFire) { if (tryToExtinguish(onFire) && onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } void negative_by_val(bool onFire) { if (tryToExtinguishByVal(onFire) && onFire) { if (tryToExtinguish(onFire) && onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } if (tryToExtinguish(onFire) && onFire) { if (tryToExtinguishByVal(onFire) && onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] scream(); } } } void negative_reassigned() { bool onFire = isBurning(); if (onFire) { onFire = isReallyBurning(); if (onFire) { // NO-MESSAGE: it was a false alarm then scream(); } } } //===--- Special Positives ------------------------------------------------===// // Condition variable mutated in or after the inner loop void positive_direct_mutated_after_inner() { bool onFire = isBurning(); if (onFire) { if (onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } // CHECK-FIXES: {{^\ *$}} tryToExtinguish(onFire); } } void positive_indirect_mutated_after_inner() { bool onFire = isBurning(); if (onFire) { if (someOtherCondition()) { if (onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } // CHECK-FIXES: {{^\ *$}} } tryToExtinguish(onFire); } } void positive_indirect2_mutated_after_inner() { bool onFire = isBurning(); if (onFire) { if (someOtherCondition()) { if (onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} scream(); } // CHECK-FIXES: {{^\ *$}} tryToExtinguish(onFire); } } } void positive_mutated_in_inner() { bool onFire = isBurning(); if (onFire) { if (onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: {{^\ *$}} tryToExtinguish(onFire); scream(); } // CHECK-FIXES: {{^\ *$}} } } void positive_or_lhs_with_side_effect() { bool onFire = isBurning(); if (onFire) { if (callTheFD() || onFire) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: callTheFD() ; scream(); } // CHECK-FIXES: {{^\ *$}} } } void positive_or_rhs_with_side_effect() { bool onFire = isBurning(); if (onFire) { if (onFire || callTheFD()) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHECK-FIXES: callTheFD(); scream(); } // CHECK-FIXES: {{^\ *$}} } } // GNU Expression Statements void doSomething(); void positive_gnu_expression_statement() { bool onFire = isBurning(); if (({ doSomething(); onFire; })) { if (({ doSomething(); onFire; })) { // FIXME: Handle GNU epxression statements // CHECK-MESSAGES-NOT: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHCK-FIXES-NOT: doSomething(); scream(); } } } // Comma after Condition void positive_comma_after_condition() { bool onFire = isBurning(); if (doSomething(), onFire) { if (doSomething(), onFire) { // FIXME: Handle comma operator // CHECK-MESSAGES-NOT: :[[@LINE-1]]:5: warning: redundant condition 'onFire' [bugprone-redundant-branch-condition] // CHCK-FIXES-NOT: doSomething(); scream(); } } } // ExprWithCleanups doesn't crash int positive_expr_with_cleanups() { class RetT { public: RetT(const int code); bool Ok() const; static RetT Test(bool isSet); private: int code_; }; bool isSet = false; if (RetT::Test(isSet).Ok() && isSet) { if (RetT::Test(isSet).Ok() && isSet) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'isSet' [bugprone-redundant-branch-condition] // CHECK-FIXES: if (RetT::Test(isSet).Ok() ) { } } if (isSet) { if ((RetT::Test(isSet).Ok() && isSet)) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'isSet' [bugprone-redundant-branch-condition] // CHECK-FIXES: if ((RetT::Test(isSet).Ok() )) { } } return 0; } //===--- Special Negatives ------------------------------------------------===// // Aliasing void negative_mutated_by_ptr() { bool onFire = isBurning(); bool *firePtr = &onFire; if (onFire) { tryToExtinguish(*firePtr); if (onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } void negative_mutated_by_ref() { bool onFire = isBurning(); bool &fireRef = onFire; if (onFire) { tryToExtinguish(fireRef); if (onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } // Volatile void negatvie_volatile() { bool volatile onFire = isBurning(); if (onFire) { if (onFire) { // NO-MESSAGE: maybe some other thread extinguished the fire scream(); } } } void negative_else_branch(bool isHot) { bool onFire = isBurning(); if (onFire) { tryPutFireOut(); } else { if (isHot && onFire) { // NO-MESSAGE: new check is in the `else` branch // FIXME: handle `else` branches and negated conditions scream(); } } } // Lambda / block captures. template void accept_callback(T t) { // Potentially call the callback. // Possibly on a background thread or something. } void accept_block(void (^)(void)) { // Potentially call the callback. // Possibly on a background thread or something. } void wait(void) { // Wait for the previously passed callback to be called. } void capture_and_mutate_by_lambda() { bool x = true; accept_callback([&]() { x = false; }); if (x) { wait(); if (x) { } } } void lambda_capture_by_value() { bool x = true; accept_callback([x]() { if (x) {} }); if (x) { wait(); if (x) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'x' [bugprone-redundant-branch-condition] } } } void capture_by_lambda_but_not_mutate() { bool x = true; accept_callback([&]() { if (x) {} }); if (x) { wait(); // FIXME: Should warn. if (x) { } } } void capture_and_mutate_by_block() { __block bool x = true; accept_block(^{ x = false; }); if (x) { wait(); if (x) { } } } void block_capture_by_value() { bool x = true; accept_block(^{ if (x) {} }); if (x) { wait(); if (x) { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'x' [bugprone-redundant-branch-condition] } } } void capture_by_block_but_not_mutate() { __block bool x = true; accept_callback(^{ if (x) {} }); if (x) { wait(); // FIXME: Should warn. if (x) { } } } void mutate_at_any_time(bool *x); void capture_with_branches_inside_lambda_bad() { bool x = true; accept_callback([=]() { if (x) { wait(); if (x) { // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant condition 'x' [bugprone-redundant-branch-condition] } } }); mutate_at_any_time(&x); } void capture_with_branches_inside_lambda_good() { bool x = true; accept_callback([&]() { if (x) { wait(); if (x) { } } }); mutate_at_any_time(&x); } void capture_with_branches_inside_block_bad() { bool x = true; accept_callback(^{ if (x) { wait(); if (x) { // FIXME: Should warn. It currently reacts to &x outside the block // which ideally shouldn't have any effect. } } }); mutate_at_any_time(&x); } void capture_with_branches_inside_block_bad_simpler() { bool x = true; accept_callback(^{ if (x) { wait(); if (x) { // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant condition 'x' [bugprone-redundant-branch-condition] } } }); } void capture_with_branches_inside_block_good() { __block bool x = true; accept_callback(^{ if (x) { wait(); if (x) { } } }); mutate_at_any_time(&x); } // GNU Expression Statements void negative_gnu_expression_statement() { bool onFire = isBurning(); if (({ doSomething(); onFire; })) { tryToExtinguish(onFire); if (({ doSomething(); onFire; })) { // NO-MESSAGE: fire may have been extinguished scream(); } } } // Comma after Condition void negative_comma_after_condition() { bool onFire = isBurning(); if (doSomething(), onFire) { tryToExtinguish(onFire); if (doSomething(), onFire) { // NO-MESSAGE: fire may have been extinguished scream(); } } } //===--- Unhandled Cases --------------------------------------------------===// void negated_in_else() { bool onFire = isBurning(); if (onFire) { scream(); } else { if (!onFire) { doSomething(); } } } void equality() { if (peopleInTheBuilding == 1) { if (peopleInTheBuilding == 1) { doSomething(); } } } void relational_operator() { if (peopleInTheBuilding > 2) { if (peopleInTheBuilding > 1) { doSomething(); } } } void relational_operator_reversed() { if (peopleInTheBuilding > 1) { if (1 < peopleInTheBuilding) { doSomething(); } } } void volatile_concrete_address() { // No warning. The value behind the volatile concrete address // is beyond our control. It may change at any time. if (*(volatile int *)0x1234) { if (*(volatile int *)0x1234) { doSomething(); } } }