clang-tools 22.0.0git
IncorrectRoundingsCheck.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "clang/ASTMatchers/ASTMatchFinder.h"
11#include "clang/ASTMatchers/ASTMatchers.h"
12
13using namespace clang::ast_matchers;
14
15namespace clang::tidy::bugprone {
16
17static llvm::APFloat getHalf(const llvm::fltSemantics &Semantics) {
18 return llvm::APFloat(Semantics, 1U) / llvm::APFloat(Semantics, 2U);
19}
20
21namespace {
22AST_MATCHER(FloatingLiteral, floatHalf) {
23 return Node.getValue() == getHalf(Node.getSemantics());
24}
25} // namespace
26
27void IncorrectRoundingsCheck::registerMatchers(MatchFinder *MatchFinder) {
28 // Match a floating literal with value 0.5.
29 auto FloatHalf = floatLiteral(floatHalf());
30
31 // Match a floating point expression.
32 auto FloatType = expr(hasType(realFloatingPointType()));
33
34 // Find expressions of cast to int of the sum of a floating point expression
35 // and 0.5.
36 MatchFinder->addMatcher(
37 traverse(TK_AsIs,
38 implicitCastExpr(
39 hasImplicitDestinationType(isInteger()),
40 ignoringParenCasts(binaryOperator(
41 hasOperatorName("+"), hasOperands(FloatType, FloatType),
42 hasEitherOperand(ignoringParenImpCasts(FloatHalf)))))
43 .bind("CastExpr")),
44 this);
45}
46
47void IncorrectRoundingsCheck::check(const MatchFinder::MatchResult &Result) {
48 const auto *CastExpr = Result.Nodes.getNodeAs<ImplicitCastExpr>("CastExpr");
49 diag(CastExpr->getBeginLoc(),
50 "casting (double + 0.5) to integer leads to incorrect rounding; "
51 "consider using lround (#include <cmath>) instead");
52}
53
54} // namespace clang::tidy::bugprone
void registerMatchers(ast_matchers::MatchFinder *Finder) override
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
static llvm::APFloat getHalf(const llvm::fltSemantics &Semantics)