diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-06-08 19:50:34 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-06-08 19:50:34 +0000 |
| commit | ec170db73d501d73c9e1b08178ea7ad325ceeb38 (patch) | |
| tree | 47217ecc63b3e8f4c666403586db136b020c66c1 /clang/lib/Sema | |
| parent | 61b5ff5ab4e5848e5e98b811cf0accf5d3b8db22 (diff) | |
| download | bcm5719-llvm-ec170db73d501d73c9e1b08178ea7ad325ceeb38.tar.gz bcm5719-llvm-ec170db73d501d73c9e1b08178ea7ad325ceeb38.zip | |
Warn about comparisons between arrays and improve self-comparison
warnings, from Troy Straszheim! Fixes PR6163.
llvm-svn: 105631
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index da7c6a2daec..6c1f4161328 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5292,13 +5292,6 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) return CheckVectorCompareOperands(lex, rex, Loc, isRelational); - // C99 6.5.8p3 / C99 6.5.9p4 - if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType()) - UsualArithmeticConversions(lex, rex); - else { - UsualUnaryConversions(lex); - UsualUnaryConversions(rex); - } QualType lType = lex->getType(); QualType rType = rex->getType(); @@ -5312,10 +5305,36 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, Expr *LHSStripped = lex->IgnoreParens(); Expr *RHSStripped = rex->IgnoreParens(); if (DeclRefExpr* DRL = dyn_cast<DeclRefExpr>(LHSStripped)) - if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(RHSStripped)) + if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(RHSStripped)) { if (DRL->getDecl() == DRR->getDecl() && - !isa<EnumConstantDecl>(DRL->getDecl())) - DiagRuntimeBehavior(Loc, PDiag(diag::warn_selfcomparison)); + !isa<EnumConstantDecl>(DRL->getDecl())) { + DiagRuntimeBehavior(Loc, PDiag(diag::warn_comparison_always) + << 0 // self- + << (Opc == BinaryOperator::EQ + || Opc == BinaryOperator::LE + || Opc == BinaryOperator::GE)); + } else if (lType->isArrayType() && rType->isArrayType() && + !DRL->getDecl()->getType()->isReferenceType() && + !DRR->getDecl()->getType()->isReferenceType()) { + // what is it always going to eval to? + char always_evals_to; + switch(Opc) { + case BinaryOperator::EQ: // e.g. array1 == array2 + always_evals_to = 0; // false + break; + case BinaryOperator::NE: // e.g. array1 != array2 + always_evals_to = 1; // true + break; + default: + // best we can say is 'a constant' + always_evals_to = 2; // e.g. array1 <= array2 + break; + } + DiagRuntimeBehavior(Loc, PDiag(diag::warn_comparison_always) + << 1 // array + << always_evals_to); + } + } if (isa<CastExpr>(LHSStripped)) LHSStripped = LHSStripped->IgnoreParenCasts(); @@ -5358,6 +5377,17 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, } } + // C99 6.5.8p3 / C99 6.5.9p4 + if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType()) + UsualArithmeticConversions(lex, rex); + else { + UsualUnaryConversions(lex); + UsualUnaryConversions(rex); + } + + lType = lex->getType(); + rType = rex->getType(); + // The result of comparisons is 'bool' in C++, 'int' in C. QualType ResultTy = getLangOptions().CPlusPlus ? Context.BoolTy:Context.IntTy; @@ -5632,7 +5662,11 @@ QualType Sema::CheckVectorCompareOperands(Expr *&lex, Expr *&rex, if (DeclRefExpr* DRL = dyn_cast<DeclRefExpr>(lex->IgnoreParens())) if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(rex->IgnoreParens())) if (DRL->getDecl() == DRR->getDecl()) - DiagRuntimeBehavior(Loc, PDiag(diag::warn_selfcomparison)); + DiagRuntimeBehavior(Loc, + PDiag(diag::warn_comparison_always) + << 0 // self- + << 2 // "a constant" + ); } // Check for comparisons of floating point operands using != and ==. |

