From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- build/clang-plugin/NaNExprChecker.cpp | 54 +++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 build/clang-plugin/NaNExprChecker.cpp (limited to 'build/clang-plugin/NaNExprChecker.cpp') diff --git a/build/clang-plugin/NaNExprChecker.cpp b/build/clang-plugin/NaNExprChecker.cpp new file mode 100644 index 0000000000..bacebc9155 --- /dev/null +++ b/build/clang-plugin/NaNExprChecker.cpp @@ -0,0 +1,54 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "NaNExprChecker.h" +#include "CustomMatchers.h" + +void NaNExprChecker::registerMatchers(MatchFinder *AstMatcher) { + AstMatcher->addMatcher( + binaryOperator( + allOf(binaryEqualityOperator(), + hasLHS(has(ignoringParenImpCasts( + declRefExpr(hasType(qualType((isFloat())))).bind("lhs")))), + hasRHS(has(ignoringParenImpCasts( + declRefExpr(hasType(qualType((isFloat())))).bind("rhs")))), + unless(anyOf(isInSystemHeader(), isInWhitelistForNaNExpr())))) + .bind("node"), + this); +} + +void NaNExprChecker::check(const MatchFinder::MatchResult &Result) { + if (!Result.Context->getLangOpts().CPlusPlus) { + return; + } + + const BinaryOperator *Expression = + Result.Nodes.getNodeAs("node"); + const DeclRefExpr *LHS = Result.Nodes.getNodeAs("lhs"); + const DeclRefExpr *RHS = Result.Nodes.getNodeAs("rhs"); + const ImplicitCastExpr *LHSExpr = + dyn_cast(Expression->getLHS()); + const ImplicitCastExpr *RHSExpr = + dyn_cast(Expression->getRHS()); + // The AST subtree that we are looking for will look like this: + // -BinaryOperator ==/!= + // |-ImplicitCastExpr LValueToRValue + // | |-DeclRefExpr + // |-ImplicitCastExpr LValueToRValue + // |-DeclRefExpr + // The check below ensures that we are dealing with the correct AST subtree + // shape, and + // also that both of the found DeclRefExpr's point to the same declaration. + if (LHS->getFoundDecl() == RHS->getFoundDecl() && LHSExpr && RHSExpr && + std::distance(LHSExpr->child_begin(), LHSExpr->child_end()) == 1 && + std::distance(RHSExpr->child_begin(), RHSExpr->child_end()) == 1 && + *LHSExpr->child_begin() == LHS && *RHSExpr->child_begin() == RHS) { + diag(Expression->getBeginLoc(), + "comparing a floating point value to itself for " + "NaN checking can lead to incorrect results", + DiagnosticIDs::Error); + diag(Expression->getBeginLoc(), "consider using std::isnan instead", + DiagnosticIDs::Note); + } +} -- cgit v1.2.3