diff options
| author | John McCall <rjmccall@apple.com> | 2009-10-12 21:59:07 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2009-10-12 21:59:07 +0000 |
| commit | d5707abdfdd5b07190d7473f9ef12e5f742cf5be (patch) | |
| tree | f28c146eb502841ea8a42787c35b3a7a84e6a7eb /clang/lib/Sema/SemaExpr.cpp | |
| parent | 3250e7769fd6b39572c675a480a1e3cd04af4e4d (diff) | |
| download | bcm5719-llvm-d5707abdfdd5b07190d7473f9ef12e5f742cf5be.tar.gz bcm5719-llvm-d5707abdfdd5b07190d7473f9ef12e5f742cf5be.zip | |
Implement -Wparentheses: warn about using assignments in contexts that require
conditions. Add a fixit to insert the parentheses. Also fix a very minor
possible memory leak in 'for' conditions.
Fixes PR 4876 and rdar://problem/7289172
llvm-svn: 83907
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 3dc7d8f4efe..7c1c62c0a0d 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -6268,3 +6268,56 @@ bool Sema::CheckCallReturnType(QualType ReturnType, SourceLocation Loc, return false; } +// Diagnose the common s/=/==/ typo. Note that adding parentheses +// will prevent this condition from triggering, which is what we want. +void Sema::DiagnoseAssignmentAsCondition(Expr *E) { + SourceLocation Loc; + + if (isa<BinaryOperator>(E)) { + BinaryOperator *Op = cast<BinaryOperator>(E); + if (Op->getOpcode() != BinaryOperator::Assign) + return; + + Loc = Op->getOperatorLoc(); + } else if (isa<CXXOperatorCallExpr>(E)) { + CXXOperatorCallExpr *Op = cast<CXXOperatorCallExpr>(E); + if (Op->getOperator() != OO_Equal) + return; + + Loc = Op->getOperatorLoc(); + } else { + // Not an assignment. + return; + } + + // We want to insert before the start of the expression... + SourceLocation Open = E->getSourceRange().getBegin(); + // ...and one character after the end. + SourceLocation Close = E->getSourceRange().getEnd().getFileLocWithOffset(1); + + Diag(Loc, diag::warn_condition_is_assignment) + << E->getSourceRange() + << CodeModificationHint::CreateInsertion(Open, "(") + << CodeModificationHint::CreateInsertion(Close, ")"); +} + +bool Sema::CheckBooleanCondition(Expr *&E, SourceLocation Loc) { + DiagnoseAssignmentAsCondition(E); + + if (!E->isTypeDependent()) { + DefaultFunctionArrayConversion(E); + + QualType T = E->getType(); + + if (getLangOptions().CPlusPlus) { + if (CheckCXXBooleanCondition(E)) // C++ 6.4p4 + return true; + } else if (!T->isScalarType()) { // C99 6.8.4.1p1 + Diag(Loc, diag::err_typecheck_statement_requires_scalar) + << T << E->getSourceRange(); + return true; + } + } + + return false; +} |

