summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2009-10-12 21:59:07 +0000
committerJohn McCall <rjmccall@apple.com>2009-10-12 21:59:07 +0000
commitd5707abdfdd5b07190d7473f9ef12e5f742cf5be (patch)
treef28c146eb502841ea8a42787c35b3a7a84e6a7eb /clang/lib/Sema/SemaExpr.cpp
parent3250e7769fd6b39572c675a480a1e3cd04af4e4d (diff)
downloadbcm5719-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.cpp53
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;
+}
OpenPOWER on IntegriCloud