bool CheckBuiltinCFStringArgument(Expr* Arg);
+
+ void CheckFloatComparison(SourceLocation loc, Expr* lex, Expr* rex);
};
#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
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<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());
+}
//===----------------------------------------------------------------------===//
#include "Sema.h"
+#include "SemaUtil.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
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<ParenExpr>(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<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)
{
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<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());
+ CheckFloatComparison(loc,lex,rex);
}
if (lType->isArithmeticType() && rType->isArithmeticType())
--- /dev/null
+//===--- 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<ParenExpr>(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<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;
+}
+
+} // end namespace clang
+
+#endif
35839B0A0CDF845F006ED061 /* TypeSerialization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeSerialization.cpp; path = AST/TypeSerialization.cpp; sourceTree = "<group>"; };
35847BE30CC7DB9000C40FFF /* StmtIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StmtIterator.h; path = clang/AST/StmtIterator.h; sourceTree = "<group>"; };
35847BE40CC7DBAF00C40FFF /* StmtIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StmtIterator.cpp; path = AST/StmtIterator.cpp; sourceTree = "<group>"; };
+ 35A2B8610CF8FFA300E6C317 /* SemaUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SemaUtil.h; path = Sema/SemaUtil.h; sourceTree = "<group>"; };
35AE0F660C9B4CA300CC1279 /* UninitializedValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UninitializedValues.h; path = clang/Analysis/UninitializedValues.h; sourceTree = "<group>"; };
35BFBD2B0C9EDE1E006CB644 /* ASTConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTConsumer.h; path = clang/AST/ASTConsumer.h; sourceTree = "<group>"; };
35CFFDFF0CA1CBCB00E6F2BE /* StmtViz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StmtViz.cpp; path = AST/StmtViz.cpp; sourceTree = "<group>"; };
children = (
DE67E7190C020F4F00F66BC5 /* ASTStreamer.cpp */,
DE67E7140C020EDF00F66BC5 /* Sema.h */,
+ 35A2B8610CF8FFA300E6C317 /* SemaUtil.h */,
DE67E7160C020EE400F66BC5 /* Sema.cpp */,
DEF2F00F0C6CFED5000C4259 /* SemaChecking.cpp */,
DE67E7120C020ED900F66BC5 /* SemaDecl.cpp */,