[cfe-commits] r86083 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp test/Parser/if-scope-c90.c test/Parser/if-scope-c99.c test/Sema/compare.c
John McCall
rjmccall at apple.com
Wed Nov 4 16:40:04 PST 2009
Author: rjmccall
Date: Wed Nov 4 18:40:04 2009
New Revision: 86083
URL: http://llvm.org/viewvc/llvm-project?rev=86083&view=rev
Log:
Implement -Wsign-compare, or at least the actual comparison part of it.
Conditional operands are next.
Fixes part of rdar://problem/7289584.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/Parser/if-scope-c90.c
cfe/trunk/test/Parser/if-scope-c99.c
cfe/trunk/test/Sema/compare.c
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=86083&r1=86082&r2=86083&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Nov 4 18:40:04 2009
@@ -1537,6 +1537,9 @@
def err_typecheck_assign_const : Error<"read-only variable is not assignable">;
def err_stmtexpr_file_scope : Error<
"statement expression not allowed at file scope">;
+def warn_mixed_sign_comparison : Warning<
+ "comparison of integers of different signs: %0 and %1">,
+ InGroup<DiagGroup<"sign-compare">>;
def err_invalid_this_use : Error<
"invalid use of 'this' outside of a nonstatic member function">;
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=86083&r1=86082&r2=86083&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Nov 4 18:40:04 2009
@@ -4427,6 +4427,41 @@
return LHSTy;
}
+/// Implements -Wsign-compare.
+static void DiagnoseSignCompare(Sema &S, Expr *lex, Expr *rex,
+ BinaryOperator::Opcode Opc, SourceLocation OpLoc) {
+ QualType lt = lex->getType(), rt = rex->getType();
+
+ // Only warn if both operands are integral.
+ if (!lt->isIntegerType() || !rt->isIntegerType())
+ return;
+
+ // The rule is that the signed operand becomes unsigned, so isolate the
+ // signed operand.
+ Expr *signedOperand;
+ if (lt->isSignedIntegerType()) {
+ if (rt->isSignedIntegerType()) return;
+ signedOperand = lex;
+ } else {
+ if (!rt->isSignedIntegerType()) return;
+ signedOperand = rex;
+ }
+
+ // If the value is a non-negative integer constant, then the
+ // signed->unsigned conversion won't change it.
+ llvm::APSInt value;
+ if (signedOperand->isIntegerConstantExpr(value, S.Context)) {
+ assert(value.isSigned() && "result of signed expression not signed");
+
+ if (value.isNonNegative())
+ return;
+ }
+
+ S.Diag(OpLoc, diag::warn_mixed_sign_comparison)
+ << lex->getType() << rex->getType()
+ << lex->getSourceRange() << rex->getSourceRange();
+}
+
// C99 6.5.8, C++ [expr.rel]
QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
unsigned OpaqueOpc, bool isRelational) {
@@ -4435,6 +4470,8 @@
if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
return CheckVectorCompareOperands(lex, rex, Loc, isRelational);
+ DiagnoseSignCompare(*this, lex, rex, Opc, Loc);
+
// C99 6.5.8p3 / C99 6.5.9p4
if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType())
UsualArithmeticConversions(lex, rex);
Modified: cfe/trunk/test/Parser/if-scope-c90.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/if-scope-c90.c?rev=86083&r1=86082&r2=86083&view=diff
==============================================================================
--- cfe/trunk/test/Parser/if-scope-c90.c (original)
+++ cfe/trunk/test/Parser/if-scope-c90.c Wed Nov 4 18:40:04 2009
@@ -2,7 +2,7 @@
int f (int z)
{
- if (z > sizeof (enum {a, b}))
+ if (z > (int) sizeof (enum {a, b}))
return a;
return b;
}
Modified: cfe/trunk/test/Parser/if-scope-c99.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/if-scope-c99.c?rev=86083&r1=86082&r2=86083&view=diff
==============================================================================
--- cfe/trunk/test/Parser/if-scope-c99.c (original)
+++ cfe/trunk/test/Parser/if-scope-c99.c Wed Nov 4 18:40:04 2009
@@ -2,7 +2,7 @@
int f (int z)
{
- if (z > sizeof (enum {a, b}))
+ if (z > (int) sizeof (enum {a, b}))
return a;
return b; // expected-error{{use of undeclared identifier}}
}
Modified: cfe/trunk/test/Sema/compare.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/compare.c?rev=86083&r1=86082&r2=86083&view=diff
==============================================================================
--- cfe/trunk/test/Sema/compare.c (original)
+++ cfe/trunk/test/Sema/compare.c Wed Nov 4 18:40:04 2009
@@ -7,6 +7,14 @@
return C != 1; // expected-warning {{comparison between pointer and integer ('char *' and 'int')}}
}
+int ints(long a, unsigned long b) {
+ return (a == b) + // expected-warning {{comparison of integers of different signs}}
+ ((int)a == b) + // expected-warning {{comparison of integers of different signs}}
+ ((short)a == b) + // expected-warning {{comparison of integers of different signs}}
+ (a == (unsigned int) b) + // expected-warning {{comparison of integers of different signs}}
+ (a == (unsigned short) b); // expected-warning {{comparison of integers of different signs}}
+}
+
int equal(char *a, const char *b) {
return a == b;
}
More information about the cfe-commits
mailing list