Index: include/clang/AST/Expr.h =================================================================== --- include/clang/AST/Expr.h +++ include/clang/AST/Expr.h @@ -116,6 +116,7 @@ ExprBits.ValueKind = VK; ExprBits.ObjectKind = OK; ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; + ExprBits.IsCondition = 0; setType(T); } @@ -219,6 +220,17 @@ ExprBits.ContainsUnexpandedParameterPack = PP; } + /// \brief Whether this expression appears in condition expression context. + bool isCondition() const { + return ExprBits.IsCondition; + } + + /// \brief Set the bit that describes whether this expression + /// appears in condition context e.g.: if(expr) while(expr) ?: etc. + void setIsCondition(bool PP = true) { + ExprBits.IsCondition = PP; + } + /// getExprLoc - Return the preferred location for the arrow when diagnosing /// a problem with a generic expression. SourceLocation getExprLoc() const LLVM_READONLY; Index: include/clang/AST/Stmt.h =================================================================== --- include/clang/AST/Stmt.h +++ include/clang/AST/Stmt.h @@ -131,8 +131,9 @@ unsigned ValueDependent : 1; unsigned InstantiationDependent : 1; unsigned ContainsUnexpandedParameterPack : 1; + unsigned IsCondition : 1; }; - enum { NumExprBits = 16 }; + enum { NumExprBits = 17 }; class CharacterLiteralBitfields { friend class CharacterLiteral; Index: lib/Parse/ParseExpr.cpp =================================================================== --- lib/Parse/ParseExpr.cpp +++ lib/Parse/ParseExpr.cpp @@ -309,6 +309,8 @@ TernaryMiddle = nullptr; Diag(Tok, diag::ext_gnu_conditional_expr); } + if (!LHS.isInvalid()) + LHS.get()->setIsCondition(); if (!TryConsumeToken(tok::colon, ColonLoc)) { // Otherwise, we're missing a ':'. Assume that this was a typo that Index: lib/Sema/SemaChecking.cpp =================================================================== --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -9020,6 +9020,10 @@ if (S.SourceMgr.isInSystemMacro(CC)) return; + // Suppress float-to-bool diagnostic in conditions. + if (TargetBT->isBooleanType() && E->isCondition()) + return; + DiagnoseFloatingImpCast(S, E, T, CC); } @@ -9222,7 +9226,10 @@ /// of competing diagnostics here, -Wconversion and -Wsign-compare. void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, SourceLocation CC) { QualType T = OrigE->getType(); + bool isCondition = OrigE->isCondition(); Expr *E = OrigE->IgnoreParenImpCasts(); + if (isCondition) + E->setIsCondition(isCondition); if (E->isTypeDependent() || E->isValueDependent()) return; Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -14607,10 +14607,12 @@ ExprResult Cond; switch (CK) { case ConditionKind::Boolean: + SubExpr->setIsCondition(); Cond = CheckBooleanCondition(Loc, SubExpr); break; case ConditionKind::ConstexprIf: + SubExpr->setIsCondition(); Cond = CheckBooleanCondition(Loc, SubExpr, true); break; Index: lib/Sema/SemaStmt.cpp =================================================================== --- lib/Sema/SemaStmt.cpp +++ lib/Sema/SemaStmt.cpp @@ -1264,6 +1264,7 @@ if (CondResult.isInvalid()) return StmtError(); Cond = CondResult.get(); + Cond->setIsCondition(); CondResult = ActOnFinishFullExpr(Cond, DoLoc); if (CondResult.isInvalid()) Index: test/SemaCXX/warn-float-conversion.cpp =================================================================== --- test/SemaCXX/warn-float-conversion.cpp +++ test/SemaCXX/warn-float-conversion.cpp @@ -87,3 +87,29 @@ char e = 1.0 / 0.0; // expected-warning{{implicit conversion of out of range value from 'double' to 'char' changes value from +Inf to 127}} } #endif // OVERFLOW + +int m(int argc) +{ + float f = argc; + // Test that float-to-bool conversion warnings are not issued + // for conditions. + + + if (f) + return 1; + else + return f + ? 1 + : 0; + + if (f+1) //Question: also suppress for this expresson? + return 1; + + while (f) ; + + do ; while (f) ; + + for (; f ; ) ; + + return 0; +}