[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
diff --git a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
index 0c3bff5..cf57b8d 100644
--- a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
@@ -255,7 +255,10 @@
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 f651596..7304d78 100644
--- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -1541,7 +1541,7 @@
// 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 6a4c4d1..5a4031c 100644
--- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -396,7 +396,9 @@
}
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 1304116..55ff158 100644
--- a/clang/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp
@@ -33,7 +33,7 @@
// 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 a5b5744..94d29d5 100644
--- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -679,7 +679,7 @@
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();