[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/PiotrZSL closed https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/HerrCai0907 approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
11happy wrote: hello @5chmidti I am sorry for my delayed response quite busy with my academic work last week, I have added this change ``` if (EndLoc.isInvalid()) return; ``` this works fine for those macros. Thank you https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/11happy updated https://github.com/llvm/llvm-project/pull/84481 >From 8fdf6306085ed4cf0f77b7e718e374e9f65fedf9 Mon Sep 17 00:00:00 2001 From: 11happy Date: Fri, 8 Mar 2024 19:02:47 +0530 Subject: [PATCH 01/14] add clang-tidy check readability-math-missing-parentheses Signed-off-by: 11happy --- .../clang-tidy/readability/CMakeLists.txt | 1 + .../MathMissingParenthesesCheck.cpp | 167 ++ .../readability/MathMissingParenthesesCheck.h | 31 .../readability/ReadabilityTidyModule.cpp | 3 + clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 1 + .../readability/math-missing-parentheses.rst | 19 ++ .../readability/math-missing-parentheses.cpp | 42 + 8 files changed, 270 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/math-missing-parentheses.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index a6c8cbd8eb448a..0d4fa095501dfb 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -27,6 +27,7 @@ add_clang_library(clangTidyReadabilityModule IsolateDeclarationCheck.cpp MagicNumbersCheck.cpp MakeMemberFunctionConstCheck.cpp + MathMissingParenthesesCheck.cpp MisleadingIndentationCheck.cpp MisplacedArrayIndexCheck.cpp NamedParameterCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp new file mode 100644 index 00..d9574a9fb7a476 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp @@ -0,0 +1,167 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include +#include + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} +static int precedenceCheck(const char op) { + if (op == '/' || op == '*' || op == '%') +return 5; + + else if (op == '+' || op == '-') +return 4; + + else if (op == '&') +return 3; + else if (op == '^') +return 2; + + else if (op == '|') +return 1; + + else +return 0; +} +static bool isOperand(const char c) { + if (c >= 'a' && c <= 'z') +return true; + else if (c >= 'A' && c <= 'Z') +return true; + else if (c >= '0' && c <= '9') +return true; + else if (c == '$') +return true; + else +return false; +} +static bool conditionForNegative(const std::string s, int i, + const std::string CurStr) { + if (CurStr[0] == '-') { +if (i == 0) { + return true; +} else { + while (s[i - 1] == ' ') { +i--; + } + if (!isOperand(s[i - 1])) { +return true; + } else { +return false; + } +} + } else { +return false; + } +} +static std::string getOperationOrder(std::string s, std::set &Operators) { + std::stack StackOne; + std::string TempStr = ""; + for (int i = 0; i < s.length(); i++) { +std::string CurStr = ""; +CurStr += s[i]; +if (CurStr == " ") + continue; +else { + if (isOperand(CurStr[0]) || conditionForNegative(s, i, CurStr)) { +while (i < s.length() && (isOperand(s[i]) || s[i] == '-')) { + if (s[i] == '-') { +TempStr += "$"; + } else { +TempStr += CurStr; + } + i++; + CurStr = s[i]; +} +TempStr += " "; + } else if (CurStr == "(") { +StackOne.push("("); + } else if (CurStr == ")") { +while (StackOne.top() != "(") { + TempStr += StackOne.top(); + StackOne.pop(); +} +StackOne.pop(); + } else { +while (!StackOne.empty() && precedenceCh
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
5chmidti wrote: I let it run for a few minutes and didn't observe any crashes (on a release build though). However, I did find an issue with macros: ```c++ int sink(int); #define FUN(ARG) (sink(ARG)) #define FUN2(ARG) sink((ARG)) #define FUN3(ARG) sink(ARG) void f() { ... //CHECK-MESSAGES: :[[@LINE+4]]:17: warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] //CHECK-FIXES: int r = FUN(0 + (1 * 2)); int r = FUN(0 + 1 * 2); //CHECK-MESSAGES: :[[@LINE+4]]:17: warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] //CHECK-FIXES: int s = FUN2(0 + (1 * 2)); int s = FUN2(0 + 1 * 2); //CHECK-MESSAGES: :[[@LINE+4]]:17: warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] //CHECK-FIXES: int s = FUN3(0 + (1 * 2)); int t = FUN3(0 + 1 * 2); } ``` All three of these fail, because the closing parentheses is not added. Files with issues: - `polly/lib/External/isl/isl_map.c` - `/home/julian/dev/llvm/llvm-tmp/llvm/unittests/DebugInfo/MSF/MSFBuilderTest.cpp` - unittest files will generally have issues with this, because of the test macros - found by invoking this inside the build dir: `run-clang-tidy -clang-tidy-binary /path/to/clang-tidy -checks="-*,readability-math-missing*" -quiet unittests` Checking `EndLoc.isValid()` reveals that the location is invalid for all of these cases (`llvm::errs() << "EndLoc: " << EndLoc.isValid() << "\n";`). The documentation for `getLocForEndOfToken` also explicitly mentions this case for macros: ``` /// token where it expected something different that it received. If /// the returned source location would not be meaningful (e.g., if /// it points into a macro), this routine returns an invalid /// source location. ``` https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/11happy updated https://github.com/llvm/llvm-project/pull/84481 >From 8fdf6306085ed4cf0f77b7e718e374e9f65fedf9 Mon Sep 17 00:00:00 2001 From: 11happy Date: Fri, 8 Mar 2024 19:02:47 +0530 Subject: [PATCH 01/13] add clang-tidy check readability-math-missing-parentheses Signed-off-by: 11happy --- .../clang-tidy/readability/CMakeLists.txt | 1 + .../MathMissingParenthesesCheck.cpp | 167 ++ .../readability/MathMissingParenthesesCheck.h | 31 .../readability/ReadabilityTidyModule.cpp | 3 + clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 1 + .../readability/math-missing-parentheses.rst | 19 ++ .../readability/math-missing-parentheses.cpp | 42 + 8 files changed, 270 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/math-missing-parentheses.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index a6c8cbd8eb448a..0d4fa095501dfb 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -27,6 +27,7 @@ add_clang_library(clangTidyReadabilityModule IsolateDeclarationCheck.cpp MagicNumbersCheck.cpp MakeMemberFunctionConstCheck.cpp + MathMissingParenthesesCheck.cpp MisleadingIndentationCheck.cpp MisplacedArrayIndexCheck.cpp NamedParameterCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp new file mode 100644 index 00..d9574a9fb7a476 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp @@ -0,0 +1,167 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include +#include + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} +static int precedenceCheck(const char op) { + if (op == '/' || op == '*' || op == '%') +return 5; + + else if (op == '+' || op == '-') +return 4; + + else if (op == '&') +return 3; + else if (op == '^') +return 2; + + else if (op == '|') +return 1; + + else +return 0; +} +static bool isOperand(const char c) { + if (c >= 'a' && c <= 'z') +return true; + else if (c >= 'A' && c <= 'Z') +return true; + else if (c >= '0' && c <= '9') +return true; + else if (c == '$') +return true; + else +return false; +} +static bool conditionForNegative(const std::string s, int i, + const std::string CurStr) { + if (CurStr[0] == '-') { +if (i == 0) { + return true; +} else { + while (s[i - 1] == ' ') { +i--; + } + if (!isOperand(s[i - 1])) { +return true; + } else { +return false; + } +} + } else { +return false; + } +} +static std::string getOperationOrder(std::string s, std::set &Operators) { + std::stack StackOne; + std::string TempStr = ""; + for (int i = 0; i < s.length(); i++) { +std::string CurStr = ""; +CurStr += s[i]; +if (CurStr == " ") + continue; +else { + if (isOperand(CurStr[0]) || conditionForNegative(s, i, CurStr)) { +while (i < s.length() && (isOperand(s[i]) || s[i] == '-')) { + if (s[i] == '-') { +TempStr += "$"; + } else { +TempStr += CurStr; + } + i++; + CurStr = s[i]; +} +TempStr += " "; + } else if (CurStr == "(") { +StackOne.push("("); + } else if (CurStr == ")") { +while (StackOne.top() != "(") { + TempStr += StackOne.top(); + StackOne.pop(); +} +StackOne.pop(); + } else { +while (!StackOne.empty() && precedenceCh
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,97 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +unless(isAssignmentOperator()), +unless(isComparisonOperator()), +unless(hasAnyOperatorName("&&", "||")), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +static int getPrecedence(const BinaryOperator *BinOp) { + if (!BinOp) +return 0; + switch (BinOp->getOpcode()) { + case BO_Mul: + case BO_Div: + case BO_Rem: +return 5; + case BO_Add: + case BO_Sub: +return 4; + case BO_And: +return 3; + case BO_Xor: +return 2; + case BO_Or: +return 1; + default: +return 0; + } +} +static void addParantheses(const BinaryOperator *BinOp, + const BinaryOperator *ParentBinOp, + ClangTidyCheck *Check, + const clang::SourceManager &SM, + const clang::LangOptions &LangOpts) { + if (!BinOp) +return; + + int Precedence1 = getPrecedence(BinOp); + int Precedence2 = getPrecedence(ParentBinOp); + + if (ParentBinOp != nullptr && Precedence1 != Precedence2) { +const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); +const clang::SourceLocation EndLoc = +clang::Lexer::getLocForEndOfToken(BinOp->getEndLoc(), 0, SM, LangOpts); + +auto Diag = +Check->diag(StartLoc, +"'%0' has higher precedence than '%1'; add parentheses to " +"explicitly specify the order of operations") +<< (Precedence1 > Precedence2 ? BinOp->getOpcodeStr() + : ParentBinOp->getOpcodeStr()) +<< (Precedence1 > Precedence2 ? ParentBinOp->getOpcodeStr() + : BinOp->getOpcodeStr()); + +Diag << FixItHint::CreateInsertion(StartLoc, "("); +Diag << FixItHint::CreateInsertion(EndLoc, ")"); +Diag << SourceRange(StartLoc, EndLoc); 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/11happy updated https://github.com/llvm/llvm-project/pull/84481 >From 8fdf6306085ed4cf0f77b7e718e374e9f65fedf9 Mon Sep 17 00:00:00 2001 From: 11happy Date: Fri, 8 Mar 2024 19:02:47 +0530 Subject: [PATCH 01/12] add clang-tidy check readability-math-missing-parentheses Signed-off-by: 11happy --- .../clang-tidy/readability/CMakeLists.txt | 1 + .../MathMissingParenthesesCheck.cpp | 167 ++ .../readability/MathMissingParenthesesCheck.h | 31 .../readability/ReadabilityTidyModule.cpp | 3 + clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 1 + .../readability/math-missing-parentheses.rst | 19 ++ .../readability/math-missing-parentheses.cpp | 42 + 8 files changed, 270 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/math-missing-parentheses.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index a6c8cbd8eb448a..0d4fa095501dfb 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -27,6 +27,7 @@ add_clang_library(clangTidyReadabilityModule IsolateDeclarationCheck.cpp MagicNumbersCheck.cpp MakeMemberFunctionConstCheck.cpp + MathMissingParenthesesCheck.cpp MisleadingIndentationCheck.cpp MisplacedArrayIndexCheck.cpp NamedParameterCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp new file mode 100644 index 00..d9574a9fb7a476 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp @@ -0,0 +1,167 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include +#include + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} +static int precedenceCheck(const char op) { + if (op == '/' || op == '*' || op == '%') +return 5; + + else if (op == '+' || op == '-') +return 4; + + else if (op == '&') +return 3; + else if (op == '^') +return 2; + + else if (op == '|') +return 1; + + else +return 0; +} +static bool isOperand(const char c) { + if (c >= 'a' && c <= 'z') +return true; + else if (c >= 'A' && c <= 'Z') +return true; + else if (c >= '0' && c <= '9') +return true; + else if (c == '$') +return true; + else +return false; +} +static bool conditionForNegative(const std::string s, int i, + const std::string CurStr) { + if (CurStr[0] == '-') { +if (i == 0) { + return true; +} else { + while (s[i - 1] == ' ') { +i--; + } + if (!isOperand(s[i - 1])) { +return true; + } else { +return false; + } +} + } else { +return false; + } +} +static std::string getOperationOrder(std::string s, std::set &Operators) { + std::stack StackOne; + std::string TempStr = ""; + for (int i = 0; i < s.length(); i++) { +std::string CurStr = ""; +CurStr += s[i]; +if (CurStr == " ") + continue; +else { + if (isOperand(CurStr[0]) || conditionForNegative(s, i, CurStr)) { +while (i < s.length() && (isOperand(s[i]) || s[i] == '-')) { + if (s[i] == '-') { +TempStr += "$"; + } else { +TempStr += CurStr; + } + i++; + CurStr = s[i]; +} +TempStr += " "; + } else if (CurStr == "(") { +StackOne.push("("); + } else if (CurStr == ")") { +while (StackOne.top() != "(") { + TempStr += StackOne.top(); + StackOne.pop(); +} +StackOne.pop(); + } else { +while (!StackOne.empty() && precedenceCh
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
11happy wrote: Hello @PiotrZSL , I ran it on simple codebases & it looks good. I havent tried it on llvm codebase. it was taking a lot of time on my pc. https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/PiotrZSL approved this pull request. LGTM, Would be good to run it on llvm or any other code base, and check what it found. https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
11happy wrote: Humble reminder! @PiotrZSL https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,97 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +unless(isAssignmentOperator()), +unless(isComparisonOperator()), +unless(hasAnyOperatorName("&&", "||")), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +static int getPrecedence(const BinaryOperator *BinOp) { + if (!BinOp) +return 0; + switch (BinOp->getOpcode()) { + case BO_Mul: + case BO_Div: + case BO_Rem: +return 5; + case BO_Add: + case BO_Sub: +return 4; + case BO_And: +return 3; + case BO_Xor: +return 2; + case BO_Or: +return 1; + default: +return 0; + } +} +static void addParantheses(const BinaryOperator *BinOp, + const BinaryOperator *ParentBinOp, + ClangTidyCheck *Check, + const clang::SourceManager &SM, + const clang::LangOptions &LangOpts) { + if (!BinOp) +return; + + int Precedence1 = getPrecedence(BinOp); + int Precedence2 = getPrecedence(ParentBinOp); + + if (ParentBinOp != nullptr && Precedence1 != Precedence2) { +const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); +const clang::SourceLocation EndLoc = +clang::Lexer::getLocForEndOfToken(BinOp->getEndLoc(), 0, SM, LangOpts); + +auto Diag = +Check->diag(StartLoc, +"'%0' has higher precedence than '%1'; add parentheses to " +"explicitly specify the order of operations") +<< (Precedence1 > Precedence2 ? BinOp->getOpcodeStr() + : ParentBinOp->getOpcodeStr()) +<< (Precedence1 > Precedence2 ? ParentBinOp->getOpcodeStr() + : BinOp->getOpcodeStr()); + +Diag << FixItHint::CreateInsertion(StartLoc, "("); +Diag << FixItHint::CreateInsertion(EndLoc, ")"); +Diag << SourceRange(StartLoc, EndLoc); 5chmidti wrote: Nit: You could stream these directly into the diagnostic, like the operator strings, and remove the `Diag` variable`. https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/5chmidti approved this pull request. LGTM from my side, others are still reviewing. Your test file contains a few trailing whitespaces that you could remove. https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/5chmidti edited https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/11happy updated https://github.com/llvm/llvm-project/pull/84481 >From 8fdf6306085ed4cf0f77b7e718e374e9f65fedf9 Mon Sep 17 00:00:00 2001 From: 11happy Date: Fri, 8 Mar 2024 19:02:47 +0530 Subject: [PATCH 01/11] add clang-tidy check readability-math-missing-parentheses Signed-off-by: 11happy --- .../clang-tidy/readability/CMakeLists.txt | 1 + .../MathMissingParenthesesCheck.cpp | 167 ++ .../readability/MathMissingParenthesesCheck.h | 31 .../readability/ReadabilityTidyModule.cpp | 3 + clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 1 + .../readability/math-missing-parentheses.rst | 19 ++ .../readability/math-missing-parentheses.cpp | 42 + 8 files changed, 270 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/math-missing-parentheses.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index a6c8cbd8eb448a..0d4fa095501dfb 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -27,6 +27,7 @@ add_clang_library(clangTidyReadabilityModule IsolateDeclarationCheck.cpp MagicNumbersCheck.cpp MakeMemberFunctionConstCheck.cpp + MathMissingParenthesesCheck.cpp MisleadingIndentationCheck.cpp MisplacedArrayIndexCheck.cpp NamedParameterCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp new file mode 100644 index 00..d9574a9fb7a476 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp @@ -0,0 +1,167 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include +#include + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} +static int precedenceCheck(const char op) { + if (op == '/' || op == '*' || op == '%') +return 5; + + else if (op == '+' || op == '-') +return 4; + + else if (op == '&') +return 3; + else if (op == '^') +return 2; + + else if (op == '|') +return 1; + + else +return 0; +} +static bool isOperand(const char c) { + if (c >= 'a' && c <= 'z') +return true; + else if (c >= 'A' && c <= 'Z') +return true; + else if (c >= '0' && c <= '9') +return true; + else if (c == '$') +return true; + else +return false; +} +static bool conditionForNegative(const std::string s, int i, + const std::string CurStr) { + if (CurStr[0] == '-') { +if (i == 0) { + return true; +} else { + while (s[i - 1] == ' ') { +i--; + } + if (!isOperand(s[i - 1])) { +return true; + } else { +return false; + } +} + } else { +return false; + } +} +static std::string getOperationOrder(std::string s, std::set &Operators) { + std::stack StackOne; + std::string TempStr = ""; + for (int i = 0; i < s.length(); i++) { +std::string CurStr = ""; +CurStr += s[i]; +if (CurStr == " ") + continue; +else { + if (isOperand(CurStr[0]) || conditionForNegative(s, i, CurStr)) { +while (i < s.length() && (isOperand(s[i]) || s[i] == '-')) { + if (s[i] == '-') { +TempStr += "$"; + } else { +TempStr += CurStr; + } + i++; + CurStr = s[i]; +} +TempStr += " "; + } else if (CurStr == "(") { +StackOne.push("("); + } else if (CurStr == ")") { +while (StackOne.top() != "(") { + TempStr += StackOne.top(); + StackOne.pop(); +} +StackOne.pop(); + } else { +while (!StackOne.empty() && precedenceCh
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/11happy updated https://github.com/llvm/llvm-project/pull/84481 >From 8fdf6306085ed4cf0f77b7e718e374e9f65fedf9 Mon Sep 17 00:00:00 2001 From: 11happy Date: Fri, 8 Mar 2024 19:02:47 +0530 Subject: [PATCH 01/11] add clang-tidy check readability-math-missing-parentheses Signed-off-by: 11happy --- .../clang-tidy/readability/CMakeLists.txt | 1 + .../MathMissingParenthesesCheck.cpp | 167 ++ .../readability/MathMissingParenthesesCheck.h | 31 .../readability/ReadabilityTidyModule.cpp | 3 + clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 1 + .../readability/math-missing-parentheses.rst | 19 ++ .../readability/math-missing-parentheses.cpp | 42 + 8 files changed, 270 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/math-missing-parentheses.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index a6c8cbd8eb448a..0d4fa095501dfb 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -27,6 +27,7 @@ add_clang_library(clangTidyReadabilityModule IsolateDeclarationCheck.cpp MagicNumbersCheck.cpp MakeMemberFunctionConstCheck.cpp + MathMissingParenthesesCheck.cpp MisleadingIndentationCheck.cpp MisplacedArrayIndexCheck.cpp NamedParameterCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp new file mode 100644 index 00..d9574a9fb7a476 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp @@ -0,0 +1,167 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include +#include + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} +static int precedenceCheck(const char op) { + if (op == '/' || op == '*' || op == '%') +return 5; + + else if (op == '+' || op == '-') +return 4; + + else if (op == '&') +return 3; + else if (op == '^') +return 2; + + else if (op == '|') +return 1; + + else +return 0; +} +static bool isOperand(const char c) { + if (c >= 'a' && c <= 'z') +return true; + else if (c >= 'A' && c <= 'Z') +return true; + else if (c >= '0' && c <= '9') +return true; + else if (c == '$') +return true; + else +return false; +} +static bool conditionForNegative(const std::string s, int i, + const std::string CurStr) { + if (CurStr[0] == '-') { +if (i == 0) { + return true; +} else { + while (s[i - 1] == ' ') { +i--; + } + if (!isOperand(s[i - 1])) { +return true; + } else { +return false; + } +} + } else { +return false; + } +} +static std::string getOperationOrder(std::string s, std::set &Operators) { + std::stack StackOne; + std::string TempStr = ""; + for (int i = 0; i < s.length(); i++) { +std::string CurStr = ""; +CurStr += s[i]; +if (CurStr == " ") + continue; +else { + if (isOperand(CurStr[0]) || conditionForNegative(s, i, CurStr)) { +while (i < s.length() && (isOperand(s[i]) || s[i] == '-')) { + if (s[i] == '-') { +TempStr += "$"; + } else { +TempStr += CurStr; + } + i++; + CurStr = s[i]; +} +TempStr += " "; + } else if (CurStr == "(") { +StackOne.push("("); + } else if (CurStr == ")") { +while (StackOne.top() != "(") { + TempStr += StackOne.top(); + StackOne.pop(); +} +StackOne.pop(); + } else { +while (!StackOne.empty() && precedenceCh
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,112 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,81 @@ +// RUN: %check_clang_tidy %s readability-math-missing-parentheses %t + +int foo(){ +return 5; +} + +int bar(){ +return 4; +} + +class fun{ +public: +int A; +double B; +fun(){ +A = 5; +B = 5.4; +} +}; + +void f(){ +//CHECK-MESSAGES: :[[@LINE+2]]:17: warning: '*' has higher precedence than '+'; add parentheses to make the precedence of operations explicit [readability-math-missing-parentheses] +//CHECK-FIXES: int a = 1 + (2 * 3); +int a = 1 + 2 * 3; + +int b = 1 + 2 + 3; // No warning + +int c = 1 * 2 * 3; // No warning + +//CHECK-MESSAGES: :[[@LINE+3]]:17: warning: '*' has higher precedence than '+'; add parentheses to make the precedence of operations explicit [readability-math-missing-parentheses] +//CHECK-MESSAGES: :[[@LINE+2]]:25: warning: '/' has higher precedence than '-'; add parentheses to make the precedence of operations explicit [readability-math-missing-parentheses] +//CHECK-FIXES: int d = 1 + (2 * 3) - (4 / 5); +int d = 1 + 2 * 3 - 4 / 5; 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,112 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +unless(allOf(hasOperatorName("&&"), + hasOperatorName("||"))), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +static int getPrecedence(const BinaryOperator *BinOp) { + if (!BinOp) +return 0; + switch (BinOp->getOpcode()) { + case BO_Mul: + case BO_Div: + case BO_Rem: +return 5; + case BO_Add: + case BO_Sub: +return 4; + case BO_And: +return 3; + case BO_Xor: +return 2; + case BO_Or: +return 1; + default: +return 0; + } +} +static bool addParantheses( +const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp, +std::vector< +std::pair>> +&Insertions, +const clang::SourceManager &SM, const clang::LangOptions &LangOpts) { + bool NeedToDiagnose = false; + if (!BinOp) +return NeedToDiagnose; + + if (ParentBinOp != nullptr && + getPrecedence(BinOp) != getPrecedence(ParentBinOp)) { +NeedToDiagnose = true; +const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); +clang::SourceLocation EndLoc = +clang::Lexer::getLocForEndOfToken(BinOp->getEndLoc(), 0, SM, LangOpts); +Insertions.push_back( +{clang::SourceRange(StartLoc, EndLoc), {BinOp, ParentBinOp}}); + } + + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getLHS()->IgnoreImpCasts()), BinOp, + Insertions, SM, LangOpts); + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getRHS()->IgnoreImpCasts()), BinOp, + Insertions, SM, LangOpts); + return NeedToDiagnose; +} + +void MathMissingParenthesesCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + std::vector< + std::pair>> + Insertions; + const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); + const SourceManager &SM = *Result.SourceManager; + const clang::LangOptions &LO = Result.Context->getLangOpts(); + + if (addParantheses(BinOp, nullptr, Insertions, SM, LO)) { +for (const auto &Insertion : Insertions) { + const clang::BinaryOperator *BinOp1 = Insertion.second.first; + const clang::BinaryOperator *BinOp2 = Insertion.second.second; + + int Precedence1 = getPrecedence(BinOp1); + int Precedence2 = getPrecedence(BinOp2); + + auto Diag = diag(Insertion.first.getBegin(), + "'%0' has higher precedence than '%1'; add parentheses " + "to make the precedence of operations explicit") 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,25 @@ +.. title:: clang-tidy - readability-math-missing-parentheses + +readability-math-missing-parentheses + + +Check for missing parentheses in mathematical expressions that involve operators +of different priorities. Parentheses in mathematical expressions clarify the order 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,112 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +unless(allOf(hasOperatorName("&&"), + hasOperatorName("||"))), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +static int getPrecedence(const BinaryOperator *BinOp) { + if (!BinOp) +return 0; + switch (BinOp->getOpcode()) { + case BO_Mul: + case BO_Div: + case BO_Rem: +return 5; + case BO_Add: + case BO_Sub: +return 4; + case BO_And: +return 3; + case BO_Xor: +return 2; + case BO_Or: +return 1; + default: +return 0; + } +} +static bool addParantheses( +const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp, +std::vector< +std::pair>> +&Insertions, +const clang::SourceManager &SM, const clang::LangOptions &LangOpts) { + bool NeedToDiagnose = false; + if (!BinOp) +return NeedToDiagnose; + + if (ParentBinOp != nullptr && + getPrecedence(BinOp) != getPrecedence(ParentBinOp)) { +NeedToDiagnose = true; +const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); +clang::SourceLocation EndLoc = +clang::Lexer::getLocForEndOfToken(BinOp->getEndLoc(), 0, SM, LangOpts); +Insertions.push_back( +{clang::SourceRange(StartLoc, EndLoc), {BinOp, ParentBinOp}}); 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -129,6 +129,12 @@ New checks Replaces certain conditional statements with equivalent calls to ``std::min`` or ``std::max``. +- New :doc:`readability-math-missing-parentheses 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/11happy updated https://github.com/llvm/llvm-project/pull/84481 >From 8fdf6306085ed4cf0f77b7e718e374e9f65fedf9 Mon Sep 17 00:00:00 2001 From: 11happy Date: Fri, 8 Mar 2024 19:02:47 +0530 Subject: [PATCH 01/10] add clang-tidy check readability-math-missing-parentheses Signed-off-by: 11happy --- .../clang-tidy/readability/CMakeLists.txt | 1 + .../MathMissingParenthesesCheck.cpp | 167 ++ .../readability/MathMissingParenthesesCheck.h | 31 .../readability/ReadabilityTidyModule.cpp | 3 + clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 1 + .../readability/math-missing-parentheses.rst | 19 ++ .../readability/math-missing-parentheses.cpp | 42 + 8 files changed, 270 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/math-missing-parentheses.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index a6c8cbd8eb448a..0d4fa095501dfb 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -27,6 +27,7 @@ add_clang_library(clangTidyReadabilityModule IsolateDeclarationCheck.cpp MagicNumbersCheck.cpp MakeMemberFunctionConstCheck.cpp + MathMissingParenthesesCheck.cpp MisleadingIndentationCheck.cpp MisplacedArrayIndexCheck.cpp NamedParameterCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp new file mode 100644 index 00..d9574a9fb7a476 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp @@ -0,0 +1,167 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include +#include + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} +static int precedenceCheck(const char op) { + if (op == '/' || op == '*' || op == '%') +return 5; + + else if (op == '+' || op == '-') +return 4; + + else if (op == '&') +return 3; + else if (op == '^') +return 2; + + else if (op == '|') +return 1; + + else +return 0; +} +static bool isOperand(const char c) { + if (c >= 'a' && c <= 'z') +return true; + else if (c >= 'A' && c <= 'Z') +return true; + else if (c >= '0' && c <= '9') +return true; + else if (c == '$') +return true; + else +return false; +} +static bool conditionForNegative(const std::string s, int i, + const std::string CurStr) { + if (CurStr[0] == '-') { +if (i == 0) { + return true; +} else { + while (s[i - 1] == ' ') { +i--; + } + if (!isOperand(s[i - 1])) { +return true; + } else { +return false; + } +} + } else { +return false; + } +} +static std::string getOperationOrder(std::string s, std::set &Operators) { + std::stack StackOne; + std::string TempStr = ""; + for (int i = 0; i < s.length(); i++) { +std::string CurStr = ""; +CurStr += s[i]; +if (CurStr == " ") + continue; +else { + if (isOperand(CurStr[0]) || conditionForNegative(s, i, CurStr)) { +while (i < s.length() && (isOperand(s[i]) || s[i] == '-')) { + if (s[i] == '-') { +TempStr += "$"; + } else { +TempStr += CurStr; + } + i++; + CurStr = s[i]; +} +TempStr += " "; + } else if (CurStr == "(") { +StackOne.push("("); + } else if (CurStr == ")") { +while (StackOne.top() != "(") { + TempStr += StackOne.top(); + StackOne.pop(); +} +StackOne.pop(); + } else { +while (!StackOne.empty() && precedenceCh
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,112 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), PiotrZSL wrote: ``` unless(isAssignmentOperator()), unless(isComparisonOperator()), unless(hasAnyOperatorName("&&", "||")) -- ``` ()), https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,112 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +unless(allOf(hasOperatorName("&&"), + hasOperatorName("||"))), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +static int getPrecedence(const BinaryOperator *BinOp) { + if (!BinOp) +return 0; + switch (BinOp->getOpcode()) { + case BO_Mul: + case BO_Div: + case BO_Rem: +return 5; + case BO_Add: + case BO_Sub: +return 4; + case BO_And: +return 3; + case BO_Xor: +return 2; + case BO_Or: +return 1; + default: +return 0; + } +} +static bool addParantheses( +const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp, +std::vector< +std::pair>> +&Insertions, +const clang::SourceManager &SM, const clang::LangOptions &LangOpts) { + bool NeedToDiagnose = false; + if (!BinOp) +return NeedToDiagnose; + + if (ParentBinOp != nullptr && + getPrecedence(BinOp) != getPrecedence(ParentBinOp)) { +NeedToDiagnose = true; +const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); +clang::SourceLocation EndLoc = +clang::Lexer::getLocForEndOfToken(BinOp->getEndLoc(), 0, SM, LangOpts); +Insertions.push_back( +{clang::SourceRange(StartLoc, EndLoc), {BinOp, ParentBinOp}}); + } + + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getLHS()->IgnoreImpCasts()), BinOp, + Insertions, SM, LangOpts); + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getRHS()->IgnoreImpCasts()), BinOp, + Insertions, SM, LangOpts); + return NeedToDiagnose; +} + +void MathMissingParenthesesCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + std::vector< + std::pair>> + Insertions; + const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); + const SourceManager &SM = *Result.SourceManager; + const clang::LangOptions &LO = Result.Context->getLangOpts(); + + if (addParantheses(BinOp, nullptr, Insertions, SM, LO)) { +for (const auto &Insertion : Insertions) { + const clang::BinaryOperator *BinOp1 = Insertion.second.first; + const clang::BinaryOperator *BinOp2 = Insertion.second.second; + + int Precedence1 = getPrecedence(BinOp1); + int Precedence2 = getPrecedence(BinOp2); + + auto Diag = diag(Insertion.first.getBegin(), + "'%0' has higher precedence than '%1'; add parentheses " + "to make the precedence of operations explicit") PiotrZSL wrote: were thinking about this, I thing this will be better: `'%0' has higher precedence than '%1'; add parentheses to explicitly specify the order of operations` https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/PiotrZSL commented: Overall, I like what I see. Just few nits. https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -129,6 +129,12 @@ New checks Replaces certain conditional statements with equivalent calls to ``std::min`` or ``std::max``. +- New :doc:`readability-math-missing-parentheses PiotrZSL wrote: put this before readability-use-std-min-max https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,81 @@ +// RUN: %check_clang_tidy %s readability-math-missing-parentheses %t + +int foo(){ +return 5; +} + +int bar(){ +return 4; +} + +class fun{ +public: +int A; +double B; +fun(){ +A = 5; +B = 5.4; +} +}; + +void f(){ +//CHECK-MESSAGES: :[[@LINE+2]]:17: warning: '*' has higher precedence than '+'; add parentheses to make the precedence of operations explicit [readability-math-missing-parentheses] +//CHECK-FIXES: int a = 1 + (2 * 3); +int a = 1 + 2 * 3; + +int b = 1 + 2 + 3; // No warning + +int c = 1 * 2 * 3; // No warning + +//CHECK-MESSAGES: :[[@LINE+3]]:17: warning: '*' has higher precedence than '+'; add parentheses to make the precedence of operations explicit [readability-math-missing-parentheses] +//CHECK-MESSAGES: :[[@LINE+2]]:25: warning: '/' has higher precedence than '-'; add parentheses to make the precedence of operations explicit [readability-math-missing-parentheses] +//CHECK-FIXES: int d = 1 + (2 * 3) - (4 / 5); +int d = 1 + 2 * 3 - 4 / 5; PiotrZSL wrote: Add more negative tests, like this: `int d_negative = 1 + (2 * 3) - (4 / 5);` Just to check that `()` won't be added if they already exists. https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,25 @@ +.. title:: clang-tidy - readability-math-missing-parentheses + +readability-math-missing-parentheses + + +Check for missing parentheses in mathematical expressions that involve operators +of different priorities. Parentheses in mathematical expressions clarify the order PiotrZSL wrote: add empty line after "priorities." https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/5chmidti edited https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/5chmidti commented: I had an idea to simplify `addParantheses` and `check` a bit, otherwise this looks good. https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,112 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +unless(allOf(hasOperatorName("&&"), + hasOperatorName("||"))), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +static int getPrecedence(const BinaryOperator *BinOp) { + if (!BinOp) +return 0; + switch (BinOp->getOpcode()) { + case BO_Mul: + case BO_Div: + case BO_Rem: +return 5; + case BO_Add: + case BO_Sub: +return 4; + case BO_And: +return 3; + case BO_Xor: +return 2; + case BO_Or: +return 1; + default: +return 0; + } +} +static bool addParantheses( +const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp, +std::vector< +std::pair>> +&Insertions, +const clang::SourceManager &SM, const clang::LangOptions &LangOpts) { + bool NeedToDiagnose = false; + if (!BinOp) +return NeedToDiagnose; + + if (ParentBinOp != nullptr && + getPrecedence(BinOp) != getPrecedence(ParentBinOp)) { +NeedToDiagnose = true; +const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); +clang::SourceLocation EndLoc = +clang::Lexer::getLocForEndOfToken(BinOp->getEndLoc(), 0, SM, LangOpts); +Insertions.push_back( +{clang::SourceRange(StartLoc, EndLoc), {BinOp, ParentBinOp}}); 5chmidti wrote: Instead of filling this vector, you could move emitting the diagnostic itself into this function by passing it the check itself like in https://github.com/llvm/llvm-project/blob/6aa53888a8e8a6e3f0bd279539703f4d4701b4e7/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp#L377-L379 Because whatever you push into the vector will be diagnosed. This would remove the need for the vector and the bool return type. https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,86 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +static int getPrecedence(const BinaryOperator *BinOp) { + if (!BinOp) +return 0; + switch (BinOp->getOpcode()) { + case BO_Mul: + case BO_Div: + case BO_Rem: +return 5; + case BO_Add: + case BO_Sub: +return 4; + case BO_And: +return 3; + case BO_Xor: +return 2; + case BO_Or: +return 1; + default: +return 0; + } +} +static bool addParantheses(const BinaryOperator *BinOp, + const BinaryOperator *ParentBinOp, + std::vector &Insertions) { + bool NeedToDiagnose = false; + if (!BinOp) +return NeedToDiagnose; + + if (ParentBinOp != nullptr && + getPrecedence(BinOp) != getPrecedence(ParentBinOp)) { +NeedToDiagnose = true; +const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); +const clang::SourceLocation EndLoc = BinOp->getEndLoc().getLocWithOffset(1); +Insertions.push_back(clang::SourceRange(StartLoc, EndLoc)); + } + + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getLHS()->IgnoreImpCasts()), BinOp, + Insertions); + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getRHS()->IgnoreImpCasts()), BinOp, + Insertions); + return NeedToDiagnose; +} + +void MathMissingParenthesesCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + std::vector Insertions; + const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); + + if (addParantheses(BinOp, nullptr, Insertions)) { +const auto &Diag = diag( +StartLoc, "add parantheses to clarify the precedence of operations"); 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,86 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +static int getPrecedence(const BinaryOperator *BinOp) { + if (!BinOp) +return 0; + switch (BinOp->getOpcode()) { + case BO_Mul: + case BO_Div: + case BO_Rem: +return 5; + case BO_Add: + case BO_Sub: +return 4; + case BO_And: +return 3; + case BO_Xor: +return 2; + case BO_Or: +return 1; + default: +return 0; + } +} +static bool addParantheses(const BinaryOperator *BinOp, + const BinaryOperator *ParentBinOp, + std::vector &Insertions) { + bool NeedToDiagnose = false; + if (!BinOp) +return NeedToDiagnose; + + if (ParentBinOp != nullptr && + getPrecedence(BinOp) != getPrecedence(ParentBinOp)) { +NeedToDiagnose = true; +const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); +const clang::SourceLocation EndLoc = BinOp->getEndLoc().getLocWithOffset(1); +Insertions.push_back(clang::SourceRange(StartLoc, EndLoc)); + } + + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getLHS()->IgnoreImpCasts()), BinOp, + Insertions); + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getRHS()->IgnoreImpCasts()), BinOp, + Insertions); + return NeedToDiagnose; +} + +void MathMissingParenthesesCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + std::vector Insertions; + const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); + + if (addParantheses(BinOp, nullptr, Insertions)) { +const auto &Diag = diag( 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,86 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +static int getPrecedence(const BinaryOperator *BinOp) { + if (!BinOp) +return 0; + switch (BinOp->getOpcode()) { + case BO_Mul: + case BO_Div: + case BO_Rem: +return 5; + case BO_Add: + case BO_Sub: +return 4; + case BO_And: +return 3; + case BO_Xor: +return 2; + case BO_Or: +return 1; + default: +return 0; + } +} +static bool addParantheses(const BinaryOperator *BinOp, + const BinaryOperator *ParentBinOp, + std::vector &Insertions) { + bool NeedToDiagnose = false; + if (!BinOp) +return NeedToDiagnose; + + if (ParentBinOp != nullptr && + getPrecedence(BinOp) != getPrecedence(ParentBinOp)) { +NeedToDiagnose = true; +const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); +const clang::SourceLocation EndLoc = BinOp->getEndLoc().getLocWithOffset(1); 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/11happy updated https://github.com/llvm/llvm-project/pull/84481 >From 8fdf6306085ed4cf0f77b7e718e374e9f65fedf9 Mon Sep 17 00:00:00 2001 From: 11happy Date: Fri, 8 Mar 2024 19:02:47 +0530 Subject: [PATCH 1/9] add clang-tidy check readability-math-missing-parentheses Signed-off-by: 11happy --- .../clang-tidy/readability/CMakeLists.txt | 1 + .../MathMissingParenthesesCheck.cpp | 167 ++ .../readability/MathMissingParenthesesCheck.h | 31 .../readability/ReadabilityTidyModule.cpp | 3 + clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 1 + .../readability/math-missing-parentheses.rst | 19 ++ .../readability/math-missing-parentheses.cpp | 42 + 8 files changed, 270 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/math-missing-parentheses.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index a6c8cbd8eb448a..0d4fa095501dfb 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -27,6 +27,7 @@ add_clang_library(clangTidyReadabilityModule IsolateDeclarationCheck.cpp MagicNumbersCheck.cpp MakeMemberFunctionConstCheck.cpp + MathMissingParenthesesCheck.cpp MisleadingIndentationCheck.cpp MisplacedArrayIndexCheck.cpp NamedParameterCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp new file mode 100644 index 00..d9574a9fb7a476 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp @@ -0,0 +1,167 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include +#include + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} +static int precedenceCheck(const char op) { + if (op == '/' || op == '*' || op == '%') +return 5; + + else if (op == '+' || op == '-') +return 4; + + else if (op == '&') +return 3; + else if (op == '^') +return 2; + + else if (op == '|') +return 1; + + else +return 0; +} +static bool isOperand(const char c) { + if (c >= 'a' && c <= 'z') +return true; + else if (c >= 'A' && c <= 'Z') +return true; + else if (c >= '0' && c <= '9') +return true; + else if (c == '$') +return true; + else +return false; +} +static bool conditionForNegative(const std::string s, int i, + const std::string CurStr) { + if (CurStr[0] == '-') { +if (i == 0) { + return true; +} else { + while (s[i - 1] == ' ') { +i--; + } + if (!isOperand(s[i - 1])) { +return true; + } else { +return false; + } +} + } else { +return false; + } +} +static std::string getOperationOrder(std::string s, std::set &Operators) { + std::stack StackOne; + std::string TempStr = ""; + for (int i = 0; i < s.length(); i++) { +std::string CurStr = ""; +CurStr += s[i]; +if (CurStr == " ") + continue; +else { + if (isOperand(CurStr[0]) || conditionForNegative(s, i, CurStr)) { +while (i < s.length() && (isOperand(s[i]) || s[i] == '-')) { + if (s[i] == '-') { +TempStr += "$"; + } else { +TempStr += CurStr; + } + i++; + CurStr = s[i]; +} +TempStr += " "; + } else if (CurStr == "(") { +StackOne.push("("); + } else if (CurStr == ")") { +while (StackOne.top() != "(") { + TempStr += StackOne.top(); + StackOne.pop(); +} +StackOne.pop(); + } else { +while (!StackOne.empty() && precedenceCheck
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,31 @@ +//===--- MathMissingParenthesesCheck.h - clang-tidy -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MATHMISSINGPARENTHESESCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MATHMISSINGPARENTHESESCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::readability { + +/// Checks for mathematical expressions that involve operators of different +/// priorities. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/readability/math-missing-parentheses.html +class MathMissingParenthesesCheck : public ClangTidyCheck { +public: + MathMissingParenthesesCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; PiotrZSL wrote: Because now it will generate multiple warnings for template instances, and there will be overlap of fixes. https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,86 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +static int getPrecedence(const BinaryOperator *BinOp) { + if (!BinOp) +return 0; + switch (BinOp->getOpcode()) { + case BO_Mul: + case BO_Div: + case BO_Rem: +return 5; + case BO_Add: + case BO_Sub: +return 4; + case BO_And: +return 3; + case BO_Xor: +return 2; + case BO_Or: +return 1; + default: +return 0; + } +} +static bool addParantheses(const BinaryOperator *BinOp, + const BinaryOperator *ParentBinOp, + std::vector &Insertions) { + bool NeedToDiagnose = false; + if (!BinOp) +return NeedToDiagnose; + + if (ParentBinOp != nullptr && + getPrecedence(BinOp) != getPrecedence(ParentBinOp)) { +NeedToDiagnose = true; +const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); +const clang::SourceLocation EndLoc = BinOp->getEndLoc().getLocWithOffset(1); +Insertions.push_back(clang::SourceRange(StartLoc, EndLoc)); + } + + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getLHS()->IgnoreImpCasts()), BinOp, + Insertions); + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getRHS()->IgnoreImpCasts()), BinOp, + Insertions); + return NeedToDiagnose; +} + +void MathMissingParenthesesCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + std::vector Insertions; + const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); + + if (addParantheses(BinOp, nullptr, Insertions)) { +const auto &Diag = diag( +StartLoc, "add parantheses to clarify the precedence of operations"); PiotrZSL wrote: the reason why i wanted to generate single issue for every operator usage, is because then we could print here information about operators, otherwise developer may not know about what expression message refers. also consider something like: "add parentheses to make the precedence of operations explicit". https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,86 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +static int getPrecedence(const BinaryOperator *BinOp) { + if (!BinOp) +return 0; + switch (BinOp->getOpcode()) { + case BO_Mul: + case BO_Div: + case BO_Rem: +return 5; + case BO_Add: + case BO_Sub: +return 4; + case BO_And: +return 3; + case BO_Xor: +return 2; + case BO_Or: +return 1; + default: +return 0; + } +} +static bool addParantheses(const BinaryOperator *BinOp, + const BinaryOperator *ParentBinOp, + std::vector &Insertions) { + bool NeedToDiagnose = false; + if (!BinOp) +return NeedToDiagnose; + + if (ParentBinOp != nullptr && + getPrecedence(BinOp) != getPrecedence(ParentBinOp)) { +NeedToDiagnose = true; +const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); +const clang::SourceLocation EndLoc = BinOp->getEndLoc().getLocWithOffset(1); +Insertions.push_back(clang::SourceRange(StartLoc, EndLoc)); + } + + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getLHS()->IgnoreImpCasts()), BinOp, + Insertions); + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getRHS()->IgnoreImpCasts()), BinOp, + Insertions); + return NeedToDiagnose; +} + +void MathMissingParenthesesCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + std::vector Insertions; + const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); + + if (addParantheses(BinOp, nullptr, Insertions)) { +const auto &Diag = diag( PiotrZSL wrote: auto Diag https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,86 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +static int getPrecedence(const BinaryOperator *BinOp) { + if (!BinOp) +return 0; + switch (BinOp->getOpcode()) { + case BO_Mul: + case BO_Div: + case BO_Rem: +return 5; + case BO_Add: + case BO_Sub: +return 4; + case BO_And: +return 3; + case BO_Xor: +return 2; + case BO_Or: +return 1; + default: +return 0; + } +} +static bool addParantheses(const BinaryOperator *BinOp, + const BinaryOperator *ParentBinOp, + std::vector &Insertions) { + bool NeedToDiagnose = false; + if (!BinOp) +return NeedToDiagnose; + + if (ParentBinOp != nullptr && + getPrecedence(BinOp) != getPrecedence(ParentBinOp)) { +NeedToDiagnose = true; +const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); +const clang::SourceLocation EndLoc = BinOp->getEndLoc().getLocWithOffset(1); PiotrZSL wrote: this may not be proper EndLoc, get width of token, check utils/SourceManager/Lexer for that, or make sure that SourceRange bellow is an token based range https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include +using namespace std; + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) PiotrZSL wrote: For sure it shouldn't check Or/And, as for those there is compiler warning. https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,25 @@ +.. title:: clang-tidy - readability-math-missing-parentheses + +readability-math-missing-parentheses + + +Check for missing parentheses in mathematical expressions that involve operators +of different priorities. Parentheses in mathematical expressions clarify the order +of operations, especially with different-priority operators. Lengthy or multiline +expressions can obscure this order, leading to coding errors. IDEs can aid clarity +by highlighting parentheses. Explicitly using parentheses also clarify what the 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/11happy updated https://github.com/llvm/llvm-project/pull/84481 >From 8fdf6306085ed4cf0f77b7e718e374e9f65fedf9 Mon Sep 17 00:00:00 2001 From: 11happy Date: Fri, 8 Mar 2024 19:02:47 +0530 Subject: [PATCH 1/8] add clang-tidy check readability-math-missing-parentheses Signed-off-by: 11happy --- .../clang-tidy/readability/CMakeLists.txt | 1 + .../MathMissingParenthesesCheck.cpp | 167 ++ .../readability/MathMissingParenthesesCheck.h | 31 .../readability/ReadabilityTidyModule.cpp | 3 + clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 1 + .../readability/math-missing-parentheses.rst | 19 ++ .../readability/math-missing-parentheses.cpp | 42 + 8 files changed, 270 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/math-missing-parentheses.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index a6c8cbd8eb448a..0d4fa095501dfb 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -27,6 +27,7 @@ add_clang_library(clangTidyReadabilityModule IsolateDeclarationCheck.cpp MagicNumbersCheck.cpp MakeMemberFunctionConstCheck.cpp + MathMissingParenthesesCheck.cpp MisleadingIndentationCheck.cpp MisplacedArrayIndexCheck.cpp NamedParameterCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp new file mode 100644 index 00..d9574a9fb7a476 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp @@ -0,0 +1,167 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include +#include + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} +static int precedenceCheck(const char op) { + if (op == '/' || op == '*' || op == '%') +return 5; + + else if (op == '+' || op == '-') +return 4; + + else if (op == '&') +return 3; + else if (op == '^') +return 2; + + else if (op == '|') +return 1; + + else +return 0; +} +static bool isOperand(const char c) { + if (c >= 'a' && c <= 'z') +return true; + else if (c >= 'A' && c <= 'Z') +return true; + else if (c >= '0' && c <= '9') +return true; + else if (c == '$') +return true; + else +return false; +} +static bool conditionForNegative(const std::string s, int i, + const std::string CurStr) { + if (CurStr[0] == '-') { +if (i == 0) { + return true; +} else { + while (s[i - 1] == ' ') { +i--; + } + if (!isOperand(s[i - 1])) { +return true; + } else { +return false; + } +} + } else { +return false; + } +} +static std::string getOperationOrder(std::string s, std::set &Operators) { + std::stack StackOne; + std::string TempStr = ""; + for (int i = 0; i < s.length(); i++) { +std::string CurStr = ""; +CurStr += s[i]; +if (CurStr == " ") + continue; +else { + if (isOperand(CurStr[0]) || conditionForNegative(s, i, CurStr)) { +while (i < s.length() && (isOperand(s[i]) || s[i] == '-')) { + if (s[i] == '-') { +TempStr += "$"; + } else { +TempStr += CurStr; + } + i++; + CurStr = s[i]; +} +TempStr += " "; + } else if (CurStr == "(") { +StackOne.push("("); + } else if (CurStr == ")") { +while (StackOne.top() != "(") { + TempStr += StackOne.top(); + StackOne.pop(); +} +StackOne.pop(); + } else { +while (!StackOne.empty() && precedenceCheck
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,25 @@ +.. title:: clang-tidy - readability-math-missing-parentheses + +readability-math-missing-parentheses + + +Check for missing parentheses in mathematical expressions that involve operators +of different priorities. Parentheses in mathematical expressions clarify the order +of operations, especially with different-priority operators. Lengthy or multiline +expressions can obscure this order, leading to coding errors. IDEs can aid clarity +by highlighting parentheses. Explicitly using parentheses also clarify what the 5chmidti wrote: Maybe I didn't select the correct lines, given that GitHub shows 4 lines here, my bad. I only meant the second `clarify`, not both. - `Parentheses in mathematical expressions clarify` - `Explicitly using parentheses also clarifies` https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,87 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +static int getPrecedence(const BinaryOperator *BinOp) { + if (!BinOp) +return 0; + switch (BinOp->getOpcode()) { + case BO_Mul: + case BO_Div: + case BO_Rem: +return 5; + case BO_Add: + case BO_Sub: +return 4; + case BO_And: +return 3; + case BO_Xor: +return 2; + case BO_Or: +return 1; + default: +return 0; + } +} +static bool addParantheses(const BinaryOperator *BinOp, + const BinaryOperator *ParentBinOp, + std::vector &Insertions) { + bool NeedToDiagnose = false; + if (!BinOp) +return NeedToDiagnose; + + if (ParentBinOp != nullptr && + getPrecedence(BinOp) != getPrecedence(ParentBinOp)) { +NeedToDiagnose = true; +const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); +const clang::SourceLocation EndLoc = BinOp->getEndLoc().getLocWithOffset(1); +Insertions.push_back(clang::SourceRange(StartLoc, EndLoc)); + } + + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getLHS()->IgnoreImpCasts()), BinOp, + Insertions); + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getRHS()->IgnoreImpCasts()), BinOp, + Insertions); + return NeedToDiagnose; +} + +void MathMissingParenthesesCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + bool NeedToDiagnose = false; 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,87 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +static int getPrecedence(const BinaryOperator *BinOp) { + if (!BinOp) +return 0; + switch (BinOp->getOpcode()) { + case BO_Mul: + case BO_Div: + case BO_Rem: +return 5; + case BO_Add: + case BO_Sub: +return 4; + case BO_And: +return 3; + case BO_Xor: +return 2; + case BO_Or: +return 1; + default: +return 0; + } +} +static bool addParantheses(const BinaryOperator *BinOp, + const BinaryOperator *ParentBinOp, + std::vector &Insertions) { + bool NeedToDiagnose = false; + if (!BinOp) +return NeedToDiagnose; + + if (ParentBinOp != nullptr && + getPrecedence(BinOp) != getPrecedence(ParentBinOp)) { +NeedToDiagnose = true; +const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); +const clang::SourceLocation EndLoc = BinOp->getEndLoc().getLocWithOffset(1); +Insertions.push_back(clang::SourceRange(StartLoc, EndLoc)); + } + + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getLHS()->IgnoreImpCasts()), BinOp, + Insertions); + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getRHS()->IgnoreImpCasts()), BinOp, + Insertions); + return NeedToDiagnose; +} + +void MathMissingParenthesesCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + bool NeedToDiagnose = false; + std::vector Insertions; + const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); + + if (addParantheses(BinOp, nullptr, Insertions)) { +auto const &Diag = diag( 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,87 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +static int getPrecedence(const BinaryOperator *BinOp) { + if (!BinOp) +return 0; + switch (BinOp->getOpcode()) { + case BO_Mul: + case BO_Div: + case BO_Rem: +return 5; + case BO_Add: + case BO_Sub: +return 4; + case BO_And: +return 3; + case BO_Xor: +return 2; + case BO_Or: +return 1; + default: +return 0; + } +} +static bool addParantheses(const BinaryOperator *BinOp, + const BinaryOperator *ParentBinOp, + std::vector &Insertions) { + bool NeedToDiagnose = false; + if (!BinOp) +return NeedToDiagnose; + + if (ParentBinOp != nullptr && + getPrecedence(BinOp) != getPrecedence(ParentBinOp)) { +NeedToDiagnose = true; +const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); +const clang::SourceLocation EndLoc = BinOp->getEndLoc().getLocWithOffset(1); +Insertions.push_back(clang::SourceRange(StartLoc, EndLoc)); + } + + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getLHS()->IgnoreImpCasts()), BinOp, + Insertions); + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getRHS()->IgnoreImpCasts()), BinOp, + Insertions); + return NeedToDiagnose; +} + +void MathMissingParenthesesCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + bool NeedToDiagnose = false; + std::vector Insertions; + const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); + + if (addParantheses(BinOp, nullptr, Insertions)) { +auto const &Diag = diag( +StartLoc, "add parantheses to clarify the precedence of operations"); +for (const auto &Insertion : Insertions) { + Diag << FixItHint::CreateInsertion(Insertion.getBegin(), "("); + Diag << FixItHint::CreateInsertion(Insertion.getEnd(), ")"); + Diag << SourceRange(Insertion.getBegin(), Insertion.getEnd()); 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/11happy updated https://github.com/llvm/llvm-project/pull/84481 >From 8fdf6306085ed4cf0f77b7e718e374e9f65fedf9 Mon Sep 17 00:00:00 2001 From: 11happy Date: Fri, 8 Mar 2024 19:02:47 +0530 Subject: [PATCH 1/7] add clang-tidy check readability-math-missing-parentheses Signed-off-by: 11happy --- .../clang-tidy/readability/CMakeLists.txt | 1 + .../MathMissingParenthesesCheck.cpp | 167 ++ .../readability/MathMissingParenthesesCheck.h | 31 .../readability/ReadabilityTidyModule.cpp | 3 + clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 1 + .../readability/math-missing-parentheses.rst | 19 ++ .../readability/math-missing-parentheses.cpp | 42 + 8 files changed, 270 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/math-missing-parentheses.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index a6c8cbd8eb448a..0d4fa095501dfb 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -27,6 +27,7 @@ add_clang_library(clangTidyReadabilityModule IsolateDeclarationCheck.cpp MagicNumbersCheck.cpp MakeMemberFunctionConstCheck.cpp + MathMissingParenthesesCheck.cpp MisleadingIndentationCheck.cpp MisplacedArrayIndexCheck.cpp NamedParameterCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp new file mode 100644 index 00..d9574a9fb7a476 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp @@ -0,0 +1,167 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include +#include + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} +static int precedenceCheck(const char op) { + if (op == '/' || op == '*' || op == '%') +return 5; + + else if (op == '+' || op == '-') +return 4; + + else if (op == '&') +return 3; + else if (op == '^') +return 2; + + else if (op == '|') +return 1; + + else +return 0; +} +static bool isOperand(const char c) { + if (c >= 'a' && c <= 'z') +return true; + else if (c >= 'A' && c <= 'Z') +return true; + else if (c >= '0' && c <= '9') +return true; + else if (c == '$') +return true; + else +return false; +} +static bool conditionForNegative(const std::string s, int i, + const std::string CurStr) { + if (CurStr[0] == '-') { +if (i == 0) { + return true; +} else { + while (s[i - 1] == ' ') { +i--; + } + if (!isOperand(s[i - 1])) { +return true; + } else { +return false; + } +} + } else { +return false; + } +} +static std::string getOperationOrder(std::string s, std::set &Operators) { + std::stack StackOne; + std::string TempStr = ""; + for (int i = 0; i < s.length(); i++) { +std::string CurStr = ""; +CurStr += s[i]; +if (CurStr == " ") + continue; +else { + if (isOperand(CurStr[0]) || conditionForNegative(s, i, CurStr)) { +while (i < s.length() && (isOperand(s[i]) || s[i] == '-')) { + if (s[i] == '-') { +TempStr += "$"; + } else { +TempStr += CurStr; + } + i++; + CurStr = s[i]; +} +TempStr += " "; + } else if (CurStr == "(") { +StackOne.push("("); + } else if (CurStr == ")") { +while (StackOne.top() != "(") { + TempStr += StackOne.top(); + StackOne.pop(); +} +StackOne.pop(); + } else { +while (!StackOne.empty() && precedenceCheck
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,25 @@ +.. title:: clang-tidy - readability-math-missing-parentheses + +readability-math-missing-parentheses + + +Check for missing parentheses in mathematical expressions that involve operators +of different priorities. Parentheses in mathematical expressions clarify the order +of operations, especially with different-priority operators. Lengthy or multiline +expressions can obscure this order, leading to coding errors. IDEs can aid clarity +by highlighting parentheses. Explicitly using parentheses also clarify what the 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,25 @@ +.. title:: clang-tidy - readability-math-missing-parentheses + +readability-math-missing-parentheses + + +Check for missing parentheses in mathematical expressions that involve operators +of different priorities. Parentheses in mathematical expressions clarify the order +of operations, especially with different-priority operators. Lengthy or multiline +expressions can obscure this order, leading to coding errors. IDEs can aid clarity +by highlighting parentheses. Explicitly using parentheses also clarify what the 5chmidti wrote: `clarifiy` -> `clarifies` https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,87 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +static int getPrecedence(const BinaryOperator *BinOp) { + if (!BinOp) +return 0; + switch (BinOp->getOpcode()) { + case BO_Mul: + case BO_Div: + case BO_Rem: +return 5; + case BO_Add: + case BO_Sub: +return 4; + case BO_And: +return 3; + case BO_Xor: +return 2; + case BO_Or: +return 1; + default: +return 0; + } +} +static bool addParantheses(const BinaryOperator *BinOp, + const BinaryOperator *ParentBinOp, + std::vector &Insertions) { + bool NeedToDiagnose = false; + if (!BinOp) +return NeedToDiagnose; + + if (ParentBinOp != nullptr && + getPrecedence(BinOp) != getPrecedence(ParentBinOp)) { +NeedToDiagnose = true; +const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); +const clang::SourceLocation EndLoc = BinOp->getEndLoc().getLocWithOffset(1); +Insertions.push_back(clang::SourceRange(StartLoc, EndLoc)); + } + + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getLHS()->IgnoreImpCasts()), BinOp, + Insertions); + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getRHS()->IgnoreImpCasts()), BinOp, + Insertions); + return NeedToDiagnose; +} + +void MathMissingParenthesesCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + bool NeedToDiagnose = false; 5chmidti wrote: `NeedToDiagnose` is unused here https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,87 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +static int getPrecedence(const BinaryOperator *BinOp) { + if (!BinOp) +return 0; + switch (BinOp->getOpcode()) { + case BO_Mul: + case BO_Div: + case BO_Rem: +return 5; + case BO_Add: + case BO_Sub: +return 4; + case BO_And: +return 3; + case BO_Xor: +return 2; + case BO_Or: +return 1; + default: +return 0; + } +} +static bool addParantheses(const BinaryOperator *BinOp, + const BinaryOperator *ParentBinOp, + std::vector &Insertions) { + bool NeedToDiagnose = false; + if (!BinOp) +return NeedToDiagnose; + + if (ParentBinOp != nullptr && + getPrecedence(BinOp) != getPrecedence(ParentBinOp)) { +NeedToDiagnose = true; +const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); +const clang::SourceLocation EndLoc = BinOp->getEndLoc().getLocWithOffset(1); +Insertions.push_back(clang::SourceRange(StartLoc, EndLoc)); + } + + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getLHS()->IgnoreImpCasts()), BinOp, + Insertions); + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getRHS()->IgnoreImpCasts()), BinOp, + Insertions); + return NeedToDiagnose; +} + +void MathMissingParenthesesCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + bool NeedToDiagnose = false; + std::vector Insertions; + const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); + + if (addParantheses(BinOp, nullptr, Insertions)) { +auto const &Diag = diag( +StartLoc, "add parantheses to clarify the precedence of operations"); +for (const auto &Insertion : Insertions) { + Diag << FixItHint::CreateInsertion(Insertion.getBegin(), "("); + Diag << FixItHint::CreateInsertion(Insertion.getEnd(), ")"); + Diag << SourceRange(Insertion.getBegin(), Insertion.getEnd()); 5chmidti wrote: You are constructing a `SourceRange` from a `SourceRange` here, please use `Diag << Insertion` instead https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,87 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +static int getPrecedence(const BinaryOperator *BinOp) { + if (!BinOp) +return 0; + switch (BinOp->getOpcode()) { + case BO_Mul: + case BO_Div: + case BO_Rem: +return 5; + case BO_Add: + case BO_Sub: +return 4; + case BO_And: +return 3; + case BO_Xor: +return 2; + case BO_Or: +return 1; + default: +return 0; + } +} +static bool addParantheses(const BinaryOperator *BinOp, + const BinaryOperator *ParentBinOp, + std::vector &Insertions) { + bool NeedToDiagnose = false; + if (!BinOp) +return NeedToDiagnose; + + if (ParentBinOp != nullptr && + getPrecedence(BinOp) != getPrecedence(ParentBinOp)) { +NeedToDiagnose = true; +const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); +const clang::SourceLocation EndLoc = BinOp->getEndLoc().getLocWithOffset(1); +Insertions.push_back(clang::SourceRange(StartLoc, EndLoc)); + } + + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getLHS()->IgnoreImpCasts()), BinOp, + Insertions); + NeedToDiagnose |= addParantheses( + dyn_cast(BinOp->getRHS()->IgnoreImpCasts()), BinOp, + Insertions); + return NeedToDiagnose; +} + +void MathMissingParenthesesCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + bool NeedToDiagnose = false; + std::vector Insertions; + const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); + + if (addParantheses(BinOp, nullptr, Insertions)) { +auto const &Diag = diag( 5chmidti wrote: `auto const` -> `const auto` https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/11happy updated https://github.com/llvm/llvm-project/pull/84481 >From 8fdf6306085ed4cf0f77b7e718e374e9f65fedf9 Mon Sep 17 00:00:00 2001 From: 11happy Date: Fri, 8 Mar 2024 19:02:47 +0530 Subject: [PATCH 1/6] add clang-tidy check readability-math-missing-parentheses Signed-off-by: 11happy --- .../clang-tidy/readability/CMakeLists.txt | 1 + .../MathMissingParenthesesCheck.cpp | 167 ++ .../readability/MathMissingParenthesesCheck.h | 31 .../readability/ReadabilityTidyModule.cpp | 3 + clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 1 + .../readability/math-missing-parentheses.rst | 19 ++ .../readability/math-missing-parentheses.cpp | 42 + 8 files changed, 270 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/math-missing-parentheses.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index a6c8cbd8eb448a..0d4fa095501dfb 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -27,6 +27,7 @@ add_clang_library(clangTidyReadabilityModule IsolateDeclarationCheck.cpp MagicNumbersCheck.cpp MakeMemberFunctionConstCheck.cpp + MathMissingParenthesesCheck.cpp MisleadingIndentationCheck.cpp MisplacedArrayIndexCheck.cpp NamedParameterCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp new file mode 100644 index 00..d9574a9fb7a476 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp @@ -0,0 +1,167 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include +#include + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} +static int precedenceCheck(const char op) { + if (op == '/' || op == '*' || op == '%') +return 5; + + else if (op == '+' || op == '-') +return 4; + + else if (op == '&') +return 3; + else if (op == '^') +return 2; + + else if (op == '|') +return 1; + + else +return 0; +} +static bool isOperand(const char c) { + if (c >= 'a' && c <= 'z') +return true; + else if (c >= 'A' && c <= 'Z') +return true; + else if (c >= '0' && c <= '9') +return true; + else if (c == '$') +return true; + else +return false; +} +static bool conditionForNegative(const std::string s, int i, + const std::string CurStr) { + if (CurStr[0] == '-') { +if (i == 0) { + return true; +} else { + while (s[i - 1] == ' ') { +i--; + } + if (!isOperand(s[i - 1])) { +return true; + } else { +return false; + } +} + } else { +return false; + } +} +static std::string getOperationOrder(std::string s, std::set &Operators) { + std::stack StackOne; + std::string TempStr = ""; + for (int i = 0; i < s.length(); i++) { +std::string CurStr = ""; +CurStr += s[i]; +if (CurStr == " ") + continue; +else { + if (isOperand(CurStr[0]) || conditionForNegative(s, i, CurStr)) { +while (i < s.length() && (isOperand(s[i]) || s[i] == '-')) { + if (s[i] == '-') { +TempStr += "$"; + } else { +TempStr += CurStr; + } + i++; + CurStr = s[i]; +} +TempStr += " "; + } else if (CurStr == "(") { +StackOne.push("("); + } else if (CurStr == ")") { +while (StackOne.top() != "(") { + TempStr += StackOne.top(); + StackOne.pop(); +} +StackOne.pop(); + } else { +while (!StackOne.empty() && precedenceCheck
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
github-actions[bot] wrote: :white_check_mark: With the latest revision this PR passed the C/C++ code formatter. https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
github-actions[bot] wrote: :white_check_mark: With the latest revision this PR passed the Python code formatter. https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/11happy updated https://github.com/llvm/llvm-project/pull/84481 >From 8fdf6306085ed4cf0f77b7e718e374e9f65fedf9 Mon Sep 17 00:00:00 2001 From: 11happy Date: Fri, 8 Mar 2024 19:02:47 +0530 Subject: [PATCH 1/5] add clang-tidy check readability-math-missing-parentheses Signed-off-by: 11happy --- .../clang-tidy/readability/CMakeLists.txt | 1 + .../MathMissingParenthesesCheck.cpp | 167 ++ .../readability/MathMissingParenthesesCheck.h | 31 .../readability/ReadabilityTidyModule.cpp | 3 + clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 1 + .../readability/math-missing-parentheses.rst | 19 ++ .../readability/math-missing-parentheses.cpp | 42 + 8 files changed, 270 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/math-missing-parentheses.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index a6c8cbd8eb448a..0d4fa095501dfb 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -27,6 +27,7 @@ add_clang_library(clangTidyReadabilityModule IsolateDeclarationCheck.cpp MagicNumbersCheck.cpp MakeMemberFunctionConstCheck.cpp + MathMissingParenthesesCheck.cpp MisleadingIndentationCheck.cpp MisplacedArrayIndexCheck.cpp NamedParameterCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp new file mode 100644 index 00..d9574a9fb7a476 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp @@ -0,0 +1,167 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include +#include + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} +static int precedenceCheck(const char op) { + if (op == '/' || op == '*' || op == '%') +return 5; + + else if (op == '+' || op == '-') +return 4; + + else if (op == '&') +return 3; + else if (op == '^') +return 2; + + else if (op == '|') +return 1; + + else +return 0; +} +static bool isOperand(const char c) { + if (c >= 'a' && c <= 'z') +return true; + else if (c >= 'A' && c <= 'Z') +return true; + else if (c >= '0' && c <= '9') +return true; + else if (c == '$') +return true; + else +return false; +} +static bool conditionForNegative(const std::string s, int i, + const std::string CurStr) { + if (CurStr[0] == '-') { +if (i == 0) { + return true; +} else { + while (s[i - 1] == ' ') { +i--; + } + if (!isOperand(s[i - 1])) { +return true; + } else { +return false; + } +} + } else { +return false; + } +} +static std::string getOperationOrder(std::string s, std::set &Operators) { + std::stack StackOne; + std::string TempStr = ""; + for (int i = 0; i < s.length(); i++) { +std::string CurStr = ""; +CurStr += s[i]; +if (CurStr == " ") + continue; +else { + if (isOperand(CurStr[0]) || conditionForNegative(s, i, CurStr)) { +while (i < s.length() && (isOperand(s[i]) || s[i] == '-')) { + if (s[i] == '-') { +TempStr += "$"; + } else { +TempStr += CurStr; + } + i++; + CurStr = s[i]; +} +TempStr += " "; + } else if (CurStr == "(") { +StackOne.push("("); + } else if (CurStr == ")") { +while (StackOne.top() != "(") { + TempStr += StackOne.top(); + StackOne.pop(); +} +StackOne.pop(); + } else { +while (!StackOne.empty() && precedenceCheck
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +void addParantheses( +const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp, +bool &NeedToDiagnose, +std::vector> +&Insertions) { + if (!BinOp) +return; + + if (ParentBinOp != nullptr && + ParentBinOp->getOpcode() != BinOp->getOpcode()) { +NeedToDiagnose = true; + } + const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); + const clang::SourceLocation EndLoc = BinOp->getEndLoc().getLocWithOffset(1); + Insertions.push_back({StartLoc, EndLoc}); + addParantheses(dyn_cast(BinOp->getLHS()->IgnoreImpCasts()), + BinOp, NeedToDiagnose, Insertions); + addParantheses(dyn_cast(BinOp->getRHS()->IgnoreImpCasts()), + BinOp, NeedToDiagnose, Insertions); +} + +void MathMissingParenthesesCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + bool NeedToDiagnose = false; + std::vector> + Insertions; + addParantheses(BinOp, nullptr, NeedToDiagnose, Insertions); + const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); + const clang::SourceLocation EndLoc = BinOp->getEndLoc().getLocWithOffset(1); + const clang::SourceRange range(StartLoc, EndLoc); 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +void addParantheses( +const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp, +bool &NeedToDiagnose, +std::vector> +&Insertions) { + if (!BinOp) +return; + + if (ParentBinOp != nullptr && + ParentBinOp->getOpcode() != BinOp->getOpcode()) { +NeedToDiagnose = true; + } + const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); + const clang::SourceLocation EndLoc = BinOp->getEndLoc().getLocWithOffset(1); + Insertions.push_back({StartLoc, EndLoc}); + addParantheses(dyn_cast(BinOp->getLHS()->IgnoreImpCasts()), + BinOp, NeedToDiagnose, Insertions); + addParantheses(dyn_cast(BinOp->getRHS()->IgnoreImpCasts()), + BinOp, NeedToDiagnose, Insertions); +} + +void MathMissingParenthesesCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + bool NeedToDiagnose = false; + std::vector> + Insertions; + addParantheses(BinOp, nullptr, NeedToDiagnose, Insertions); + const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); + const clang::SourceLocation EndLoc = BinOp->getEndLoc().getLocWithOffset(1); + const clang::SourceRange range(StartLoc, EndLoc); + if (!Insertions.empty()) { +Insertions.erase(Insertions.begin()); + } + if (NeedToDiagnose) { +auto const &Diag = diag( +StartLoc, "add parantheses to clarify the precedence of operations"); +for (const auto &Insertion : Insertions) { + Diag << FixItHint::CreateInsertion(Insertion.first, "("); + Diag << FixItHint::CreateInsertion(Insertion.second, ")"); 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,20 @@ +.. title:: clang-tidy - readability-math-missing-parentheses + +readability-math-missing-parentheses + + +Check for mising parantheses in mathematical expressions that involve operators +of different priorities. + 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,20 @@ +.. title:: clang-tidy - readability-math-missing-parentheses + +readability-math-missing-parentheses + + +Check for mising parantheses in mathematical expressions that involve operators 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,31 @@ +//===--- MathMissingParenthesesCheck.h - clang-tidy -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MATHMISSINGPARENTHESESCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MATHMISSINGPARENTHESESCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::readability { + +/// Checks for mathematical expressions that involve operators of different +/// priorities. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/readability/math-missing-parentheses.html +class MathMissingParenthesesCheck : public ClangTidyCheck { +public: + MathMissingParenthesesCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; 11happy wrote: will it be necessary to add this currently working fine? https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,20 @@ +.. title:: clang-tidy - readability-math-missing-parentheses + +readability-math-missing-parentheses + + +Check for mising parantheses in mathematical expressions that involve operators +of different priorities. + +Before: + +.. code-block:: c++ + + int x = 1 + 2 * 3 - 4 / 5; + + +After: + +.. code-block:: c++ + + int x = (1 + (2 * 3)) - (4 / 5); 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,31 @@ +//===--- MathMissingParenthesesCheck.h - clang-tidy -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MATHMISSINGPARENTHESESCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MATHMISSINGPARENTHESESCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::readability { + +/// Checks for mathematical expressions that involve operators of different +/// priorities. 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +void addParantheses( +const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp, +bool &NeedToDiagnose, +std::vector> +&Insertions) { + if (!BinOp) +return; + + if (ParentBinOp != nullptr && + ParentBinOp->getOpcode() != BinOp->getOpcode()) { +NeedToDiagnose = true; + } 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,76 @@ +// RUN: %check_clang_tidy %s readability-math-missing-parentheses %t + +int foo(){ +return 5; +} + +int bar(){ +return 4; +} + +class fun{ +public: +int A; +double B; +fun(){ +A = 5; +B = 5.4; +} +}; + +void f(){ +//CHECK-MESSAGES: :[[@LINE+2]]:13: warning: add parantheses to clarify the precedence of operations [readability-math-missing-parentheses] +//CHECK-FIXES: int a = 1 + (2 * 3); +int a = 1 + 2 * 3; + +int b = 1 + 2 + 3; // No warning + +int c = 1 * 2 * 3; // No warning + +//CHECK-MESSAGES: :[[@LINE+2]]:13: warning: add parantheses to clarify the precedence of operations [readability-math-missing-parentheses] +//CHECK-FIXES: int d = (1 + (2 * 3)) - (4 / 5); +int d = 1 + 2 * 3 - 4 / 5; 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +void addParantheses( +const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp, +bool &NeedToDiagnose, 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +void addParantheses( +const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp, +bool &NeedToDiagnose, +std::vector> 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/11happy updated https://github.com/llvm/llvm-project/pull/84481 >From 8fdf6306085ed4cf0f77b7e718e374e9f65fedf9 Mon Sep 17 00:00:00 2001 From: 11happy Date: Fri, 8 Mar 2024 19:02:47 +0530 Subject: [PATCH 1/5] add clang-tidy check readability-math-missing-parentheses Signed-off-by: 11happy --- .../clang-tidy/readability/CMakeLists.txt | 1 + .../MathMissingParenthesesCheck.cpp | 167 ++ .../readability/MathMissingParenthesesCheck.h | 31 .../readability/ReadabilityTidyModule.cpp | 3 + clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 1 + .../readability/math-missing-parentheses.rst | 19 ++ .../readability/math-missing-parentheses.cpp | 42 + 8 files changed, 270 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/math-missing-parentheses.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index a6c8cbd8eb448a..0d4fa095501dfb 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -27,6 +27,7 @@ add_clang_library(clangTidyReadabilityModule IsolateDeclarationCheck.cpp MagicNumbersCheck.cpp MakeMemberFunctionConstCheck.cpp + MathMissingParenthesesCheck.cpp MisleadingIndentationCheck.cpp MisplacedArrayIndexCheck.cpp NamedParameterCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp new file mode 100644 index 00..d9574a9fb7a476 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp @@ -0,0 +1,167 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include +#include + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} +static int precedenceCheck(const char op) { + if (op == '/' || op == '*' || op == '%') +return 5; + + else if (op == '+' || op == '-') +return 4; + + else if (op == '&') +return 3; + else if (op == '^') +return 2; + + else if (op == '|') +return 1; + + else +return 0; +} +static bool isOperand(const char c) { + if (c >= 'a' && c <= 'z') +return true; + else if (c >= 'A' && c <= 'Z') +return true; + else if (c >= '0' && c <= '9') +return true; + else if (c == '$') +return true; + else +return false; +} +static bool conditionForNegative(const std::string s, int i, + const std::string CurStr) { + if (CurStr[0] == '-') { +if (i == 0) { + return true; +} else { + while (s[i - 1] == ' ') { +i--; + } + if (!isOperand(s[i - 1])) { +return true; + } else { +return false; + } +} + } else { +return false; + } +} +static std::string getOperationOrder(std::string s, std::set &Operators) { + std::stack StackOne; + std::string TempStr = ""; + for (int i = 0; i < s.length(); i++) { +std::string CurStr = ""; +CurStr += s[i]; +if (CurStr == " ") + continue; +else { + if (isOperand(CurStr[0]) || conditionForNegative(s, i, CurStr)) { +while (i < s.length() && (isOperand(s[i]) || s[i] == '-')) { + if (s[i] == '-') { +TempStr += "$"; + } else { +TempStr += CurStr; + } + i++; + CurStr = s[i]; +} +TempStr += " "; + } else if (CurStr == "(") { +StackOne.push("("); + } else if (CurStr == ")") { +while (StackOne.top() != "(") { + TempStr += StackOne.top(); + StackOne.pop(); +} +StackOne.pop(); + } else { +while (!StackOne.empty() && precedenceCheck
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +void addParantheses( +const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp, +bool &NeedToDiagnose, +std::vector> +&Insertions) { + if (!BinOp) +return; + + if (ParentBinOp != nullptr && + ParentBinOp->getOpcode() != BinOp->getOpcode()) { +NeedToDiagnose = true; + } + const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); + const clang::SourceLocation EndLoc = BinOp->getEndLoc().getLocWithOffset(1); + Insertions.push_back({StartLoc, EndLoc}); + addParantheses(dyn_cast(BinOp->getLHS()->IgnoreImpCasts()), + BinOp, NeedToDiagnose, Insertions); + addParantheses(dyn_cast(BinOp->getRHS()->IgnoreImpCasts()), + BinOp, NeedToDiagnose, Insertions); +} + +void MathMissingParenthesesCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + bool NeedToDiagnose = false; + std::vector> + Insertions; + addParantheses(BinOp, nullptr, NeedToDiagnose, Insertions); + const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); + const clang::SourceLocation EndLoc = BinOp->getEndLoc().getLocWithOffset(1); + const clang::SourceRange range(StartLoc, EndLoc); + if (!Insertions.empty()) { +Insertions.erase(Insertions.begin()); + } + if (NeedToDiagnose) { +auto const &Diag = diag( +StartLoc, "add parantheses to clarify the precedence of operations"); +for (const auto &Insertion : Insertions) { + Diag << FixItHint::CreateInsertion(Insertion.first, "("); + Diag << FixItHint::CreateInsertion(Insertion.second, ")"); 5chmidti wrote: You can stream a range into the diagnostic here, such that the affected operator is underlined. This would also make it easier to find and hit the range in an editor when using clangd. Overlapping operators will just be a single line, and holes in the underline may occur (e.g., 2nd diagnostic). | Without the range | With the range | | --- | --- | | ![image](https://github.com/llvm/llvm-project/assets/44101708/e19e01bb-786d-4c2a-9af7-66f156ca9cc2) | ![image](https://github.com/llvm/llvm-project/assets/44101708/fa758c46-e06d-4215-bd43-b71a3ca78c1c) | The code I used to make the example: `Diag << SourceRange(Insertion.first, Insertion.second);`, and when you change the type that you use to track the insertion locations to a `SourceRange`, like Piotr suggested, then you can just use that (`Diag << Insertion`). https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +void addParantheses( +const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp, +bool &NeedToDiagnose, +std::vector> +&Insertions) { + if (!BinOp) +return; + + if (ParentBinOp != nullptr && + ParentBinOp->getOpcode() != BinOp->getOpcode()) { +NeedToDiagnose = true; + } + const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); + const clang::SourceLocation EndLoc = BinOp->getEndLoc().getLocWithOffset(1); + Insertions.push_back({StartLoc, EndLoc}); + addParantheses(dyn_cast(BinOp->getLHS()->IgnoreImpCasts()), + BinOp, NeedToDiagnose, Insertions); + addParantheses(dyn_cast(BinOp->getRHS()->IgnoreImpCasts()), + BinOp, NeedToDiagnose, Insertions); +} + +void MathMissingParenthesesCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + bool NeedToDiagnose = false; + std::vector> + Insertions; + addParantheses(BinOp, nullptr, NeedToDiagnose, Insertions); + const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); + const clang::SourceLocation EndLoc = BinOp->getEndLoc().getLocWithOffset(1); + const clang::SourceRange range(StartLoc, EndLoc); 5chmidti wrote: `range` and `EndLoc` are unused https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
11happy wrote: > Not bad, still few issues left, mainly with `getOpcode`. Thanks for your review! Update: I will update the PR with the requested changes after 24 as I have mid semester exams from 21-24. https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,31 @@ +//===--- MathMissingParenthesesCheck.h - clang-tidy -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MATHMISSINGPARENTHESESCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MATHMISSINGPARENTHESESCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::readability { + +/// Checks for mathematical expressions that involve operators of different +/// priorities. PiotrZSL wrote: `Check for mising parantheses in mathematical expressions that involve operators of different priorities.` https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +void addParantheses( +const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp, +bool &NeedToDiagnose, +std::vector> PiotrZSL wrote: use SourceRange instead of pair of source locations https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,20 @@ +.. title:: clang-tidy - readability-math-missing-parentheses + +readability-math-missing-parentheses + + +Check for mising parantheses in mathematical expressions that involve operators PiotrZSL wrote: parantheses -> parentheses mising ->missing https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,31 @@ +//===--- MathMissingParenthesesCheck.h - clang-tidy -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MATHMISSINGPARENTHESESCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MATHMISSINGPARENTHESESCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::readability { + +/// Checks for mathematical expressions that involve operators of different +/// priorities. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/readability/math-missing-parentheses.html +class MathMissingParenthesesCheck : public ClangTidyCheck { +public: + MathMissingParenthesesCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; PiotrZSL wrote: consider adding here TK_IgnoreUnlessSpelledInSource, like in other checks, to exclude code that is implicit (like template instances). https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,20 @@ +.. title:: clang-tidy - readability-math-missing-parentheses + +readability-math-missing-parentheses + + +Check for mising parantheses in mathematical expressions that involve operators +of different priorities. + PiotrZSL wrote: Consider adding some longer description, like rationale, for example: _Parentheses in mathematical expressions clarify the order of operations, especially with different-priority operators. Lengthy or multiline expressions can obscure this order, leading to coding errors. IDEs can aid clarity by highlighting parentheses. Explicitly using parentheses also clarify what the developer had in mind when writing the expression. Ensuring their presence reduces ambiguity and errors, promoting clearer and more maintainable code._ https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,76 @@ +// RUN: %check_clang_tidy %s readability-math-missing-parentheses %t + +int foo(){ +return 5; +} + +int bar(){ +return 4; +} + +class fun{ +public: +int A; +double B; +fun(){ +A = 5; +B = 5.4; +} +}; + +void f(){ +//CHECK-MESSAGES: :[[@LINE+2]]:13: warning: add parantheses to clarify the precedence of operations [readability-math-missing-parentheses] +//CHECK-FIXES: int a = 1 + (2 * 3); +int a = 1 + 2 * 3; + +int b = 1 + 2 + 3; // No warning + +int c = 1 * 2 * 3; // No warning + +//CHECK-MESSAGES: :[[@LINE+2]]:13: warning: add parantheses to clarify the precedence of operations [readability-math-missing-parentheses] +//CHECK-FIXES: int d = (1 + (2 * 3)) - (4 / 5); +int d = 1 + 2 * 3 - 4 / 5; PiotrZSL wrote: last () is not needed. Also () are not needed when we got 1 + (2 * 3) - (4 / 5). Simply we got: ``` - + 1 * 2 3 / 4 5 ``` + and - have same priority, no need to put () there. https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +void addParantheses( +const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp, +bool &NeedToDiagnose, +std::vector> +&Insertions) { + if (!BinOp) +return; + + if (ParentBinOp != nullptr && + ParentBinOp->getOpcode() != BinOp->getOpcode()) { +NeedToDiagnose = true; + } PiotrZSL wrote: this is not sufficient, operator priority need to be check, what you had was +- fine `precedenceCheck`, the only problem with that was that you compared strings instead of enum values returned by getOpcode. https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +void addParantheses( +const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp, +bool &NeedToDiagnose, PiotrZSL wrote: use return value instead of in-out argument... https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,20 @@ +.. title:: clang-tidy - readability-math-missing-parentheses + +readability-math-missing-parentheses + + +Check for mising parantheses in mathematical expressions that involve operators +of different priorities. + +Before: + +.. code-block:: c++ + + int x = 1 + 2 * 3 - 4 / 5; + + +After: + +.. code-block:: c++ + + int x = (1 + (2 * 3)) - (4 / 5); PiotrZSL wrote: target should be: `int x = 1 + (2 * 3) - (4 / 5);` same like in example: 1 * 2 / 3 *10 / 23, no parentheses should be inserted. https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/PiotrZSL requested changes to this pull request. Not bad, still few issues left, mainly with `getOpcode`. https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/5chmidti edited https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include +using namespace std; + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) 11happy wrote: I agree with you should be restricted to `+-*/%` https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include +using namespace std; 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include +using namespace std; + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +void addParantheses(const BinaryOperator *BinOp, clang::Rewriter &Rewrite, +const BinaryOperator *ParentBinOp, bool &NeedToDiagnose) { + if (!BinOp) +return; + if (ParentBinOp != nullptr && + ParentBinOp->getOpcode() != BinOp->getOpcode()) { +NeedToDiagnose = true; + } + clang::SourceLocation StartLoc = BinOp->getLHS()->getBeginLoc(); + clang::SourceLocation EndLoc = BinOp->getRHS()->getEndLoc(); 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include +using namespace std; + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +void addParantheses(const BinaryOperator *BinOp, clang::Rewriter &Rewrite, +const BinaryOperator *ParentBinOp, bool &NeedToDiagnose) { + if (!BinOp) +return; + if (ParentBinOp != nullptr && + ParentBinOp->getOpcode() != BinOp->getOpcode()) { +NeedToDiagnose = true; + } + clang::SourceLocation StartLoc = BinOp->getLHS()->getBeginLoc(); + clang::SourceLocation EndLoc = BinOp->getRHS()->getEndLoc(); + Rewrite.InsertText(StartLoc, "("); + Rewrite.InsertTextAfterToken(EndLoc, ")"); + addParantheses(dyn_cast(BinOp->getLHS()), Rewrite, BinOp, + NeedToDiagnose); + addParantheses(dyn_cast(BinOp->getRHS()), Rewrite, BinOp, + NeedToDiagnose); 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,74 @@ +// RUN: %check_clang_tidy %s readability-math-missing-parentheses %t + +// FIXME: Add something that triggers the check here. + +int foo(){ +return 5; +} + +int bar(){ +return 4; +} + +class fun{ +public: +int A; +double B; +fun(){ +A = 5; +B = 5.4; +} +}; + +void f(){ +//CHECK-MESSAGES: :[[@LINE+2]]:13: warning: add parantheses to clarify the precedence of operations [readability-math-missing-parentheses] +//CHECK-FIXES: int a = (1 + (2 * 3)); +int a = 1 + 2 * 3; + +int b = 1 + 2 + 3; // No warning + +int c = 1 * 2 * 3; // No warning + +//CHECK-MESSAGES: :[[@LINE+2]]:13: warning: add parantheses to clarify the precedence of operations [readability-math-missing-parentheses] +//CHECK-FIXES: int d = ((1 + (2 * 3)) - (4 / 5)); +int d = 1 + 2 * 3 - 4 / 5; + +//CHECK-MESSAGES: :[[@LINE+2]]:13: warning: add parantheses to clarify the precedence of operations [readability-math-missing-parentheses] +//CHECK-FIXES: int e = ((1 & (2 + 3)) | (4 * 5)); +int e = 1 & 2 + 3 | 4 * 5; + +//CHECK-MESSAGES: :[[@LINE+2]]:13: warning: add parantheses to clarify the precedence of operations [readability-math-missing-parentheses] +//CHECK-FIXES: int f = ((1 * -2) + 4); +int f = 1 * -2 + 4; + +//CHECK-MESSAGES: :[[@LINE+2]]:13: warning: add parantheses to clarify the precedence of operations [readability-math-missing-parentheses] +//CHECK-FIXES: int g = 1 * 2) * 3) + 4) + 5); +int g = 1 * 2 * 3 + 4 + 5; + +// CHECK-MESSAGES: :[[@LINE+2]]:13: warning: add parantheses to clarify the precedence of operations [readability-math-missing-parentheses] +// CHECK-FIXES: int h = ((120 & (2 + 3)) | (22 * 5)); +int h = 120 & 2 + 3 | 22 * 5; + +int i = 1 & 2 & 3; // No warning + +int j = 1 | 2 | 3; // No warning + +int k = 1 ^ 2 ^ 3; // No warning + +// CHECK-MESSAGES: :[[@LINE+2]]:13: warning: add parantheses to clarify the precedence of operations [readability-math-missing-parentheses] +// CHECK-FIXES: int l = ((1 + 2) ^ 3); +int l = 1 + 2 ^ 3; + +// CHECK-MESSAGES: :[[@LINE+2]]:13: warning: add parantheses to clarify the precedence of operations [readability-math-missing-parentheses] +// CHECK-FIXES: int m = ((2 * foo()) + bar()); +int m = 2 * foo() + bar(); + +// CHECK-MESSAGES: :[[@LINE+2]]:13: warning: add parantheses to clarify the precedence of operations [readability-math-missing-parentheses] +// CHECK-FIXES: int n = ((1.05 * foo()) + double(bar())); +int n = 1.05 * foo() + double(bar()); + +// CHECK-MESSAGES: :[[@LINE+3]]:13: warning: add parantheses to clarify the precedence of operations [readability-math-missing-parentheses] +// CHECK-FIXES: int o = (1 + (obj.A * 3)) + obj.B; +fun obj; +int o = 1 + obj.A * 3 + obj.B; +} 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include +using namespace std; + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +void addParantheses(const BinaryOperator *BinOp, clang::Rewriter &Rewrite, +const BinaryOperator *ParentBinOp, bool &NeedToDiagnose) { + if (!BinOp) +return; + if (ParentBinOp != nullptr && + ParentBinOp->getOpcode() != BinOp->getOpcode()) { +NeedToDiagnose = true; + } + clang::SourceLocation StartLoc = BinOp->getLHS()->getBeginLoc(); + clang::SourceLocation EndLoc = BinOp->getRHS()->getEndLoc(); + Rewrite.InsertText(StartLoc, "("); + Rewrite.InsertTextAfterToken(EndLoc, ")"); + addParantheses(dyn_cast(BinOp->getLHS()), Rewrite, BinOp, + NeedToDiagnose); + addParantheses(dyn_cast(BinOp->getRHS()), Rewrite, BinOp, + NeedToDiagnose); +} + +void MathMissingParenthesesCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + if (!BinOp) +return; 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,19 @@ +.. title:: clang-tidy - readability-math-missing-parentheses + +readability-math-missing-parentheses + + +Checks for mathematical expressions that involve operators of different priorities. 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include +using namespace std; + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +void addParantheses(const BinaryOperator *BinOp, clang::Rewriter &Rewrite, +const BinaryOperator *ParentBinOp, bool &NeedToDiagnose) { + if (!BinOp) +return; + if (ParentBinOp != nullptr && + ParentBinOp->getOpcode() != BinOp->getOpcode()) { +NeedToDiagnose = true; + } + clang::SourceLocation StartLoc = BinOp->getLHS()->getBeginLoc(); + clang::SourceLocation EndLoc = BinOp->getRHS()->getEndLoc(); + Rewrite.InsertText(StartLoc, "("); + Rewrite.InsertTextAfterToken(EndLoc, ")"); + addParantheses(dyn_cast(BinOp->getLHS()), Rewrite, BinOp, + NeedToDiagnose); + addParantheses(dyn_cast(BinOp->getRHS()), Rewrite, BinOp, + NeedToDiagnose); +} + +void MathMissingParenthesesCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + if (!BinOp) +return; + clang::SourceManager &SM = *Result.SourceManager; + clang::LangOptions LO = Result.Context->getLangOpts(); 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include +using namespace std; + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +void addParantheses(const BinaryOperator *BinOp, clang::Rewriter &Rewrite, +const BinaryOperator *ParentBinOp, bool &NeedToDiagnose) { + if (!BinOp) +return; + if (ParentBinOp != nullptr && + ParentBinOp->getOpcode() != BinOp->getOpcode()) { +NeedToDiagnose = true; + } + clang::SourceLocation StartLoc = BinOp->getLHS()->getBeginLoc(); + clang::SourceLocation EndLoc = BinOp->getRHS()->getEndLoc(); + Rewrite.InsertText(StartLoc, "("); + Rewrite.InsertTextAfterToken(EndLoc, ")"); + addParantheses(dyn_cast(BinOp->getLHS()), Rewrite, BinOp, + NeedToDiagnose); + addParantheses(dyn_cast(BinOp->getRHS()), Rewrite, BinOp, + NeedToDiagnose); +} + +void MathMissingParenthesesCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + if (!BinOp) +return; + clang::SourceManager &SM = *Result.SourceManager; + clang::LangOptions LO = Result.Context->getLangOpts(); + Rewriter Rewrite(SM, LO); + bool NeedToDiagnose = false; + addParantheses(BinOp, Rewrite, nullptr, NeedToDiagnose); + clang::SourceLocation StartLoc = BinOp->getLHS()->getBeginLoc(); + clang::SourceLocation EndLoc = + BinOp->getRHS()->getEndLoc().getLocWithOffset(1); 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,74 @@ +// RUN: %check_clang_tidy %s readability-math-missing-parentheses %t + +// FIXME: Add something that triggers the check here. 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
@@ -0,0 +1,68 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include +using namespace std; + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +void addParantheses(const BinaryOperator *BinOp, clang::Rewriter &Rewrite, +const BinaryOperator *ParentBinOp, bool &NeedToDiagnose) { + if (!BinOp) +return; + if (ParentBinOp != nullptr && + ParentBinOp->getOpcode() != BinOp->getOpcode()) { +NeedToDiagnose = true; + } + clang::SourceLocation StartLoc = BinOp->getLHS()->getBeginLoc(); + clang::SourceLocation EndLoc = BinOp->getRHS()->getEndLoc(); + Rewrite.InsertText(StartLoc, "("); + Rewrite.InsertTextAfterToken(EndLoc, ")"); + addParantheses(dyn_cast(BinOp->getLHS()), Rewrite, BinOp, + NeedToDiagnose); + addParantheses(dyn_cast(BinOp->getRHS()), Rewrite, BinOp, + NeedToDiagnose); +} + +void MathMissingParenthesesCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + if (!BinOp) +return; + clang::SourceManager &SM = *Result.SourceManager; + clang::LangOptions LO = Result.Context->getLangOpts(); + Rewriter Rewrite(SM, LO); + bool NeedToDiagnose = false; + addParantheses(BinOp, Rewrite, nullptr, NeedToDiagnose); + clang::SourceLocation StartLoc = BinOp->getLHS()->getBeginLoc(); + clang::SourceLocation EndLoc = + BinOp->getRHS()->getEndLoc().getLocWithOffset(1); + clang::SourceRange range(StartLoc, EndLoc); + std::string NewExpression = Rewrite.getRewrittenText(range); + if (NeedToDiagnose) { +diag(StartLoc, "add parantheses to clarify the precedence of operations") +<< FixItHint::CreateReplacement(range, NewExpression); 11happy wrote: done https://github.com/llvm/llvm-project/pull/84481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)
https://github.com/11happy updated https://github.com/llvm/llvm-project/pull/84481 >From 8fdf6306085ed4cf0f77b7e718e374e9f65fedf9 Mon Sep 17 00:00:00 2001 From: 11happy Date: Fri, 8 Mar 2024 19:02:47 +0530 Subject: [PATCH 1/4] add clang-tidy check readability-math-missing-parentheses Signed-off-by: 11happy --- .../clang-tidy/readability/CMakeLists.txt | 1 + .../MathMissingParenthesesCheck.cpp | 167 ++ .../readability/MathMissingParenthesesCheck.h | 31 .../readability/ReadabilityTidyModule.cpp | 3 + clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 1 + .../readability/math-missing-parentheses.rst | 19 ++ .../readability/math-missing-parentheses.cpp | 42 + 8 files changed, 270 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/math-missing-parentheses.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index a6c8cbd8eb448a..0d4fa095501dfb 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -27,6 +27,7 @@ add_clang_library(clangTidyReadabilityModule IsolateDeclarationCheck.cpp MagicNumbersCheck.cpp MakeMemberFunctionConstCheck.cpp + MathMissingParenthesesCheck.cpp MisleadingIndentationCheck.cpp MisplacedArrayIndexCheck.cpp NamedParameterCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp new file mode 100644 index 00..d9574a9fb7a476 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp @@ -0,0 +1,167 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MathMissingParenthesesCheck.h" +#include "../utils/ASTUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" +#include +#include + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), +hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} +static int precedenceCheck(const char op) { + if (op == '/' || op == '*' || op == '%') +return 5; + + else if (op == '+' || op == '-') +return 4; + + else if (op == '&') +return 3; + else if (op == '^') +return 2; + + else if (op == '|') +return 1; + + else +return 0; +} +static bool isOperand(const char c) { + if (c >= 'a' && c <= 'z') +return true; + else if (c >= 'A' && c <= 'Z') +return true; + else if (c >= '0' && c <= '9') +return true; + else if (c == '$') +return true; + else +return false; +} +static bool conditionForNegative(const std::string s, int i, + const std::string CurStr) { + if (CurStr[0] == '-') { +if (i == 0) { + return true; +} else { + while (s[i - 1] == ' ') { +i--; + } + if (!isOperand(s[i - 1])) { +return true; + } else { +return false; + } +} + } else { +return false; + } +} +static std::string getOperationOrder(std::string s, std::set &Operators) { + std::stack StackOne; + std::string TempStr = ""; + for (int i = 0; i < s.length(); i++) { +std::string CurStr = ""; +CurStr += s[i]; +if (CurStr == " ") + continue; +else { + if (isOperand(CurStr[0]) || conditionForNegative(s, i, CurStr)) { +while (i < s.length() && (isOperand(s[i]) || s[i] == '-')) { + if (s[i] == '-') { +TempStr += "$"; + } else { +TempStr += CurStr; + } + i++; + CurStr = s[i]; +} +TempStr += " "; + } else if (CurStr == "(") { +StackOne.push("("); + } else if (CurStr == ")") { +while (StackOne.top() != "(") { + TempStr += StackOne.top(); + StackOne.pop(); +} +StackOne.pop(); + } else { +while (!StackOne.empty() && precedenceCheck