From: Ted Kremenek Date: Tue, 13 Nov 2007 19:17:00 +0000 (+0000) Subject: Modified -Wfloat-equal logic to suppress warnings where floating point values X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c8f488d1c851fddeb7754d0c9cf98045b17da535;p=clang Modified -Wfloat-equal logic to suppress warnings where floating point values are compared against builtins such as __builtin_inf. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44058 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index a533da6306..e87ad6a398 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -1218,6 +1218,33 @@ static inline Expr* IgnoreParen(Expr* E) { return E; } +// Utility method to plow through parenthesis and casts. +static inline Expr* IgnoreParenCasts(Expr* E) { + while(true) { + if (ParenExpr* P = dyn_cast(E)) + E = P->getSubExpr(); + else if (CastExpr* P = dyn_cast(E)) + E = P->getSubExpr(); + else if (ImplicitCastExpr* P = dyn_cast(E)) + E = P->getSubExpr(); + else + break; + } + + return E; +} + +// Utility method to determine if a CallExpr is a call to a builtin. +static inline bool isCallBuiltin(CallExpr* cexp) { + Expr* sub = IgnoreParenCasts(cexp->getCallee()); + + if (DeclRefExpr* E = dyn_cast(sub)) + if (E->getDecl()->getIdentifier()->getBuiltinID() > 0) + return true; + + return false; +} + inline QualType Sema::CheckCompareOperands( // C99 6.5.8 Expr *&lex, Expr *&rex, SourceLocation loc, bool isRelational) { @@ -1254,11 +1281,27 @@ inline QualType Sema::CheckCompareOperands( // C99 6.5.8 // Special case: check for x == x (which is OK). bool EmitWarning = true; - if (DeclRefExpr* DRL = dyn_cast(IgnoreParen(lex))) - if (DeclRefExpr* DRR = dyn_cast(IgnoreParen(rex))) + Expr* LeftExprSansParen = IgnoreParen(lex); + Expr* RightExprSansParen = IgnoreParen(rex); + + // Look for x == x. Do not emit warnings for such cases. + if (DeclRefExpr* DRL = dyn_cast(LeftExprSansParen)) + if (DeclRefExpr* DRR = dyn_cast(RightExprSansParen)) if (DRL->getDecl() == DRR->getDecl()) EmitWarning = false; + + // Check for comparisons with builtin types. + if (EmitWarning) + if (CallExpr* CL = dyn_cast(LeftExprSansParen)) + if (isCallBuiltin(CL)) + EmitWarning = false; + if (EmitWarning) + if (CallExpr* CR = dyn_cast(RightExprSansParen)) + if (isCallBuiltin(CR)) + EmitWarning = false; + + // Emit the diagnostic. if (EmitWarning) Diag(loc, diag::warn_floatingpoint_eq, lex->getSourceRange(),rex->getSourceRange()); diff --git a/test/Sema/floating-point-compare.c b/test/Sema/floating-point-compare.c index cc96be0fd3..d8eff58e92 100644 --- a/test/Sema/floating-point-compare.c +++ b/test/Sema/floating-point-compare.c @@ -11,3 +11,11 @@ int bar(float x, float y) { int qux(float x) { return x == x; // no-warning } + +int baz(float x) { + return x == 0.0; // no-warning +} + +int taz(float x) { + return x == __builtin_inf(); // no-warning +} \ No newline at end of file