From: Ted Kremenek Date: Sun, 25 Nov 2007 00:58:00 +0000 (+0000) Subject: Moved logic for -Wfloat-equal to SemaChecking.cpp. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=588e5ebee2db045c3611e0c8f601bc4495ebd0f3;p=clang Moved logic for -Wfloat-equal to SemaChecking.cpp. Moved utility functions IgnoreParen and friends to be static inline functions defined in SemaUtil.h. Added SemaUtil.h to Xcode project. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44312 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Sema/Sema.h b/Sema/Sema.h index 16d4cabb7e..c879146760 100644 --- a/Sema/Sema.h +++ b/Sema/Sema.h @@ -729,6 +729,8 @@ private: bool CheckBuiltinCFStringArgument(Expr* Arg); + + void CheckFloatComparison(SourceLocation loc, Expr* lex, Expr* rex); }; diff --git a/Sema/SemaChecking.cpp b/Sema/SemaChecking.cpp index c2e3817171..cb22f03a31 100644 --- a/Sema/SemaChecking.cpp +++ b/Sema/SemaChecking.cpp @@ -25,6 +25,8 @@ #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" +#include "SemaUtil.h" + using namespace clang; /// CheckFunctionCall - Check a direct function call for various correctness @@ -694,3 +696,38 @@ static DeclRefExpr* EvalVal(Expr *E) { return NULL; } } + +//===--- CHECK: Floating-Point comparisons (-Wfloat-equal) ---------------===// + +/// Check for comparisons of floating point operands using != and ==. +/// Issue a warning if these are no self-comparisons, as they are not likely +/// to do what the programmer intended. +void Sema::CheckFloatComparison(SourceLocation loc, Expr* lex, Expr *rex) { + bool EmitWarning = true; + + Expr* LeftExprSansParen = IgnoreParen(lex); + Expr* RightExprSansParen = IgnoreParen(rex); + + // Special case: check for x == x (which is OK). + // 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/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index 6c3b06e015..a9cd41580b 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "Sema.h" +#include "SemaUtil.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" @@ -1213,42 +1214,6 @@ inline QualType Sema::CheckShiftOperands( // C99 6.5.7 return QualType(); } -// Utility method to plow through parentheses to get the first nested -// non-ParenExpr expr. -static inline Expr* IgnoreParen(Expr* E) { - while (ParenExpr* P = dyn_cast(E)) - E = P->getSubExpr(); - - 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) { @@ -1277,38 +1242,9 @@ inline QualType Sema::CheckCompareOperands( // C99 6.5.8 return Context.IntTy; } else { // Check for comparisons of floating point operands using != and ==. - // Issue a warning if these are no self-comparisons, as they are not likely - // to do what the programmer intended. if (lType->isFloatingType()) { assert (rType->isFloatingType()); - - // Special case: check for x == x (which is OK). - bool EmitWarning = true; - - 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()); + CheckFloatComparison(loc,lex,rex); } if (lType->isArithmeticType() && rType->isArithmeticType()) diff --git a/Sema/SemaUtil.h b/Sema/SemaUtil.h new file mode 100644 index 0000000000..2932862e91 --- /dev/null +++ b/Sema/SemaUtil.h @@ -0,0 +1,60 @@ +//===--- SemaUtil.h - Utility functions for semantic analysis -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Ted Kremenek and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides a few static inline functions that are useful for +// performing semantic analysis. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_UTIL_H +#define LLVM_CLANG_SEMA_UTIL_H + +#include "clang/AST/Expr.h" + +namespace clang { + +/// Utility method to plow through parentheses to get the first nested +/// non-ParenExpr expr. +static inline Expr* IgnoreParen(Expr* E) { + while (ParenExpr* P = dyn_cast(E)) + E = P->getSubExpr(); + + 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; +} + +} // end namespace clang + +#endif diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index b9eb859d85..1585d851d9 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -242,6 +242,7 @@ 35839B0A0CDF845F006ED061 /* TypeSerialization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeSerialization.cpp; path = AST/TypeSerialization.cpp; sourceTree = ""; }; 35847BE30CC7DB9000C40FFF /* StmtIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StmtIterator.h; path = clang/AST/StmtIterator.h; sourceTree = ""; }; 35847BE40CC7DBAF00C40FFF /* StmtIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StmtIterator.cpp; path = AST/StmtIterator.cpp; sourceTree = ""; }; + 35A2B8610CF8FFA300E6C317 /* SemaUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SemaUtil.h; path = Sema/SemaUtil.h; sourceTree = ""; }; 35AE0F660C9B4CA300CC1279 /* UninitializedValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UninitializedValues.h; path = clang/Analysis/UninitializedValues.h; sourceTree = ""; }; 35BFBD2B0C9EDE1E006CB644 /* ASTConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTConsumer.h; path = clang/AST/ASTConsumer.h; sourceTree = ""; }; 35CFFDFF0CA1CBCB00E6F2BE /* StmtViz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StmtViz.cpp; path = AST/StmtViz.cpp; sourceTree = ""; }; @@ -516,6 +517,7 @@ children = ( DE67E7190C020F4F00F66BC5 /* ASTStreamer.cpp */, DE67E7140C020EDF00F66BC5 /* Sema.h */, + 35A2B8610CF8FFA300E6C317 /* SemaUtil.h */, DE67E7160C020EE400F66BC5 /* Sema.cpp */, DEF2F00F0C6CFED5000C4259 /* SemaChecking.cpp */, DE67E7120C020ED900F66BC5 /* SemaDecl.cpp */,