diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-12-14 15:16:18 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-12-14 15:16:18 +0000 |
commit | c70f1d63f89258d1da24e7419b15fa58a61e6607 (patch) | |
tree | 4f781286647f9e7a65b4fdf6b6c7a6760bd4b057 /clang/lib/StaticAnalyzer | |
parent | ee27d2ebae8b57f3d2e6788efaed75494ff2d2ac (diff) | |
download | bcm5719-llvm-c70f1d63f89258d1da24e7419b15fa58a61e6607.tar.gz bcm5719-llvm-c70f1d63f89258d1da24e7419b15fa58a61e6607.zip |
[c++20] P0515R3: Parsing support and basic AST construction for operator <=>.
Adding the new enumerator forced a bunch more changes into this patch than I
would have liked. The -Wtautological-compare warning was extended to properly
check the new comparison operator, clang-format needed updating because it uses
precedence levels as weights for determining where to break lines (and several
operators increased their precedence levels with this change), thread-safety
analysis needed changes to build its own IL properly for the new operator.
All "real" semantic checking for this operator has been deferred to a future
patch. For now, we use the relational comparison rules and arbitrarily give
the builtin form of the operator a return type of 'void'.
llvm-svn: 320707
Diffstat (limited to 'clang/lib/StaticAnalyzer')
5 files changed, 10 insertions, 5 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp index 0c3bff5b63b..cf57b8dca06 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp @@ -255,7 +255,10 @@ void FindIdenticalExprVisitor::checkComparisonOp(const BinaryOperator *B) { PathDiagnosticLocation ELoc = PathDiagnosticLocation::createOperatorLoc(B, BR.getSourceManager()); StringRef Message; - if (((Op == BO_EQ) || (Op == BO_LE) || (Op == BO_GE))) + if (Op == BO_Cmp) + Message = "comparison of identical expressions always evaluates to " + "'equal'"; + else if (((Op == BO_EQ) || (Op == BO_LE) || (Op == BO_GE))) Message = "comparison of identical expressions always evaluates to true"; else Message = "comparison of identical expressions always evaluates to false"; diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index f651596006b..7304d789431 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -1541,7 +1541,7 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond, const BinaryOperator *BExpr, // For non-assignment operations, we require that we can understand // both the LHS and RHS. if (LhsString.empty() || RhsString.empty() || - !BinaryOperator::isComparisonOp(Op)) + !BinaryOperator::isComparisonOp(Op) || Op == BO_Cmp) return nullptr; // Should we invert the strings if the LHS is not a variable name? diff --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp index 6a4c4d11585..5a4031c0b4a 100644 --- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp +++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp @@ -396,7 +396,9 @@ bool RangeConstraintManager::canReasonAbout(SVal X) const { } if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(SE)) { - if (BinaryOperator::isComparisonOp(SSE->getOpcode())) { + // FIXME: Handle <=> here. + if (BinaryOperator::isEqualityOp(SSE->getOpcode()) || + BinaryOperator::isRelationalOp(SSE->getOpcode())) { // We handle Loc <> Loc comparisons, but not (yet) NonLoc <> NonLoc. if (Loc::isLocType(SSE->getLHS()->getType())) { assert(Loc::isLocType(SSE->getRHS()->getType())); diff --git a/clang/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp b/clang/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp index 1304116f497..55ff15806ef 100644 --- a/clang/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp +++ b/clang/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp @@ -33,7 +33,7 @@ ProgramStateRef RangedConstraintManager::assumeSym(ProgramStateRef State, // We can only simplify expressions whose RHS is an integer. BinaryOperator::Opcode op = SIE->getOpcode(); - if (BinaryOperator::isComparisonOp(op)) { + if (BinaryOperator::isComparisonOp(op) && op != BO_Cmp) { if (!Assumption) op = BinaryOperator::negateComparisonOp(op); diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index a5b5744c3fb..94d29d5a6ba 100644 --- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -679,7 +679,7 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state, if (SymbolRef rSym = rhs.getAsLocSymbol()) { // We can only build expressions with symbols on the left, // so we need a reversible operator. - if (!BinaryOperator::isComparisonOp(op)) + if (!BinaryOperator::isComparisonOp(op) || op == BO_Cmp) return UnknownVal(); const llvm::APSInt &lVal = lhs.castAs<loc::ConcreteInt>().getValue(); |