aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Sema/SemaExpr.cpp47
-rw-r--r--test/Sema/floating-point-compare.c8
2 files changed, 53 insertions, 2 deletions
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<ParenExpr>(E))
+ E = P->getSubExpr();
+ else if (CastExpr* P = dyn_cast<CastExpr>(E))
+ E = P->getSubExpr();
+ else if (ImplicitCastExpr* P = dyn_cast<ImplicitCastExpr>(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<DeclRefExpr>(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<DeclRefExpr>(IgnoreParen(lex)))
- if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(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<DeclRefExpr>(LeftExprSansParen))
+ if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
if (DRL->getDecl() == DRR->getDecl())
EmitWarning = false;
+
+ // Check for comparisons with builtin types.
+ if (EmitWarning)
+ if (CallExpr* CL = dyn_cast<CallExpr>(LeftExprSansParen))
+ if (isCallBuiltin(CL))
+ EmitWarning = false;
+ if (EmitWarning)
+ if (CallExpr* CR = dyn_cast<CallExpr>(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