[clang] Match against all plugins when parsing microsoft attributes (PR #86426)
https://github.com/apache-hb created https://github.com/llvm/llvm-project/pull/86426 Fixes #86422 >From 245a21512d8658225b17b91b8af4764f54084e01 Mon Sep 17 00:00:00 2001 From: Elliot <35050275+apache...@users.noreply.github.com> Date: Sun, 24 Mar 2024 03:03:47 -0400 Subject: [PATCH] Match against all plugins when parsing microsoft attributes fixes #86422 --- clang/lib/Parse/ParseDeclCXX.cpp | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 63fe678cbb29e2..d05b3a455f7f63 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -5061,11 +5061,12 @@ void Parser::ParseMicrosoftAttributes(ParsedAttributes &Attrs) { IdentifierInfo *II = Tok.getIdentifierInfo(); SourceLocation NameLoc = Tok.getLocation(); ConsumeToken(); -ParsedAttr::Kind AttrKind = -ParsedAttr::getParsedKind(II, nullptr, ParsedAttr::AS_Microsoft); + // For HLSL we want to handle all attributes, but for MSVC compat, we // silently ignore unknown Microsoft attributes. -if (getLangOpts().HLSL || AttrKind != ParsedAttr::UnknownAttribute) { +AttributeCommonInfo Info{II, NameLoc, AttributeCommonInfo::Form::Microsoft()}; +const ParsedAttrInfo& AttrInfo = ParsedAttrInfo::get(Info); +if (getLangOpts().HLSL || AttrInfo.hasSpelling(AttributeCommonInfo::AS_Microsoft, II->getName())) { bool AttrParsed = false; if (Tok.is(tok::l_paren)) { CachedTokens OpenMPTokens; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Match against all plugins when parsing microsoft attributes (PR #86426)
github-actions[bot] wrote: Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using `@` followed by their GitHub username. If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the [LLVM GitHub User Guide](https://llvm.org/docs/GitHub.html). You can also ask questions in a comment on this PR, on the [LLVM Discord](https://discord.com/invite/xS7Z362) or on the [forums](https://discourse.llvm.org/). https://github.com/llvm/llvm-project/pull/86426 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Match against all plugins when parsing microsoft attributes (PR #86426)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Elliot (apache-hb) Changes Fixes #86422 --- Full diff: https://github.com/llvm/llvm-project/pull/86426.diff 1 Files Affected: - (modified) clang/lib/Parse/ParseDeclCXX.cpp (+4-3) ``diff diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 63fe678cbb29e2..d05b3a455f7f63 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -5061,11 +5061,12 @@ void Parser::ParseMicrosoftAttributes(ParsedAttributes &Attrs) { IdentifierInfo *II = Tok.getIdentifierInfo(); SourceLocation NameLoc = Tok.getLocation(); ConsumeToken(); -ParsedAttr::Kind AttrKind = -ParsedAttr::getParsedKind(II, nullptr, ParsedAttr::AS_Microsoft); + // For HLSL we want to handle all attributes, but for MSVC compat, we // silently ignore unknown Microsoft attributes. -if (getLangOpts().HLSL || AttrKind != ParsedAttr::UnknownAttribute) { +AttributeCommonInfo Info{II, NameLoc, AttributeCommonInfo::Form::Microsoft()}; +const ParsedAttrInfo& AttrInfo = ParsedAttrInfo::get(Info); +if (getLangOpts().HLSL || AttrInfo.hasSpelling(AttributeCommonInfo::AS_Microsoft, II->getName())) { bool AttrParsed = false; if (Tok.is(tok::l_paren)) { CachedTokens OpenMPTokens; `` https://github.com/llvm/llvm-project/pull/86426 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Match against all plugins when parsing microsoft attributes (PR #86426)
github-actions[bot] wrote: ⚠️ We detected that you are using a GitHub private e-mail address to contribute to the repo. Please turn off [Keep my email addresses private](https://github.com/settings/emails) setting in your account. See [LLVM Discourse](https://discourse.llvm.org/t/hidden-emails-on-github-should-we-do-something-about-it) for more information. https://github.com/llvm/llvm-project/pull/86426 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Match against all plugins when parsing microsoft attributes (PR #86426)
https://github.com/apache-hb updated https://github.com/llvm/llvm-project/pull/86426 >From 245a21512d8658225b17b91b8af4764f54084e01 Mon Sep 17 00:00:00 2001 From: Elliot <35050275+apache...@users.noreply.github.com> Date: Sun, 24 Mar 2024 03:03:47 -0400 Subject: [PATCH 1/2] Match against all plugins when parsing microsoft attributes fixes #86422 --- clang/lib/Parse/ParseDeclCXX.cpp | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 63fe678cbb29e2..d05b3a455f7f63 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -5061,11 +5061,12 @@ void Parser::ParseMicrosoftAttributes(ParsedAttributes &Attrs) { IdentifierInfo *II = Tok.getIdentifierInfo(); SourceLocation NameLoc = Tok.getLocation(); ConsumeToken(); -ParsedAttr::Kind AttrKind = -ParsedAttr::getParsedKind(II, nullptr, ParsedAttr::AS_Microsoft); + // For HLSL we want to handle all attributes, but for MSVC compat, we // silently ignore unknown Microsoft attributes. -if (getLangOpts().HLSL || AttrKind != ParsedAttr::UnknownAttribute) { +AttributeCommonInfo Info{II, NameLoc, AttributeCommonInfo::Form::Microsoft()}; +const ParsedAttrInfo& AttrInfo = ParsedAttrInfo::get(Info); +if (getLangOpts().HLSL || AttrInfo.hasSpelling(AttributeCommonInfo::AS_Microsoft, II->getName())) { bool AttrParsed = false; if (Tok.is(tok::l_paren)) { CachedTokens OpenMPTokens; >From 4e47899a9fb17dec5931007b5025f6ce97dbe3eb Mon Sep 17 00:00:00 2001 From: Elliot <35050275+apache...@users.noreply.github.com> Date: Sun, 24 Mar 2024 03:05:54 -0400 Subject: [PATCH 2/2] Apply formatting --- clang/lib/Parse/ParseDeclCXX.cpp | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index d05b3a455f7f63..856ac11f7bb839 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -5064,9 +5064,12 @@ void Parser::ParseMicrosoftAttributes(ParsedAttributes &Attrs) { // For HLSL we want to handle all attributes, but for MSVC compat, we // silently ignore unknown Microsoft attributes. -AttributeCommonInfo Info{II, NameLoc, AttributeCommonInfo::Form::Microsoft()}; -const ParsedAttrInfo& AttrInfo = ParsedAttrInfo::get(Info); -if (getLangOpts().HLSL || AttrInfo.hasSpelling(AttributeCommonInfo::AS_Microsoft, II->getName())) { +AttributeCommonInfo Info{II, NameLoc, + AttributeCommonInfo::Form::Microsoft()}; +const ParsedAttrInfo &AttrInfo = ParsedAttrInfo::get(Info); +if (getLangOpts().HLSL || +AttrInfo.hasSpelling(AttributeCommonInfo::AS_Microsoft, + II->getName())) { bool AttrParsed = false; if (Tok.is(tok::l_paren)) { CachedTokens OpenMPTokens; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][analyzer] add documentation for optin performance padding (padding checker) #73675 (PR #86411)
@@ -804,10 +804,28 @@ Check for performance anti-patterns when using Grand Central Dispatch. .. _optin-performance-Padding: -optin.performance.Padding -" +optin.performance.Padding (PaddingChecker) +""" Check for excessively padded structs. +.. code-block:: objc + + struct TestStruct { + int data1; // 4 bytes + char data2; // 1 byte + char padding[27]; // 27 bytes of padding +}; // Total size: 32 bytes + + void TestFunction() { steakhal wrote: All lines in the example block should be indented nicely in a consistent manner. As of now, the indentation level varies. https://github.com/llvm/llvm-project/pull/86411 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][analyzer] add documentation for optin performance padding (padding checker) #73675 (PR #86411)
https://github.com/steakhal requested changes to this pull request. The docs should also explain why is a problem to have padding bytes, and how to fix it. How does the generated html look like after your change for this file? (Have a look at my commits to this or to the releasenotes file for clang to see what commands to run to generate it) Does the checker have any limitations? Why is it even implemented in CSA? https://github.com/llvm/llvm-project/pull/86411 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][analyzer] add documentation for optin performance padding (padding checker) #73675 (PR #86411)
@@ -804,10 +804,28 @@ Check for performance anti-patterns when using Grand Central Dispatch. .. _optin-performance-Padding: -optin.performance.Padding -" +optin.performance.Padding (PaddingChecker) +""" Check for excessively padded structs. +.. code-block:: objc steakhal wrote: This code is rather c. https://github.com/llvm/llvm-project/pull/86411 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][analyzer] add documentation for optin performance padding (padding checker) #73675 (PR #86411)
@@ -804,10 +804,28 @@ Check for performance anti-patterns when using Grand Central Dispatch. .. _optin-performance-Padding: -optin.performance.Padding -" +optin.performance.Padding (PaddingChecker) +""" steakhal wrote: This line should be aligned with the line above. https://github.com/llvm/llvm-project/pull/86411 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][analyzer] add documentation for optin performance padding (padding checker) #73675 (PR #86411)
@@ -804,10 +804,28 @@ Check for performance anti-patterns when using Grand Central Dispatch. .. _optin-performance-Padding: -optin.performance.Padding -" +optin.performance.Padding (PaddingChecker) steakhal wrote: It should be the languages within the parens, that the checker supports. I think this checker applies for C, C++ and probably even for ObjC as well. https://github.com/llvm/llvm-project/pull/86411 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][analyzer] add documentation for optin performance padding (padding checker) #73675 (PR #86411)
@@ -804,10 +804,28 @@ Check for performance anti-patterns when using Grand Central Dispatch. .. _optin-performance-Padding: -optin.performance.Padding -" +optin.performance.Padding (PaddingChecker) +""" Check for excessively padded structs. +.. code-block:: objc + + struct TestStruct { + int data1; // 4 bytes + char data2; // 1 byte + char padding[27]; // 27 bytes of padding +}; // Total size: 32 bytes + + void TestFunction() { + struct TestStruct struct1; // Warning is generated due to excessive padding. +} + + // Reports are only generated if the excessive padding exceeds 'AllowedPad' in bytes. + + // AllowedPad: Default Value: 24 bytes + + Usage: `AllowedPad=` steakhal wrote: In other places we use double backticks. Why do you use one where? https://github.com/llvm/llvm-project/pull/86411 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][analyzer] add documentation for optin performance padding (padding checker) #73675 (PR #86411)
@@ -804,10 +804,28 @@ Check for performance anti-patterns when using Grand Central Dispatch. .. _optin-performance-Padding: -optin.performance.Padding -" +optin.performance.Padding (PaddingChecker) +""" Check for excessively padded structs. +.. code-block:: objc + + struct TestStruct { + int data1; // 4 bytes + char data2; // 1 byte + char padding[27]; // 27 bytes of padding steakhal wrote: This is a field, thus it shouldn't be counted as padding. https://github.com/llvm/llvm-project/pull/86411 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][analyzer] add documentation for optin performance padding (padding checker) #73675 (PR #86411)
https://github.com/steakhal edited https://github.com/llvm/llvm-project/pull/86411 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][analyzer] add documentation for optin performance padding (padding checker) #73675 (PR #86411)
https://github.com/steakhal edited https://github.com/llvm/llvm-project/pull/86411 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][analyzer] add documentation for optin performance padding (padding checker) #73675 (PR #86411)
https://github.com/steakhal edited https://github.com/llvm/llvm-project/pull/86411 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Comments] Add argument parsing for @throw @throws @exception (PR #84726)
https://github.com/hdoc updated https://github.com/llvm/llvm-project/pull/84726 >From ec3f444913d9162de4494cdb09b336b1b00380fa Mon Sep 17 00:00:00 2001 From: hdoc Date: Mon, 11 Mar 2024 01:13:25 -0700 Subject: [PATCH 1/5] Comment parsing: add argument parsing for @throw @throws @exception Doxygen allows for the @throw, @throws, and @exception commands to have an attached argument indicating the type being thrown. Currently, Clang's AST parsing doesn't support parsing out this argument from doc comments. The result is missing compatibility with Doxygen. We would find it helpful if the AST exposed these thrown types as BlockCommandComment arguments so that we could generate better documentation. This PR implements parsing of arguments for the @throw, @throws, and @exception commands. Each command can only have one argument, matching the semantics of Doxygen. We have also added unit tests to validate the functionality. --- clang/include/clang/AST/CommentCommands.td | 6 +- clang/include/clang/AST/CommentParser.h| 3 + clang/lib/AST/CommentParser.cpp| 133 clang/unittests/AST/CommentParser.cpp | 235 - 4 files changed, 373 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/AST/CommentCommands.td b/clang/include/clang/AST/CommentCommands.td index e839031752cdd8..06b2fa9b5531c6 100644 --- a/clang/include/clang/AST/CommentCommands.td +++ b/clang/include/clang/AST/CommentCommands.td @@ -132,9 +132,9 @@ def Tparam : BlockCommand<"tparam"> { let IsTParamCommand = 1; } // HeaderDoc command for template parameter documentation. def Templatefield : BlockCommand<"templatefield"> { let IsTParamCommand = 1; } -def Throws: BlockCommand<"throws"> { let IsThrowsCommand = 1; } -def Throw : BlockCommand<"throw"> { let IsThrowsCommand = 1; } -def Exception : BlockCommand<"exception"> { let IsThrowsCommand = 1; } +def Throws: BlockCommand<"throws"> { let IsThrowsCommand = 1; let NumArgs = 1; } +def Throw : BlockCommand<"throw"> { let IsThrowsCommand = 1; let NumArgs = 1; } +def Exception : BlockCommand<"exception"> { let IsThrowsCommand = 1; let NumArgs = 1;} def Deprecated : BlockCommand<"deprecated"> { let IsEmptyParagraphAllowed = 1; diff --git a/clang/include/clang/AST/CommentParser.h b/clang/include/clang/AST/CommentParser.h index e11e818b1af0a1..5884a25d007851 100644 --- a/clang/include/clang/AST/CommentParser.h +++ b/clang/include/clang/AST/CommentParser.h @@ -100,6 +100,9 @@ class Parser { ArrayRef parseCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs); + ArrayRef + parseThrowCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs); + BlockCommandComment *parseBlockCommand(); InlineCommandComment *parseInlineCommand(); diff --git a/clang/lib/AST/CommentParser.cpp b/clang/lib/AST/CommentParser.cpp index 8adfd85d0160c3..c70fa1b05cb241 100644 --- a/clang/lib/AST/CommentParser.cpp +++ b/clang/lib/AST/CommentParser.cpp @@ -75,6 +75,25 @@ class TextTokenRetokenizer { return *Pos.BufferPtr; } + char peekNext(unsigned offset) const { +assert(!isEnd()); +assert(Pos.BufferPtr != Pos.BufferEnd); +if (Pos.BufferPtr + offset <= Pos.BufferEnd) { + return *(Pos.BufferPtr + offset); +} else { + return '\0'; +} + } + + void peekNextToken(SmallString<32> &WordText) const { +unsigned offset = 1; +char C = peekNext(offset++); +while (!isWhitespace(C) && C != '\0') { + WordText.push_back(C); + C = peekNext(offset++); +} + } + void consumeChar() { assert(!isEnd()); assert(Pos.BufferPtr != Pos.BufferEnd); @@ -89,6 +108,29 @@ class TextTokenRetokenizer { } } + /// Extract a template type + bool lexTemplateType(SmallString<32> &WordText) { +unsigned IncrementCounter = 0; +while (!isEnd()) { + const char C = peek(); + WordText.push_back(C); + consumeChar(); + switch (C) { + default: +break; + case '<': { +IncrementCounter++; + } break; + case '>': { +IncrementCounter--; +if (!IncrementCounter) + return true; + } break; + } +} +return false; + } + /// Add a token. /// Returns true on success, false if there are no interesting tokens to /// fetch from lexer. @@ -149,6 +191,76 @@ class TextTokenRetokenizer { addToken(); } + /// Extract a type argument + bool lexDataType(Token &Tok) { +if (isEnd()) + return false; +Position SavedPos = Pos; +consumeWhitespace(); +SmallString<32> NextToken; +SmallString<32> WordText; +const char *WordBegin = Pos.BufferPtr; +SourceLocation Loc = getSourceLocation(); +StringRef ConstVal = StringRef("const"); +bool ConstPointer = false; + +while (!isEnd()) { + const char C = peek(); + if (!isWhitespace(C)) { +if (C == '<') { + if (!lexTemplateType(WordText)) +return fals
[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> 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> +&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,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,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. +/// +/// 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 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,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,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)
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)
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)
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)
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] [HLSL] remove double impelementation of log, sin, trunc intrinsics (PR #86432)
https://github.com/aabysswalker created https://github.com/llvm/llvm-project/pull/86432 This change removes the log, log2, log10, sin, trunc intrinsics with parameters of type double as it is not available in the DCX compiler. https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-log https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-log2 https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-log10 https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-sin https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-trunc Closes #86181 >From 93e207ccaadb2d6bef60c71af39333dd2685927a Mon Sep 17 00:00:00 2001 From: aabysswalker Date: Sun, 24 Mar 2024 13:48:17 +0200 Subject: [PATCH] This change removes the log, log2, log10, sin, trunc intrinsics with parameters of type double as it is not available in the DCX compiler. --- clang/lib/Headers/hlsl/hlsl_intrinsics.h | 45 1 file changed, 45 deletions(-) diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 5e703772b7ee4f..90e115521e02f6 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -737,15 +737,6 @@ float3 log(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) float4 log(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) -double log(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) -double2 log(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) -double3 log(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) -double4 log(double4); - //===--===// // log10 builtins //===--===// @@ -779,15 +770,6 @@ float3 log10(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) float4 log10(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) -double log10(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) -double2 log10(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) -double3 log10(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) -double4 log10(double4); - //===--===// // log2 builtins //===--===// @@ -821,15 +803,6 @@ float3 log2(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) float4 log2(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) -double log2(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) -double2 log2(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) -double3 log2(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) -double4 log2(double4); - //===--===// // mad builtins //===--===// @@ -1393,15 +1366,6 @@ float3 sin(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) float4 sin(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) -double sin(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) -double2 sin(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) -double3 sin(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) -double4 sin(double4); - //===--===// // sqrt builtins //===--===// @@ -1450,15 +1414,6 @@ float3 trunc(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) float4 trunc(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) -double trunc(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) -double2 trunc(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) -double3 trunc(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) -double4 trunc(double4); - //===--===// // Wave* builtins //===--===// ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] remove double impelementation of log, sin, trunc intrinsics (PR #86432)
github-actions[bot] wrote: Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using `@` followed by their GitHub username. If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the [LLVM GitHub User Guide](https://llvm.org/docs/GitHub.html). You can also ask questions in a comment on this PR, on the [LLVM Discord](https://discord.com/invite/xS7Z362) or on the [forums](https://discourse.llvm.org/). https://github.com/llvm/llvm-project/pull/86432 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] remove double impelementation of log, sin, trunc intrinsics (PR #86432)
llvmbot wrote: @llvm/pr-subscribers-backend-x86 Author: Andrii Levitskiy (aabysswalker) Changes This change removes the log, log2, log10, sin, trunc intrinsics with parameters of type double as it is not available in the DCX compiler. https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-log https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-log2 https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-log10 https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-sin https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-trunc Closes #86181 --- Full diff: https://github.com/llvm/llvm-project/pull/86432.diff 1 Files Affected: - (modified) clang/lib/Headers/hlsl/hlsl_intrinsics.h (-45) ``diff diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 5e703772b7ee4f..90e115521e02f6 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -737,15 +737,6 @@ float3 log(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) float4 log(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) -double log(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) -double2 log(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) -double3 log(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) -double4 log(double4); - //===--===// // log10 builtins //===--===// @@ -779,15 +770,6 @@ float3 log10(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) float4 log10(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) -double log10(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) -double2 log10(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) -double3 log10(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) -double4 log10(double4); - //===--===// // log2 builtins //===--===// @@ -821,15 +803,6 @@ float3 log2(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) float4 log2(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) -double log2(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) -double2 log2(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) -double3 log2(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) -double4 log2(double4); - //===--===// // mad builtins //===--===// @@ -1393,15 +1366,6 @@ float3 sin(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) float4 sin(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) -double sin(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) -double2 sin(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) -double3 sin(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) -double4 sin(double4); - //===--===// // sqrt builtins //===--===// @@ -1450,15 +1414,6 @@ float3 trunc(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) float4 trunc(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) -double trunc(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) -double2 trunc(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) -double3 trunc(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) -double4 trunc(double4); - //===--===// // Wave* builtins //===--===// `` https://github.com/llvm/llvm-project/pull/86432 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] remove double impelementation of log, sin, trunc intrinsics (PR #86432)
https://github.com/aabysswalker edited https://github.com/llvm/llvm-project/pull/86432 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [mlir] [CodeGen][LLVM] Make the `va_list` related intrinsics generic. (PR #85460)
AlexVlx wrote: > CI looks unhappy, mlir also seems to need updates: > > MLIR :: Target/LLVMIR/llvmir.mlir MLIR :: mlir-cpu-runner/x86-varargs.mlir Done. https://github.com/llvm/llvm-project/pull/85460 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add check to suggest replacement of nested std::min or std::max with initializer lists (PR #85572)
sopyb wrote: ping https://github.com/llvm/llvm-project/pull/85572 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add check to suggest replacement of nested std::min or std::max with initializer lists (PR #85572)
sopyb wrote: Ping https://github.com/llvm/llvm-project/pull/85572 ___ 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)
@@ -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,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] [Clang][analyzer] add documentation for optin performance padding (padding checker) #73675 (PR #86411)
@@ -804,10 +804,28 @@ Check for performance anti-patterns when using Grand Central Dispatch. .. _optin-performance-Padding: -optin.performance.Padding -" +optin.performance.Padding (PaddingChecker) komalverma04 wrote: Thank you so much for your valuable feedbacks i will update it as you said. https://github.com/llvm/llvm-project/pull/86411 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] fix extract-to-function for overloaded operators (PR #81640)
https://github.com/5chmidti updated https://github.com/llvm/llvm-project/pull/81640 >From 1796e5d2c44bae890c13b2af3fc7e4ec36e716dd Mon Sep 17 00:00:00 2001 From: Julian Schmidt Date: Tue, 13 Feb 2024 18:59:16 +0100 Subject: [PATCH 1/2] [clangd] fix extract-to-function for overloaded operators When selecting code that contains the use of overloaded operators, the SelectionTree will attribute the operator to the operator declaration, not to the `CXXOperatorCallExpr`. To allow extract-to-function to work with these operators, make unselected `CXXOperatorCallExpr`s valid root statements, just like `DeclStmt`s. Fixes clangd/clangd#1254 --- .../refactor/tweaks/ExtractFunction.cpp | 15 +++--- .../unittests/tweaks/ExtractFunctionTests.cpp | 47 +++ clang-tools-extra/docs/ReleaseNotes.rst | 3 ++ 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp b/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp index 0302839c58252e..aae480175b33f6 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp @@ -56,6 +56,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/Stmt.h" @@ -70,7 +71,6 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Error.h" -#include "llvm/Support/raw_os_ostream.h" #include namespace clang { @@ -104,9 +104,12 @@ bool isRootStmt(const Node *N) { // Root statement cannot be partially selected. if (N->Selected == SelectionTree::Partial) return false; - // Only DeclStmt can be an unselected RootStmt since VarDecls claim the entire - // selection range in selectionTree. - if (N->Selected == SelectionTree::Unselected && !N->ASTNode.get()) + // A DeclStmt can be an unselected RootStmt since VarDecls claim the entire + // selection range in selectionTree. Additionally, an CXXOperatorCallExpr of a + // binary operation can be unselected because it's children claim the entire + // selection range in the selection tree (e.g. <<). + if (N->Selected == SelectionTree::Unselected && !N->ASTNode.get() && + !N->ASTNode.get()) return false; return true; } @@ -913,8 +916,8 @@ Expected ExtractFunction::apply(const Selection &Inputs) { tooling::Replacements OtherEdit( createForwardDeclaration(*ExtractedFunc, SM)); - if (auto PathAndEdit = Tweak::Effect::fileEdit(SM, SM.getFileID(*FwdLoc), - OtherEdit)) + if (auto PathAndEdit = + Tweak::Effect::fileEdit(SM, SM.getFileID(*FwdLoc), OtherEdit)) MultiFileEffect->ApplyEdits.try_emplace(PathAndEdit->first, PathAndEdit->second); else diff --git a/clang-tools-extra/clangd/unittests/tweaks/ExtractFunctionTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/ExtractFunctionTests.cpp index dec63d454d52c6..8e347b516c6ffe 100644 --- a/clang-tools-extra/clangd/unittests/tweaks/ExtractFunctionTests.cpp +++ b/clang-tools-extra/clangd/unittests/tweaks/ExtractFunctionTests.cpp @@ -571,6 +571,53 @@ int getNum(bool Superstitious, int Min, int Max) { EXPECT_EQ(apply(Before), After); } +TEST_F(ExtractFunctionTest, OverloadedOperators) { + Context = File; + std::string Before = R"cpp(struct A { +int operator+(int x) { return x; } + }; + A &operator<<(A &, int); + A &operator|(A &, int); + + A stream{}; + + void foo(int, int); + + int main() { +[[foo(1, 2); +foo(3, 4); +stream << 42; +stream + 42; +stream | 42; +foo(1, 2); +foo(3, 4);]] + })cpp"; + std::string After = + R"cpp(struct A { +int operator+(int x) { return x; } + }; + A &operator<<(A &, int); + A &operator|(A &, int); + + A stream{}; + + void foo(int, int); + + void extracted() { +foo(1, 2); +foo(3, 4); +stream << 42; +stream + 42; +stream | 42; +foo(1, 2); +foo(3, 4); +} +int main() { +extracted(); + })cpp"; + EXPECT_EQ(apply(Before), After); +} + } // namespace } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index a604e9276668ae..1cd7c6b6ae5adf 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -69,6 +69,9 @@ Code complet
[clang-tools-extra] [clangd] fix extract-to-function for overloaded operators (PR #81640)
5chmidti wrote: Rebase & Ping https://github.com/llvm/llvm-project/pull/81640 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] Extract Function: add hoisting support (PR #75533)
https://github.com/5chmidti updated https://github.com/llvm/llvm-project/pull/75533 >From c1130028fcbb3cd26dd1df537ca0fa449f44bfe1 Mon Sep 17 00:00:00 2001 From: Julian Schmidt <44101708+5chmi...@users.noreply.github.com> Date: Sat, 21 Jan 2023 14:49:58 +0100 Subject: [PATCH 1/2] [clangd] Extract Function: add hoisting support Adds support to hoist variables declared inside the selected region and used afterwards back out of the extraced function for later use. Uses the explicit variable type if only one decl needs hoisting, otherwise uses std::pair or std::tuple with auto return type deduction (requires c++14) and a structured binding (requires c++17) or explicitly unpacking the variables with get<>. --- .../refactor/tweaks/ExtractFunction.cpp | 159 +-- .../unittests/tweaks/ExtractFunctionTests.cpp | 393 +- clang-tools-extra/docs/ReleaseNotes.rst | 3 + 3 files changed, 523 insertions(+), 32 deletions(-) diff --git a/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp b/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp index 0302839c58252e..02d1a6d0996a53 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp @@ -79,6 +79,13 @@ namespace { using Node = SelectionTree::Node; +struct HoistSetComparator { + bool operator()(const Decl *const Lhs, const Decl *const Rhs) const { +return Lhs->getLocation() < Rhs->getLocation(); + } +}; +using HoistSet = llvm::SmallSet; + // ExtractionZone is the part of code that is being extracted. // EnclosingFunction is the function/method inside which the zone lies. // We split the file into 4 parts relative to extraction zone. @@ -171,12 +178,13 @@ struct ExtractionZone { // semicolon after the extraction. const Node *getLastRootStmt() const { return Parent->Children.back(); } - // Checks if declarations inside extraction zone are accessed afterwards. + // Checks if declarations inside extraction zone are accessed afterwards and + // adds these declarations to the returned set. // // This performs a partial AST traversal proportional to the size of the // enclosing function, so it is possibly expensive. - bool requiresHoisting(const SourceManager &SM, -const HeuristicResolver *Resolver) const { + HoistSet getDeclsToHoist(const SourceManager &SM, + const HeuristicResolver *Resolver) const { // First find all the declarations that happened inside extraction zone. llvm::SmallSet DeclsInExtZone; for (auto *RootStmt : RootStmts) { @@ -191,29 +199,28 @@ struct ExtractionZone { } // Early exit without performing expensive traversal below. if (DeclsInExtZone.empty()) - return false; -// Then make sure they are not used outside the zone. + return {}; +// Add any decl used after the selection to the returned set +HoistSet DeclsToHoist{}; for (const auto *S : EnclosingFunction->getBody()->children()) { if (SM.isBeforeInTranslationUnit(S->getSourceRange().getEnd(), ZoneRange.getEnd())) continue; - bool HasPostUse = false; findExplicitReferences( S, [&](const ReferenceLoc &Loc) { -if (HasPostUse || -SM.isBeforeInTranslationUnit(Loc.NameLoc, ZoneRange.getEnd())) +if (SM.isBeforeInTranslationUnit(Loc.NameLoc, ZoneRange.getEnd())) return; -HasPostUse = llvm::any_of(Loc.Targets, - [&DeclsInExtZone](const Decl *Target) { -return DeclsInExtZone.contains(Target); - }); +for (const NamedDecl *const PostUse : llvm::make_filter_range( + Loc.Targets, [&DeclsInExtZone](const Decl *Target) { + return DeclsInExtZone.contains(Target); + })) { + DeclsToHoist.insert(PostUse); +} }, Resolver); - if (HasPostUse) -return true; } -return false; +return DeclsToHoist; } }; @@ -367,14 +374,17 @@ struct NewFunction { bool Static = false; ConstexprSpecKind Constexpr = ConstexprSpecKind::Unspecified; bool Const = false; + const HoistSet &ToHoist; // Decides whether the extracted function body and the function call need a // semicolon after extraction. tooling::ExtractionSemicolonPolicy SemicolonPolicy; const LangOptions *LangOpts; - NewFunction(tooling::ExtractionSemicolonPolicy SemicolonPolicy, + NewFunction(const HoistSet &ToHoist, + tooling::ExtractionSemicolonPolicy SemicolonPolicy, const LangOptions *LangOpts) - : SemicolonPolicy(SemicolonPolicy), LangOpts(LangOpts) {} + : ToHoist(ToHoist), SemicolonPolicy(SemicolonPolicy), LangOpts(LangOpts)
[clang-tools-extra] [clangd] Extract Function: add hoisting support (PR #75533)
5chmidti wrote: Rebase & Ping https://github.com/llvm/llvm-project/pull/75533 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] fix extract-to-function for overloaded operators (PR #81640)
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/81640 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] fix extract-to-function for overloaded operators (PR #81640)
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/81640 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] Extract Function: add hoisting support (PR #75533)
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/75533 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] Extract Function: add hoisting support (PR #75533)
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/75533 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] remove double impelementation of log, sin, trunc intrinsics (PR #86432)
https://github.com/aabysswalker updated https://github.com/llvm/llvm-project/pull/86432 >From 93e207ccaadb2d6bef60c71af39333dd2685927a Mon Sep 17 00:00:00 2001 From: aabysswalker Date: Sun, 24 Mar 2024 13:48:17 +0200 Subject: [PATCH] This change removes the log, log2, log10, sin, trunc intrinsics with parameters of type double as it is not available in the DCX compiler. --- clang/lib/Headers/hlsl/hlsl_intrinsics.h | 45 1 file changed, 45 deletions(-) diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 5e703772b7ee4f..90e115521e02f6 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -737,15 +737,6 @@ float3 log(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) float4 log(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) -double log(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) -double2 log(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) -double3 log(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) -double4 log(double4); - //===--===// // log10 builtins //===--===// @@ -779,15 +770,6 @@ float3 log10(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) float4 log10(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) -double log10(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) -double2 log10(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) -double3 log10(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) -double4 log10(double4); - //===--===// // log2 builtins //===--===// @@ -821,15 +803,6 @@ float3 log2(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) float4 log2(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) -double log2(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) -double2 log2(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) -double3 log2(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) -double4 log2(double4); - //===--===// // mad builtins //===--===// @@ -1393,15 +1366,6 @@ float3 sin(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) float4 sin(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) -double sin(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) -double2 sin(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) -double3 sin(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) -double4 sin(double4); - //===--===// // sqrt builtins //===--===// @@ -1450,15 +1414,6 @@ float3 trunc(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) float4 trunc(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) -double trunc(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) -double2 trunc(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) -double3 trunc(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) -double4 trunc(double4); - //===--===// // Wave* builtins //===--===// ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] remove double impelementation of log, sin, trunc intrinsics (PR #86432)
https://github.com/aabysswalker closed https://github.com/llvm/llvm-project/pull/86432 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Match against all plugins when parsing microsoft attributes (PR #86426)
https://github.com/Sirraide commented: In addition to the comment above, this also needs a release note as well as some tests. Also, as the bot has already pointed out, you need to set your email address to public. https://github.com/llvm/llvm-project/pull/86426 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Match against all plugins when parsing microsoft attributes (PR #86426)
https://github.com/Sirraide edited https://github.com/llvm/llvm-project/pull/86426 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Match against all plugins when parsing microsoft attributes (PR #86426)
@@ -5061,11 +5061,15 @@ void Parser::ParseMicrosoftAttributes(ParsedAttributes &Attrs) { IdentifierInfo *II = Tok.getIdentifierInfo(); SourceLocation NameLoc = Tok.getLocation(); ConsumeToken(); -ParsedAttr::Kind AttrKind = -ParsedAttr::getParsedKind(II, nullptr, ParsedAttr::AS_Microsoft); + // For HLSL we want to handle all attributes, but for MSVC compat, we // silently ignore unknown Microsoft attributes. -if (getLangOpts().HLSL || AttrKind != ParsedAttr::UnknownAttribute) { +AttributeCommonInfo Info{II, NameLoc, + AttributeCommonInfo::Form::Microsoft()}; +const ParsedAttrInfo &AttrInfo = ParsedAttrInfo::get(Info); +if (getLangOpts().HLSL || +AttrInfo.hasSpelling(AttributeCommonInfo::AS_Microsoft, + II->getName())) { Sirraide wrote: Hmm, I can’t find a place where we’re doing anything like this here for the other syntaxes, so I’m not sure this is the right approach. `hasAttribute()` from `clang/Basic/Attributes.h` seems to do what you’re trying to do here; have you tried using that one? https://github.com/llvm/llvm-project/pull/86426 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Factor out OpenACC part of `Sema` (PR #84184)
https://github.com/Endilll updated https://github.com/llvm/llvm-project/pull/84184 >From 23f4208fb9978370f59cae16db0747acb3e2c906 Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov Date: Wed, 6 Mar 2024 18:01:35 +0300 Subject: [PATCH 1/6] [clang] Factor out OpenACC part of `Sema` This patch moves OpenACC parts of `Sema` into a separate class `SemaOpenACC` that is placed in a separate header `Sema/SemaOpenACC.h`. This patch is intended to be a model of factoring things out of `Sema`, so I picked a small OpenACC part. Goals are the following: 1) Split `Sema` into manageable parts. 2) Make dependencies between parts visible. 3) Improve Clang development cycle by avoiding recompiling unrelated parts of the compiler. 4) Avoid compile-time regressions. 5) Avoid notational regressions in the code that uses Sema. --- clang/include/clang/Sema/Sema.h| 77 -- clang/include/clang/Sema/SemaOpenACC.h | 68 +++ clang/lib/Parse/ParseOpenACC.cpp | 22 clang/lib/Sema/Sema.cpp| 4 +- clang/lib/Sema/SemaOpenACC.cpp | 44 --- clang/lib/Sema/TreeTransform.h | 11 ++-- 6 files changed, 137 insertions(+), 89 deletions(-) create mode 100644 clang/include/clang/Sema/SemaOpenACC.h diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index f3d3a57104ee07..932676c52b1f30 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -183,6 +183,7 @@ class Preprocessor; class PseudoDestructorTypeStorage; class PseudoObjectExpr; class QualType; +class SemaOpenACC; class StandardConversionSequence; class Stmt; class StringLiteral; @@ -466,9 +467,8 @@ class Sema final { // 37. Name Lookup for RISC-V Vector Intrinsic (SemaRISCVVectorLookup.cpp) // 38. CUDA (SemaCUDA.cpp) // 39. HLSL Constructs (SemaHLSL.cpp) - // 40. OpenACC Constructs (SemaOpenACC.cpp) - // 41. OpenMP Directives and Clauses (SemaOpenMP.cpp) - // 42. SYCL Constructs (SemaSYCL.cpp) + // 40. OpenMP Directives and Clauses (SemaOpenMP.cpp) + // 41. SYCL Constructs (SemaSYCL.cpp) /// \name Semantic Analysis /// Implementations are in Sema.cpp @@ -1200,6 +1200,27 @@ class Sema final { // // + /// \name Sema Components + /// Parts of Sema + ///@{ + + // Just in this section, private members are followed by public, because + // C++ requires us to create (private) objects before (public) references. + +private: + std::unique_ptr OpenACCPtr; + +public: + SemaOpenACC &OpenACC; + + ///@} + + // + // + // - + // + // + /// \name C++ Access Control /// Implementations are in SemaAccess.cpp ///@{ @@ -13309,56 +13330,6 @@ class Sema final { // // - /// \name OpenACC Constructs - /// Implementations are in SemaOpenACC.cpp - ///@{ - -public: - /// Called after parsing an OpenACC Clause so that it can be checked. - bool ActOnOpenACCClause(OpenACCClauseKind ClauseKind, - SourceLocation StartLoc); - - /// Called after the construct has been parsed, but clauses haven't been - /// parsed. This allows us to diagnose not-implemented, as well as set up any - /// state required for parsing the clauses. - void ActOnOpenACCConstruct(OpenACCDirectiveKind K, SourceLocation StartLoc); - - /// Called after the directive, including its clauses, have been parsed and - /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES - /// happen before any associated declarations or statements have been parsed. - /// This function is only called when we are parsing a 'statement' context. - bool ActOnStartOpenACCStmtDirective(OpenACCDirectiveKind K, - SourceLocation StartLoc); - - /// Called after the directive, including its clauses, have been parsed and - /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES - /// happen before any associated declarations or statements have been parsed. - /// This function is only called when we are parsing a 'Decl' context. - bool ActOnStartOpenACCDeclDirective(OpenACCDirectiveKind K, - SourceLocation StartLoc); - /// Called when we encounter an associated statement for our construct, this - /// should check legality of the statement as it appertains to this Construct. - StmtResult ActOnOpenACCAssociatedStmt(OpenACCDirectiveKind K, -StmtResult AssocStmt); - - /// Called after the directive has been completely parsed, including the - /// declaration group or associated statement. - StmtResult ActOnEndOpenACCStmtDirective(OpenACCDirectiveKind K, - SourceLocation StartLoc, - SourceLocation EndLoc, - StmtResult AssocStmt); - /// Called after the directive has
[clang] [clang] Factor out OpenACC part of `Sema` (PR #84184)
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/84184 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Factor out OpenACC part of `Sema` (PR #84184)
Endilll wrote: I added convenience functions to access `ASTContext` and other widely used facilities of `Sema` to `SemaOpenACC`. I intentionally didn't go full base class approach, saving this option for the future. https://github.com/llvm/llvm-project/pull/84184 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Factor out OpenACC part of `Sema` (PR #84184)
https://github.com/Endilll updated https://github.com/llvm/llvm-project/pull/84184 >From 23f4208fb9978370f59cae16db0747acb3e2c906 Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov Date: Wed, 6 Mar 2024 18:01:35 +0300 Subject: [PATCH 1/7] [clang] Factor out OpenACC part of `Sema` This patch moves OpenACC parts of `Sema` into a separate class `SemaOpenACC` that is placed in a separate header `Sema/SemaOpenACC.h`. This patch is intended to be a model of factoring things out of `Sema`, so I picked a small OpenACC part. Goals are the following: 1) Split `Sema` into manageable parts. 2) Make dependencies between parts visible. 3) Improve Clang development cycle by avoiding recompiling unrelated parts of the compiler. 4) Avoid compile-time regressions. 5) Avoid notational regressions in the code that uses Sema. --- clang/include/clang/Sema/Sema.h| 77 -- clang/include/clang/Sema/SemaOpenACC.h | 68 +++ clang/lib/Parse/ParseOpenACC.cpp | 22 clang/lib/Sema/Sema.cpp| 4 +- clang/lib/Sema/SemaOpenACC.cpp | 44 --- clang/lib/Sema/TreeTransform.h | 11 ++-- 6 files changed, 137 insertions(+), 89 deletions(-) create mode 100644 clang/include/clang/Sema/SemaOpenACC.h diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index f3d3a57104ee07..932676c52b1f30 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -183,6 +183,7 @@ class Preprocessor; class PseudoDestructorTypeStorage; class PseudoObjectExpr; class QualType; +class SemaOpenACC; class StandardConversionSequence; class Stmt; class StringLiteral; @@ -466,9 +467,8 @@ class Sema final { // 37. Name Lookup for RISC-V Vector Intrinsic (SemaRISCVVectorLookup.cpp) // 38. CUDA (SemaCUDA.cpp) // 39. HLSL Constructs (SemaHLSL.cpp) - // 40. OpenACC Constructs (SemaOpenACC.cpp) - // 41. OpenMP Directives and Clauses (SemaOpenMP.cpp) - // 42. SYCL Constructs (SemaSYCL.cpp) + // 40. OpenMP Directives and Clauses (SemaOpenMP.cpp) + // 41. SYCL Constructs (SemaSYCL.cpp) /// \name Semantic Analysis /// Implementations are in Sema.cpp @@ -1200,6 +1200,27 @@ class Sema final { // // + /// \name Sema Components + /// Parts of Sema + ///@{ + + // Just in this section, private members are followed by public, because + // C++ requires us to create (private) objects before (public) references. + +private: + std::unique_ptr OpenACCPtr; + +public: + SemaOpenACC &OpenACC; + + ///@} + + // + // + // - + // + // + /// \name C++ Access Control /// Implementations are in SemaAccess.cpp ///@{ @@ -13309,56 +13330,6 @@ class Sema final { // // - /// \name OpenACC Constructs - /// Implementations are in SemaOpenACC.cpp - ///@{ - -public: - /// Called after parsing an OpenACC Clause so that it can be checked. - bool ActOnOpenACCClause(OpenACCClauseKind ClauseKind, - SourceLocation StartLoc); - - /// Called after the construct has been parsed, but clauses haven't been - /// parsed. This allows us to diagnose not-implemented, as well as set up any - /// state required for parsing the clauses. - void ActOnOpenACCConstruct(OpenACCDirectiveKind K, SourceLocation StartLoc); - - /// Called after the directive, including its clauses, have been parsed and - /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES - /// happen before any associated declarations or statements have been parsed. - /// This function is only called when we are parsing a 'statement' context. - bool ActOnStartOpenACCStmtDirective(OpenACCDirectiveKind K, - SourceLocation StartLoc); - - /// Called after the directive, including its clauses, have been parsed and - /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES - /// happen before any associated declarations or statements have been parsed. - /// This function is only called when we are parsing a 'Decl' context. - bool ActOnStartOpenACCDeclDirective(OpenACCDirectiveKind K, - SourceLocation StartLoc); - /// Called when we encounter an associated statement for our construct, this - /// should check legality of the statement as it appertains to this Construct. - StmtResult ActOnOpenACCAssociatedStmt(OpenACCDirectiveKind K, -StmtResult AssocStmt); - - /// Called after the directive has been completely parsed, including the - /// declaration group or associated statement. - StmtResult ActOnEndOpenACCStmtDirective(OpenACCDirectiveKind K, - SourceLocation StartLoc, - SourceLocation EndLoc, - StmtResult AssocStmt); - /// Called after the directive has
[clang-tools-extra] [clang-tidy] Improved --verify-config when using literal style in config file (PR #85591)
@@ -19,12 +19,17 @@ static bool consumeNegativeIndicator(StringRef &GlobList) { return GlobList.consume_front("-"); } -// Converts first glob from the comma-separated list of globs to Regex and -// removes it and the trailing comma from the GlobList. -static llvm::Regex consumeGlob(StringRef &GlobList) { +// Extract the first glob from the comma-separated list of globs SimplyDanny wrote: ```suggestion // Extracts the first glob from the comma-separated list of globs, ``` https://github.com/llvm/llvm-project/pull/85591 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Improved --verify-config when using literal style in config file (PR #85591)
@@ -454,52 +454,31 @@ static constexpr StringLiteral VerifyConfigWarningEnd = " [-verify-config]\n"; static bool verifyChecks(const StringSet<> &AllChecks, StringRef CheckGlob, StringRef Source) { - llvm::StringRef Cur, Rest; + GlobList Globs(CheckGlob); bool AnyInvalid = false; - for (std::tie(Cur, Rest) = CheckGlob.split(','); - !(Cur.empty() && Rest.empty()); std::tie(Cur, Rest) = Rest.split(',')) { -Cur = Cur.trim(); -if (Cur.empty()) + for (const auto &Item : Globs.getItems()) { +const llvm::Regex &Reg = Item.Regex; +const llvm::StringRef Text = Item.Text; +if (Text.starts_with("clang-diagnostic")) continue; -Cur.consume_front("-"); -if (Cur.starts_with("clang-diagnostic")) - continue; -if (Cur.contains('*')) { - SmallString<128> RegexText("^"); - StringRef MetaChars("()^$|*+?.[]\\{}"); - for (char C : Cur) { -if (C == '*') - RegexText.push_back('.'); -else if (MetaChars.contains(C)) - RegexText.push_back('\\'); -RegexText.push_back(C); - } - RegexText.push_back('$'); - llvm::Regex Glob(RegexText); - std::string Error; - if (!Glob.isValid(Error)) { -AnyInvalid = true; -llvm::WithColor::error(llvm::errs(), Source) -<< "building check glob '" << Cur << "' " << Error << "'\n"; -continue; - } - if (llvm::none_of(AllChecks.keys(), -[&Glob](StringRef S) { return Glob.match(S); })) { -AnyInvalid = true; +if (llvm::none_of(AllChecks.keys(), [&Reg](StringRef S) { + llvm::errs() << S << '\n'; SimplyDanny wrote: Is this output intended? https://github.com/llvm/llvm-project/pull/85591 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Improved --verify-config when using literal style in config file (PR #85591)
@@ -454,52 +454,31 @@ static constexpr StringLiteral VerifyConfigWarningEnd = " [-verify-config]\n"; static bool verifyChecks(const StringSet<> &AllChecks, StringRef CheckGlob, StringRef Source) { - llvm::StringRef Cur, Rest; + GlobList Globs(CheckGlob); bool AnyInvalid = false; - for (std::tie(Cur, Rest) = CheckGlob.split(','); - !(Cur.empty() && Rest.empty()); std::tie(Cur, Rest) = Rest.split(',')) { -Cur = Cur.trim(); -if (Cur.empty()) + for (const auto &Item : Globs.getItems()) { +const llvm::Regex &Reg = Item.Regex; +const llvm::StringRef Text = Item.Text; +if (Text.starts_with("clang-diagnostic")) continue; -Cur.consume_front("-"); -if (Cur.starts_with("clang-diagnostic")) - continue; -if (Cur.contains('*')) { - SmallString<128> RegexText("^"); - StringRef MetaChars("()^$|*+?.[]\\{}"); - for (char C : Cur) { -if (C == '*') - RegexText.push_back('.'); -else if (MetaChars.contains(C)) - RegexText.push_back('\\'); -RegexText.push_back(C); - } - RegexText.push_back('$'); - llvm::Regex Glob(RegexText); - std::string Error; - if (!Glob.isValid(Error)) { -AnyInvalid = true; -llvm::WithColor::error(llvm::errs(), Source) -<< "building check glob '" << Cur << "' " << Error << "'\n"; -continue; - } - if (llvm::none_of(AllChecks.keys(), -[&Glob](StringRef S) { return Glob.match(S); })) { -AnyInvalid = true; +if (llvm::none_of(AllChecks.keys(), [&Reg](StringRef S) { + llvm::errs() << S << '\n'; + return Reg.match(S); +})) { + AnyInvalid = true; + if (Item.Text.contains('*')) SimplyDanny wrote: Previously this came before the checks for matches in line 466. Seems like the semantic has so changed slightly if only performance-wise, hasn't it? https://github.com/llvm/llvm-project/pull/85591 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Improved --verify-config when using literal style in config file (PR #85591)
@@ -454,52 +454,31 @@ static constexpr StringLiteral VerifyConfigWarningEnd = " [-verify-config]\n"; static bool verifyChecks(const StringSet<> &AllChecks, StringRef CheckGlob, StringRef Source) { - llvm::StringRef Cur, Rest; + GlobList Globs(CheckGlob); bool AnyInvalid = false; - for (std::tie(Cur, Rest) = CheckGlob.split(','); - !(Cur.empty() && Rest.empty()); std::tie(Cur, Rest) = Rest.split(',')) { -Cur = Cur.trim(); -if (Cur.empty()) + for (const auto &Item : Globs.getItems()) { +const llvm::Regex &Reg = Item.Regex; +const llvm::StringRef Text = Item.Text; SimplyDanny wrote: Fine from my point of view to inline both of these variables as it doesn't improve much to have them. If you insist to keep them, use them wherever `Item.` appears. https://github.com/llvm/llvm-project/pull/85591 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Implement P2718R0 "Lifetime extension in range-based for loops" (PR #76361)
@@ -6375,12 +6383,16 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) { ImmediateCallVisitor V(getASTContext()); if (!NestedDefaultChecking) V.TraverseDecl(Field); - if (V.HasImmediateCalls) { + if (V.HasImmediateCalls || InLifetimeExtendingContext) { ExprEvalContexts.back().DelayedDefaultInitializationContext = {Loc, Field, CurContext}; ExprEvalContexts.back().IsCurrentlyCheckingDefaultArgumentOrInitializer = NestedDefaultChecking; +// Pass down lifetime extending flag, and collect temporaries in +// CreateMaterializeTemporaryExpr when we rewrite the call argument. +keepInLifetimeExtendingContext(); +keepInMaterializeTemporaryObjectContext(); yronglin wrote: I try to extend lifetime of the `MaterializedTemporaryExpr`s in `CXXDefaultInitExpr`, but looking from the generated IR, `MaterializedTemporaryExpr ::setExtendingDecl` does not take effect. I think some modifications may be needed in CodeGen. https://github.com/llvm/llvm-project/pull/76361 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][analyzer] add documentation for optin performance padding (padding checker) #73675 (PR #86411)
https://github.com/komalverma04 updated https://github.com/llvm/llvm-project/pull/86411 >From b6ca6f0ef83d03e299d6ee9a8ed9b8044477914e Mon Sep 17 00:00:00 2001 From: komalverma04 <114138604+komalverm...@users.noreply.github.com> Date: Sat, 23 Mar 2024 11:14:44 -0700 Subject: [PATCH 1/3] Update checkers.rst Modification of documentation to demonstrate utilization of AllowedPad within PaddingChecker, along with its use and effects on code analysis. --- clang/docs/analyzer/checkers.rst | 22 -- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index fe211514914272..64b09bc6ecd1d8 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -804,10 +804,28 @@ Check for performance anti-patterns when using Grand Central Dispatch. .. _optin-performance-Padding: -optin.performance.Padding -" +optin.performance.Padding (PaddingChecker) +""" Check for excessively padded structs. +.. code-block:: objc + + struct TestStruct { + int data1; // 4 bytes + char data2; // 1 byte + char padding[27]; // 27 bytes of padding +}; // Total size: 32 bytes + + void TestFunction() { + struct TestStruct struct1; // Warning is generated due to excessive padding. +} + + // Reports are only generated if the excessive padding exceeds 'AllowedPad' in bytes. + + // AllowedPad: Default Value: 24 bytes + + Usage: `AllowedPad=` + .. _optin-portability-UnixAPI: optin.portability.UnixAPI >From 403115cd960653a3afe0491d2855d35d377d9312 Mon Sep 17 00:00:00 2001 From: komalverma04 <114138604+komalverm...@users.noreply.github.com> Date: Sat, 23 Mar 2024 11:20:46 -0700 Subject: [PATCH 2/3] Update Checkers.td Changed NotDocumented to HasDocumentation for Padding Checker under performance checker. --- clang/include/clang/StaticAnalyzer/Checkers/Checkers.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index 686e5e99f4a62c..c0e4e9a70c2ef3 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -908,7 +908,7 @@ def PaddingChecker : Checker<"Padding">, "24", Released> ]>, - Documentation; + Documentation; } // end: "padding" >From cdef12fa6a6b6c4833bc2017dae9557ee7115c92 Mon Sep 17 00:00:00 2001 From: komalverma04 Date: Sun, 24 Mar 2024 20:39:56 +0530 Subject: [PATCH 3/3] Update checkers.rst Made Indentation consistent and added description on limitation of checker. --- clang/docs/analyzer/checkers.rst | 44 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index 64b09bc6ecd1d8..85f3f33d68bc5d 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -804,27 +804,37 @@ Check for performance anti-patterns when using Grand Central Dispatch. .. _optin-performance-Padding: -optin.performance.Padding (PaddingChecker) -""" +optin.performance.Padding (C, C++, objC) + Check for excessively padded structs. -.. code-block:: objc - - struct TestStruct { - int data1; // 4 bytes - char data2; // 1 byte - char padding[27]; // 27 bytes of padding -}; // Total size: 32 bytes - - void TestFunction() { - struct TestStruct struct1; // Warning is generated due to excessive padding. -} - - // Reports are only generated if the excessive padding exceeds 'AllowedPad' in bytes. +This checker detects structs with excessive padding, which can lead to wasted memory and decreased performance. Padding bytes are added by compilers to align data within the struct for performance optimization or memory alignment purposes. However, excessive padding can significantly increase the size of the struct without adding useful data, leading to inefficient memory usage, cache misses, and decreased performance. + +.. code-block:: C + + #include + // #pragma pack(1) // Uncomment it to disable structure padding + struct TestStruct { + char data1; // 1 byte + char data2; // 1 byte + int data3; // 4 bytes + }; // Total size: 6 bytes + + int main () { + struct TestStruct struct1; + print("Structure size: %d",sizeof(struct1)); // Structure size: 8 + return 0; + } + +Total memory used is 8 bytes due to structure padding. In this case, padding is of 2 bytes. Padding is done to decrease the number of CPU cycles needed to access data members of the structure; it increases the performance of the process
[clang] [HLSL] remove double impelementation of log, sin, trunc intrinsics (PR #86440)
https://github.com/aabysswalker created https://github.com/llvm/llvm-project/pull/86440 This change removes the log, log2, log10, sin, trunc intrinsics with parameters of type double as it is not available in the DCX compiler. https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-log https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-log2 https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-log10 https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-sin https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-trunc Closes #86189 >From 417b26ffeabf7ec2e99ee28f68b1c38d92e73bf1 Mon Sep 17 00:00:00 2001 From: aabysswalker Date: Sun, 24 Mar 2024 17:13:03 +0200 Subject: [PATCH] Removes the log, sin, trunc intrinsics with parameters of type double as it is not available in the DXC. --- clang/lib/Headers/hlsl/hlsl_intrinsics.h | 45 1 file changed, 45 deletions(-) diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 5e703772b7ee4f..90e115521e02f6 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -737,15 +737,6 @@ float3 log(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) float4 log(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) -double log(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) -double2 log(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) -double3 log(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) -double4 log(double4); - //===--===// // log10 builtins //===--===// @@ -779,15 +770,6 @@ float3 log10(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) float4 log10(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) -double log10(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) -double2 log10(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) -double3 log10(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) -double4 log10(double4); - //===--===// // log2 builtins //===--===// @@ -821,15 +803,6 @@ float3 log2(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) float4 log2(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) -double log2(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) -double2 log2(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) -double3 log2(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) -double4 log2(double4); - //===--===// // mad builtins //===--===// @@ -1393,15 +1366,6 @@ float3 sin(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) float4 sin(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) -double sin(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) -double2 sin(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) -double3 sin(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) -double4 sin(double4); - //===--===// // sqrt builtins //===--===// @@ -1450,15 +1414,6 @@ float3 trunc(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) float4 trunc(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) -double trunc(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) -double2 trunc(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) -double3 trunc(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) -double4 trunc(double4); - //===--===// // Wave* builtins //===--===// ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] remove double impelementation of log, sin, trunc intrinsics (PR #86440)
github-actions[bot] wrote: Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using `@` followed by their GitHub username. If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the [LLVM GitHub User Guide](https://llvm.org/docs/GitHub.html). You can also ask questions in a comment on this PR, on the [LLVM Discord](https://discord.com/invite/xS7Z362) or on the [forums](https://discourse.llvm.org/). https://github.com/llvm/llvm-project/pull/86440 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] remove double impelementation of log, sin, trunc intrinsics (PR #86440)
llvmbot wrote: @llvm/pr-subscribers-backend-x86 @llvm/pr-subscribers-clang Author: Andrii Levitskiy (aabysswalker) Changes This change removes the log, log2, log10, sin, trunc intrinsics with parameters of type double as it is not available in the DCX compiler. https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-log https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-log2 https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-log10 https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-sin https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-trunc Closes #86189 --- Full diff: https://github.com/llvm/llvm-project/pull/86440.diff 1 Files Affected: - (modified) clang/lib/Headers/hlsl/hlsl_intrinsics.h (-45) ``diff diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 5e703772b7ee4f..90e115521e02f6 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -737,15 +737,6 @@ float3 log(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) float4 log(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) -double log(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) -double2 log(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) -double3 log(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log) -double4 log(double4); - //===--===// // log10 builtins //===--===// @@ -779,15 +770,6 @@ float3 log10(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) float4 log10(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) -double log10(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) -double2 log10(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) -double3 log10(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10) -double4 log10(double4); - //===--===// // log2 builtins //===--===// @@ -821,15 +803,6 @@ float3 log2(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) float4 log2(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) -double log2(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) -double2 log2(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) -double3 log2(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2) -double4 log2(double4); - //===--===// // mad builtins //===--===// @@ -1393,15 +1366,6 @@ float3 sin(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) float4 sin(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) -double sin(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) -double2 sin(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) -double3 sin(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin) -double4 sin(double4); - //===--===// // sqrt builtins //===--===// @@ -1450,15 +1414,6 @@ float3 trunc(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) float4 trunc(float4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) -double trunc(double); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) -double2 trunc(double2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) -double3 trunc(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc) -double4 trunc(double4); - //===--===// // Wave* builtins //===--===// `` https://github.com/llvm/llvm-project/pull/86440 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add check to suggest replacement of nested std::min or std::max with initializer lists (PR #85572)
https://github.com/5chmidti edited https://github.com/llvm/llvm-project/pull/85572 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add check to suggest replacement of nested std::min or std::max with initializer lists (PR #85572)
https://github.com/5chmidti requested changes to this pull request. Going in the right direction, but some things still have to be resolved or cleaned up. Add a few more test (these are the ones I tried locally): ```c++ template struct initializer_list { initializer_list()=default; initializer_list(T*,int){} }; template< class T > const T& max(initializer_list list); template< class T, class Compare > const T& max(initializer_list list, Compare comp); template< class T > const T& min(initializer_list list); template< class T, class Compare > const T& min(initializer_list list, Compare comp); ... int max2b = std::max(std::max(std::max(1, 2), std::max(3, 4)), std::max(std::max(5, 6), std::max(7, 8))); // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not use nested std::max calls, use std::max({1, 2, 3, 4, 5, 6, 7, 8}) instead [modernize-min-max-use-initializer-list] // CHECK-FIXES: int max2b = std::max({1, 2, 3, 4, 5, 6, 7, 8}); int max2c = std::max(std::max(1, std::max(2, 3)), 4); // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not use nested std::max calls, use std::max({1, 2, 3, 4}) instead [modernize-min-max-use-initializer-list] // CHECK-FIXES: int max2c = std::max({1, 2, 3, 4}); int max2d = std::max(std::max({1, 2, 3}), 4); // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not use nested std::max calls, use std::max({1, 2, 3, 4}) instead [modernize-min-max-use-initializer-list] // CHECK-FIXES: int max2d = std::max({1, 2, 3, 4}); int max2e = std::max(1, max(2, max(3, 4))); // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not use nested std::max calls, use std::max({1, 2, 3, 4}) instead [modernize-min-max-use-initializer-list] // CHECK-FIXES: int max2e = std::max({1, 2, 3, 4}); ``` In the above tests, `max2b` and `max2d` fail, which IMO should work, `max2b` especially. And please add some tests with type aliases. My quick test with templates also tells me that they are currently unsupported: ```c++ template void foo(T a, T b, T c){ auto v = std::max(a, std::max(b, c)); } ``` https://github.com/llvm/llvm-project/pull/85572 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add check to suggest replacement of nested std::min or std::max with initializer lists (PR #85572)
@@ -0,0 +1,199 @@ +//===--- MinMaxUseInitializerListCheck.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 "MinMaxUseInitializerListCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +MinMaxUseInitializerListCheck::MinMaxUseInitializerListCheck( +StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context), + Inserter(Options.getLocalOrGlobal("IncludeStyle", +utils::IncludeSorter::IS_LLVM), + areDiagsSelfContained()) {} + +void MinMaxUseInitializerListCheck::storeOptions( +ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IncludeStyle", Inserter.getStyle()); +} + +void MinMaxUseInitializerListCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::max"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::max"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::max")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::max"))) + .bind("topCall"), + this); + + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::min"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::min"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::min")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::min"))) + .bind("topCall"), + this); +} + +void MinMaxUseInitializerListCheck::registerPPCallbacks( +const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + Inserter.registerPreprocessor(PP); +} + +void MinMaxUseInitializerListCheck::check( +const MatchFinder::MatchResult &Match) { + const CallExpr *TopCall = Match.Nodes.getNodeAs("topCall"); + MinMaxUseInitializerListCheck::FindArgsResult Result = + findArgs(Match, TopCall); + + if (!Result.First || !Result.Last || Result.Args.size() <= 2) { +return; + } + + std::string ReplacementText = generateReplacement(Match, TopCall, Result); + + diag(TopCall->getBeginLoc(), + "do not use nested std::%0 calls, use %1 instead") + << TopCall->getDirectCallee()->getName() << ReplacementText + << FixItHint::CreateReplacement( + CharSourceRange::getTokenRange(TopCall->getBeginLoc(), +TopCall->getEndLoc()), + ReplacementText) + << Inserter.createMainFileIncludeInsertion(""); +} + +MinMaxUseInitializerListCheck::FindArgsResult +MinMaxUseInitializerListCheck::findArgs(const MatchFinder::MatchResult &Match, +const CallExpr *Call) { + FindArgsResult Result; + Result.First = nullptr; + Result.Last = nullptr; + Result.Compare = nullptr; + + if (Call->getNumArgs() > 2) { +auto ArgIterator = Call->arguments().begin(); +std::advance(ArgIterator, 2); +Result.Compare = *ArgIterator; + } + + for (const Expr *Arg : Call->arguments()) { +if (!Result.First) + Result.First = Arg; + +const CallExpr *InnerCall = dyn_cast(Arg); +if (InnerCall && InnerCall->getDirectCallee() && +InnerCall->getDirectCallee()->getNameAsString() == +Call->getDirectCallee()->getNameAsString()) { + FindArgsResult InnerResult = findArgs(Match, InnerCall); + + bool processInnerResult = false; + + if (!Result.Compare && !InnerResult.Compare) +processInnerResult = true; + else if (Result.Compare && InnerResult.Compare && + Lexer::getSourceText(CharSourceRange::getTokenRange( +Result.Compare->getSourceRange()), +*Match.SourceManager, +Match.Context->getLangOpts()) == + Lexer::getSourceText( + CharSourceRange::getTokenRange( + InnerResult.Compare->getSourceRange()), + *Match.SourceManager, Match.Context->getLangOpts())) +processInnerResult = true; + + if (processInnerResult) { +Result.Args.insert(Result.Args.end(), InnerResult.Args.begin(), + InnerResult.Args.end()); +continue; + } +} + +if (Arg == Result.Compare)
[clang-tools-extra] [clang-tidy] add check to suggest replacement of nested std::min or std::max with initializer lists (PR #85572)
@@ -0,0 +1,199 @@ +//===--- MinMaxUseInitializerListCheck.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 "MinMaxUseInitializerListCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +MinMaxUseInitializerListCheck::MinMaxUseInitializerListCheck( +StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context), + Inserter(Options.getLocalOrGlobal("IncludeStyle", +utils::IncludeSorter::IS_LLVM), + areDiagsSelfContained()) {} + +void MinMaxUseInitializerListCheck::storeOptions( +ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IncludeStyle", Inserter.getStyle()); +} + +void MinMaxUseInitializerListCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::max"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::max"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::max")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::max"))) + .bind("topCall"), + this); + + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::min"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::min"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::min")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::min"))) + .bind("topCall"), + this); 5chmidti wrote: You are repeating yourself a lot here, please add a variable like `const auto callsStdMax = callee(functionDecl(hasName("::std::max")));` for `min` and `max`. https://github.com/llvm/llvm-project/pull/85572 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add check to suggest replacement of nested std::min or std::max with initializer lists (PR #85572)
@@ -0,0 +1,199 @@ +//===--- MinMaxUseInitializerListCheck.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 "MinMaxUseInitializerListCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +MinMaxUseInitializerListCheck::MinMaxUseInitializerListCheck( +StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context), + Inserter(Options.getLocalOrGlobal("IncludeStyle", +utils::IncludeSorter::IS_LLVM), + areDiagsSelfContained()) {} + +void MinMaxUseInitializerListCheck::storeOptions( +ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IncludeStyle", Inserter.getStyle()); +} + +void MinMaxUseInitializerListCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::max"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::max"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::max")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::max"))) + .bind("topCall"), + this); + + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::min"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::min"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::min")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::min"))) + .bind("topCall"), + this); +} + +void MinMaxUseInitializerListCheck::registerPPCallbacks( +const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + Inserter.registerPreprocessor(PP); +} + +void MinMaxUseInitializerListCheck::check( +const MatchFinder::MatchResult &Match) { + const CallExpr *TopCall = Match.Nodes.getNodeAs("topCall"); 5chmidti wrote: If the type is already on the right-hand-side, then you can use `auto` to declare the variable. https://github.com/llvm/llvm-project/pull/85572 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add check to suggest replacement of nested std::min or std::max with initializer lists (PR #85572)
@@ -0,0 +1,138 @@ +//===--- MinMaxUseInitializerListCheck.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 "MinMaxUseInitializerListCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +MinMaxUseInitializerListCheck::MinMaxUseInitializerListCheck( +StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context), + Inserter(Options.getLocalOrGlobal("IncludeStyle", +utils::IncludeSorter::IS_LLVM), + areDiagsSelfContained()) {} + +void MinMaxUseInitializerListCheck::storeOptions( +ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IncludeStyle", Inserter.getStyle()); +} + +void MinMaxUseInitializerListCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::max"))), + hasAnyArgument(callExpr(callee(functionDecl(hasName("::std::max"), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::max"))) + .bind("maxCall"), + this); + + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::min"))), + hasAnyArgument(callExpr(callee(functionDecl(hasName("::std::min"), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::min"))) + .bind("minCall"), + this); +} + +void MinMaxUseInitializerListCheck::registerPPCallbacks( +const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + Inserter.registerPreprocessor(PP); +} + +void MinMaxUseInitializerListCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *MaxCall = Result.Nodes.getNodeAs("maxCall"); + const auto *MinCall = Result.Nodes.getNodeAs("minCall"); + + const CallExpr *TopCall = MaxCall ? MaxCall : MinCall; + if (!TopCall) { +return; + } + const QualType ResultType = + TopCall->getDirectCallee()->getReturnType().getNonReferenceType(); + + const Expr *FirstArg = nullptr; + const Expr *LastArg = nullptr; + std::vector Args; + findArgs(TopCall, &FirstArg, &LastArg, Args); + + if (!FirstArg || !LastArg || Args.size() <= 2) { +return; + } + + std::string ReplacementText = "{"; + for (const Expr *Arg : Args) { +QualType ArgType = Arg->getType(); +bool CastNeeded = +ArgType.getCanonicalType() != ResultType.getCanonicalType(); + +if (CastNeeded) + ReplacementText += "static_cast<" + ResultType.getAsString() + ">("; 5chmidti wrote: When using template argument deduction, conflicting types are deduced -> compile-time error, but when you explicitly specify the template arg for `min`/`max`, then you would need a cast `std::min(0U, 0.0);` And when the user has already cast one arg, then `ArgType.getCanonicalType` will already equal the result type. To catch the `std::min(0U, 0.0);` pattern, you probably want to use `const QualType ArgType = Arg->IgnoreImpCasts()->getType();` https://godbolt.org/z/onMv71bfY https://github.com/llvm/llvm-project/pull/85572 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add check to suggest replacement of nested std::min or std::max with initializer lists (PR #85572)
@@ -0,0 +1,199 @@ +//===--- MinMaxUseInitializerListCheck.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 "MinMaxUseInitializerListCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +MinMaxUseInitializerListCheck::MinMaxUseInitializerListCheck( +StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context), + Inserter(Options.getLocalOrGlobal("IncludeStyle", +utils::IncludeSorter::IS_LLVM), + areDiagsSelfContained()) {} + +void MinMaxUseInitializerListCheck::storeOptions( +ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IncludeStyle", Inserter.getStyle()); +} + +void MinMaxUseInitializerListCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::max"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::max"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::max")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::max"))) + .bind("topCall"), + this); + + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::min"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::min"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::min")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::min"))) + .bind("topCall"), + this); +} + +void MinMaxUseInitializerListCheck::registerPPCallbacks( +const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + Inserter.registerPreprocessor(PP); +} + +void MinMaxUseInitializerListCheck::check( +const MatchFinder::MatchResult &Match) { + const CallExpr *TopCall = Match.Nodes.getNodeAs("topCall"); + MinMaxUseInitializerListCheck::FindArgsResult Result = + findArgs(Match, TopCall); + + if (!Result.First || !Result.Last || Result.Args.size() <= 2) { +return; + } + + std::string ReplacementText = generateReplacement(Match, TopCall, Result); + + diag(TopCall->getBeginLoc(), + "do not use nested std::%0 calls, use %1 instead") 5chmidti wrote: Please add `'` quotes around the `std::%0` and `%1` https://github.com/llvm/llvm-project/pull/85572 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add check to suggest replacement of nested std::min or std::max with initializer lists (PR #85572)
@@ -0,0 +1,199 @@ +//===--- MinMaxUseInitializerListCheck.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 "MinMaxUseInitializerListCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +MinMaxUseInitializerListCheck::MinMaxUseInitializerListCheck( +StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context), + Inserter(Options.getLocalOrGlobal("IncludeStyle", +utils::IncludeSorter::IS_LLVM), + areDiagsSelfContained()) {} + +void MinMaxUseInitializerListCheck::storeOptions( +ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IncludeStyle", Inserter.getStyle()); +} + +void MinMaxUseInitializerListCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::max"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::max"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::max")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::max"))) + .bind("topCall"), + this); + + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::min"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::min"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::min")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::min"))) + .bind("topCall"), + this); +} + +void MinMaxUseInitializerListCheck::registerPPCallbacks( +const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + Inserter.registerPreprocessor(PP); +} + +void MinMaxUseInitializerListCheck::check( +const MatchFinder::MatchResult &Match) { + const CallExpr *TopCall = Match.Nodes.getNodeAs("topCall"); + MinMaxUseInitializerListCheck::FindArgsResult Result = + findArgs(Match, TopCall); + + if (!Result.First || !Result.Last || Result.Args.size() <= 2) { +return; + } + + std::string ReplacementText = generateReplacement(Match, TopCall, Result); 5chmidti wrote: Add `const` https://github.com/llvm/llvm-project/pull/85572 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add check to suggest replacement of nested std::min or std::max with initializer lists (PR #85572)
@@ -0,0 +1,199 @@ +//===--- MinMaxUseInitializerListCheck.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 "MinMaxUseInitializerListCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +MinMaxUseInitializerListCheck::MinMaxUseInitializerListCheck( +StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context), + Inserter(Options.getLocalOrGlobal("IncludeStyle", +utils::IncludeSorter::IS_LLVM), + areDiagsSelfContained()) {} + +void MinMaxUseInitializerListCheck::storeOptions( +ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IncludeStyle", Inserter.getStyle()); +} + +void MinMaxUseInitializerListCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::max"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::max"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::max")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::max"))) + .bind("topCall"), + this); + + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::min"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::min"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::min")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::min"))) + .bind("topCall"), + this); +} + +void MinMaxUseInitializerListCheck::registerPPCallbacks( +const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + Inserter.registerPreprocessor(PP); +} + +void MinMaxUseInitializerListCheck::check( +const MatchFinder::MatchResult &Match) { + const CallExpr *TopCall = Match.Nodes.getNodeAs("topCall"); + MinMaxUseInitializerListCheck::FindArgsResult Result = + findArgs(Match, TopCall); + + if (!Result.First || !Result.Last || Result.Args.size() <= 2) { +return; + } + + std::string ReplacementText = generateReplacement(Match, TopCall, Result); + + diag(TopCall->getBeginLoc(), + "do not use nested std::%0 calls, use %1 instead") + << TopCall->getDirectCallee()->getName() << ReplacementText + << FixItHint::CreateReplacement( + CharSourceRange::getTokenRange(TopCall->getBeginLoc(), +TopCall->getEndLoc()), 5chmidti wrote: You can use `CharSourceRange::getTokenRange(TopCall->getSourceRange())` here. You can actually omit the `CharSourceRange::getTokenRange` as well, your tests pass fine as well. (Unless there was a reason you used `getTokenRange`, then there would be a test missing for that case) https://github.com/llvm/llvm-project/pull/85572 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add check to suggest replacement of nested std::min or std::max with initializer lists (PR #85572)
@@ -0,0 +1,199 @@ +//===--- MinMaxUseInitializerListCheck.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 "MinMaxUseInitializerListCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +MinMaxUseInitializerListCheck::MinMaxUseInitializerListCheck( +StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context), + Inserter(Options.getLocalOrGlobal("IncludeStyle", +utils::IncludeSorter::IS_LLVM), + areDiagsSelfContained()) {} + +void MinMaxUseInitializerListCheck::storeOptions( +ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IncludeStyle", Inserter.getStyle()); +} + +void MinMaxUseInitializerListCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::max"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::max"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::max")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::max"))) + .bind("topCall"), + this); + + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::min"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::min"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::min")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::min"))) + .bind("topCall"), + this); +} + +void MinMaxUseInitializerListCheck::registerPPCallbacks( +const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + Inserter.registerPreprocessor(PP); +} + +void MinMaxUseInitializerListCheck::check( +const MatchFinder::MatchResult &Match) { + const CallExpr *TopCall = Match.Nodes.getNodeAs("topCall"); + MinMaxUseInitializerListCheck::FindArgsResult Result = + findArgs(Match, TopCall); + + if (!Result.First || !Result.Last || Result.Args.size() <= 2) { +return; + } + + std::string ReplacementText = generateReplacement(Match, TopCall, Result); + + diag(TopCall->getBeginLoc(), + "do not use nested std::%0 calls, use %1 instead") + << TopCall->getDirectCallee()->getName() << ReplacementText + << FixItHint::CreateReplacement( + CharSourceRange::getTokenRange(TopCall->getBeginLoc(), +TopCall->getEndLoc()), + ReplacementText) + << Inserter.createMainFileIncludeInsertion(""); +} + +MinMaxUseInitializerListCheck::FindArgsResult +MinMaxUseInitializerListCheck::findArgs(const MatchFinder::MatchResult &Match, +const CallExpr *Call) { + FindArgsResult Result; + Result.First = nullptr; + Result.Last = nullptr; + Result.Compare = nullptr; + + if (Call->getNumArgs() > 2) { +auto ArgIterator = Call->arguments().begin(); +std::advance(ArgIterator, 2); +Result.Compare = *ArgIterator; + } + + for (const Expr *Arg : Call->arguments()) { +if (!Result.First) + Result.First = Arg; + +const CallExpr *InnerCall = dyn_cast(Arg); +if (InnerCall && InnerCall->getDirectCallee() && +InnerCall->getDirectCallee()->getNameAsString() == +Call->getDirectCallee()->getNameAsString()) { + FindArgsResult InnerResult = findArgs(Match, InnerCall); + + bool processInnerResult = false; + + if (!Result.Compare && !InnerResult.Compare) +processInnerResult = true; + else if (Result.Compare && InnerResult.Compare && + Lexer::getSourceText(CharSourceRange::getTokenRange( +Result.Compare->getSourceRange()), +*Match.SourceManager, +Match.Context->getLangOpts()) == + Lexer::getSourceText( + CharSourceRange::getTokenRange( + InnerResult.Compare->getSourceRange()), + *Match.SourceManager, Match.Context->getLangOpts())) +processInnerResult = true; + + if (processInnerResult) { +Result.Args.insert(Result.Args.end(), InnerResult.Args.begin(), + InnerResult.Args.end()); +continue; + } +} + +if (Arg == Result.Compare)
[clang-tools-extra] [clang-tidy] add check to suggest replacement of nested std::min or std::max with initializer lists (PR #85572)
@@ -0,0 +1,65 @@ +//===--- MinMaxUseInitializerListCheck.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_MODERNIZE_MINMAXUSEINITIALIZERLISTCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MINMAXUSEINITIALIZERLISTCHECK_H + +#include "../ClangTidyCheck.h" +#include "../utils/IncludeInserter.h" + +namespace clang::tidy::modernize { + +/// Replaces chained ``std::min`` and ``std::max`` calls with a initializer list 5chmidti wrote: `chained` sound like statement after statement. I think `nested` sounds better, wdyt? Also: `an initializer list` instead of `a initializer list` (same in release notes and check docs). Of course, chained `min`/`max` calls could also be detected, but that may be better left for a follow-up pr. https://github.com/llvm/llvm-project/pull/85572 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add check to suggest replacement of nested std::min or std::max with initializer lists (PR #85572)
@@ -0,0 +1,199 @@ +//===--- MinMaxUseInitializerListCheck.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 "MinMaxUseInitializerListCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +MinMaxUseInitializerListCheck::MinMaxUseInitializerListCheck( +StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context), + Inserter(Options.getLocalOrGlobal("IncludeStyle", +utils::IncludeSorter::IS_LLVM), + areDiagsSelfContained()) {} + +void MinMaxUseInitializerListCheck::storeOptions( +ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IncludeStyle", Inserter.getStyle()); +} + +void MinMaxUseInitializerListCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::max"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::max"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::max")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::max"))) + .bind("topCall"), + this); + + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::min"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::min"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::min")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::min"))) + .bind("topCall"), + this); +} + +void MinMaxUseInitializerListCheck::registerPPCallbacks( +const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + Inserter.registerPreprocessor(PP); +} + +void MinMaxUseInitializerListCheck::check( +const MatchFinder::MatchResult &Match) { + const CallExpr *TopCall = Match.Nodes.getNodeAs("topCall"); + MinMaxUseInitializerListCheck::FindArgsResult Result = + findArgs(Match, TopCall); + + if (!Result.First || !Result.Last || Result.Args.size() <= 2) { +return; + } + + std::string ReplacementText = generateReplacement(Match, TopCall, Result); + + diag(TopCall->getBeginLoc(), + "do not use nested std::%0 calls, use %1 instead") + << TopCall->getDirectCallee()->getName() << ReplacementText + << FixItHint::CreateReplacement( + CharSourceRange::getTokenRange(TopCall->getBeginLoc(), +TopCall->getEndLoc()), + ReplacementText) + << Inserter.createMainFileIncludeInsertion(""); +} + +MinMaxUseInitializerListCheck::FindArgsResult +MinMaxUseInitializerListCheck::findArgs(const MatchFinder::MatchResult &Match, +const CallExpr *Call) { + FindArgsResult Result; + Result.First = nullptr; + Result.Last = nullptr; + Result.Compare = nullptr; + + if (Call->getNumArgs() > 2) { +auto ArgIterator = Call->arguments().begin(); +std::advance(ArgIterator, 2); +Result.Compare = *ArgIterator; + } + + for (const Expr *Arg : Call->arguments()) { +if (!Result.First) + Result.First = Arg; + +const CallExpr *InnerCall = dyn_cast(Arg); +if (InnerCall && InnerCall->getDirectCallee() && +InnerCall->getDirectCallee()->getNameAsString() == +Call->getDirectCallee()->getNameAsString()) { + FindArgsResult InnerResult = findArgs(Match, InnerCall); + + bool processInnerResult = false; + + if (!Result.Compare && !InnerResult.Compare) +processInnerResult = true; + else if (Result.Compare && InnerResult.Compare && + Lexer::getSourceText(CharSourceRange::getTokenRange( +Result.Compare->getSourceRange()), +*Match.SourceManager, +Match.Context->getLangOpts()) == + Lexer::getSourceText( + CharSourceRange::getTokenRange( + InnerResult.Compare->getSourceRange()), + *Match.SourceManager, Match.Context->getLangOpts())) +processInnerResult = true; + + if (processInnerResult) { +Result.Args.insert(Result.Args.end(), InnerResult.Args.begin(), + InnerResult.Args.end()); +continue; + } +} + +if (Arg == Result.Compare)
[clang-tools-extra] [clang-tidy] add check to suggest replacement of nested std::min or std::max with initializer lists (PR #85572)
@@ -0,0 +1,199 @@ +//===--- MinMaxUseInitializerListCheck.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 "MinMaxUseInitializerListCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +MinMaxUseInitializerListCheck::MinMaxUseInitializerListCheck( +StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context), + Inserter(Options.getLocalOrGlobal("IncludeStyle", +utils::IncludeSorter::IS_LLVM), + areDiagsSelfContained()) {} + +void MinMaxUseInitializerListCheck::storeOptions( +ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IncludeStyle", Inserter.getStyle()); +} + +void MinMaxUseInitializerListCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::max"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::max"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::max")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::max"))) + .bind("topCall"), + this); + + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::min"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::min"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::min")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::min"))) + .bind("topCall"), + this); +} + +void MinMaxUseInitializerListCheck::registerPPCallbacks( +const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + Inserter.registerPreprocessor(PP); +} + +void MinMaxUseInitializerListCheck::check( +const MatchFinder::MatchResult &Match) { + const CallExpr *TopCall = Match.Nodes.getNodeAs("topCall"); + MinMaxUseInitializerListCheck::FindArgsResult Result = + findArgs(Match, TopCall); + + if (!Result.First || !Result.Last || Result.Args.size() <= 2) { +return; + } + + std::string ReplacementText = generateReplacement(Match, TopCall, Result); + + diag(TopCall->getBeginLoc(), + "do not use nested std::%0 calls, use %1 instead") + << TopCall->getDirectCallee()->getName() << ReplacementText + << FixItHint::CreateReplacement( + CharSourceRange::getTokenRange(TopCall->getBeginLoc(), +TopCall->getEndLoc()), + ReplacementText) + << Inserter.createMainFileIncludeInsertion(""); +} + +MinMaxUseInitializerListCheck::FindArgsResult +MinMaxUseInitializerListCheck::findArgs(const MatchFinder::MatchResult &Match, +const CallExpr *Call) { + FindArgsResult Result; + Result.First = nullptr; + Result.Last = nullptr; + Result.Compare = nullptr; + + if (Call->getNumArgs() > 2) { +auto ArgIterator = Call->arguments().begin(); +std::advance(ArgIterator, 2); +Result.Compare = *ArgIterator; + } + + for (const Expr *Arg : Call->arguments()) { +if (!Result.First) + Result.First = Arg; + +const CallExpr *InnerCall = dyn_cast(Arg); +if (InnerCall && InnerCall->getDirectCallee() && +InnerCall->getDirectCallee()->getNameAsString() == +Call->getDirectCallee()->getNameAsString()) { + FindArgsResult InnerResult = findArgs(Match, InnerCall); + + bool processInnerResult = false; + + if (!Result.Compare && !InnerResult.Compare) +processInnerResult = true; + else if (Result.Compare && InnerResult.Compare && + Lexer::getSourceText(CharSourceRange::getTokenRange( +Result.Compare->getSourceRange()), +*Match.SourceManager, +Match.Context->getLangOpts()) == + Lexer::getSourceText( + CharSourceRange::getTokenRange( + InnerResult.Compare->getSourceRange()), + *Match.SourceManager, Match.Context->getLangOpts())) +processInnerResult = true; + + if (processInnerResult) { +Result.Args.insert(Result.Args.end(), InnerResult.Args.begin(), + InnerResult.Args.end()); +continue; + } +} + +if (Arg == Result.Compare)
[clang-tools-extra] [clang-tidy] add check to suggest replacement of nested std::min or std::max with initializer lists (PR #85572)
@@ -0,0 +1,199 @@ +//===--- MinMaxUseInitializerListCheck.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 "MinMaxUseInitializerListCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +MinMaxUseInitializerListCheck::MinMaxUseInitializerListCheck( +StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context), + Inserter(Options.getLocalOrGlobal("IncludeStyle", +utils::IncludeSorter::IS_LLVM), + areDiagsSelfContained()) {} + +void MinMaxUseInitializerListCheck::storeOptions( +ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IncludeStyle", Inserter.getStyle()); +} + +void MinMaxUseInitializerListCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::max"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::max"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::max")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::max"))) + .bind("topCall"), + this); + + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::min"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::min"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::min")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::min"))) + .bind("topCall"), + this); +} + +void MinMaxUseInitializerListCheck::registerPPCallbacks( +const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + Inserter.registerPreprocessor(PP); +} + +void MinMaxUseInitializerListCheck::check( +const MatchFinder::MatchResult &Match) { + const CallExpr *TopCall = Match.Nodes.getNodeAs("topCall"); + MinMaxUseInitializerListCheck::FindArgsResult Result = + findArgs(Match, TopCall); + + if (!Result.First || !Result.Last || Result.Args.size() <= 2) { +return; + } + + std::string ReplacementText = generateReplacement(Match, TopCall, Result); + + diag(TopCall->getBeginLoc(), + "do not use nested std::%0 calls, use %1 instead") + << TopCall->getDirectCallee()->getName() << ReplacementText + << FixItHint::CreateReplacement( + CharSourceRange::getTokenRange(TopCall->getBeginLoc(), +TopCall->getEndLoc()), + ReplacementText) + << Inserter.createMainFileIncludeInsertion(""); +} + +MinMaxUseInitializerListCheck::FindArgsResult +MinMaxUseInitializerListCheck::findArgs(const MatchFinder::MatchResult &Match, +const CallExpr *Call) { + FindArgsResult Result; + Result.First = nullptr; + Result.Last = nullptr; + Result.Compare = nullptr; + + if (Call->getNumArgs() > 2) { +auto ArgIterator = Call->arguments().begin(); +std::advance(ArgIterator, 2); +Result.Compare = *ArgIterator; + } + + for (const Expr *Arg : Call->arguments()) { +if (!Result.First) + Result.First = Arg; + +const CallExpr *InnerCall = dyn_cast(Arg); +if (InnerCall && InnerCall->getDirectCallee() && +InnerCall->getDirectCallee()->getNameAsString() == +Call->getDirectCallee()->getNameAsString()) { + FindArgsResult InnerResult = findArgs(Match, InnerCall); + + bool processInnerResult = false; + + if (!Result.Compare && !InnerResult.Compare) +processInnerResult = true; + else if (Result.Compare && InnerResult.Compare && + Lexer::getSourceText(CharSourceRange::getTokenRange( +Result.Compare->getSourceRange()), +*Match.SourceManager, +Match.Context->getLangOpts()) == + Lexer::getSourceText( + CharSourceRange::getTokenRange( + InnerResult.Compare->getSourceRange()), + *Match.SourceManager, Match.Context->getLangOpts())) +processInnerResult = true; + + if (processInnerResult) { +Result.Args.insert(Result.Args.end(), InnerResult.Args.begin(), + InnerResult.Args.end()); +continue; + } +} + +if (Arg == Result.Compare)
[clang-tools-extra] [clang-tidy] add check to suggest replacement of nested std::min or std::max with initializer lists (PR #85572)
@@ -0,0 +1,199 @@ +//===--- MinMaxUseInitializerListCheck.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 "MinMaxUseInitializerListCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +MinMaxUseInitializerListCheck::MinMaxUseInitializerListCheck( +StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context), + Inserter(Options.getLocalOrGlobal("IncludeStyle", +utils::IncludeSorter::IS_LLVM), + areDiagsSelfContained()) {} + +void MinMaxUseInitializerListCheck::storeOptions( +ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IncludeStyle", Inserter.getStyle()); +} + +void MinMaxUseInitializerListCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::max"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::max"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::max")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::max"))) + .bind("topCall"), + this); + + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::min"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::min"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::min")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::min"))) + .bind("topCall"), + this); +} + +void MinMaxUseInitializerListCheck::registerPPCallbacks( +const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + Inserter.registerPreprocessor(PP); +} + +void MinMaxUseInitializerListCheck::check( +const MatchFinder::MatchResult &Match) { + const CallExpr *TopCall = Match.Nodes.getNodeAs("topCall"); + MinMaxUseInitializerListCheck::FindArgsResult Result = + findArgs(Match, TopCall); + + if (!Result.First || !Result.Last || Result.Args.size() <= 2) { +return; + } + + std::string ReplacementText = generateReplacement(Match, TopCall, Result); + + diag(TopCall->getBeginLoc(), + "do not use nested std::%0 calls, use %1 instead") + << TopCall->getDirectCallee()->getName() << ReplacementText + << FixItHint::CreateReplacement( + CharSourceRange::getTokenRange(TopCall->getBeginLoc(), +TopCall->getEndLoc()), + ReplacementText) + << Inserter.createMainFileIncludeInsertion(""); +} + +MinMaxUseInitializerListCheck::FindArgsResult +MinMaxUseInitializerListCheck::findArgs(const MatchFinder::MatchResult &Match, +const CallExpr *Call) { + FindArgsResult Result; + Result.First = nullptr; + Result.Last = nullptr; + Result.Compare = nullptr; + + if (Call->getNumArgs() > 2) { +auto ArgIterator = Call->arguments().begin(); +std::advance(ArgIterator, 2); +Result.Compare = *ArgIterator; + } + + for (const Expr *Arg : Call->arguments()) { +if (!Result.First) + Result.First = Arg; + +const CallExpr *InnerCall = dyn_cast(Arg); +if (InnerCall && InnerCall->getDirectCallee() && +InnerCall->getDirectCallee()->getNameAsString() == +Call->getDirectCallee()->getNameAsString()) { + FindArgsResult InnerResult = findArgs(Match, InnerCall); + + bool processInnerResult = false; + + if (!Result.Compare && !InnerResult.Compare) +processInnerResult = true; + else if (Result.Compare && InnerResult.Compare && + Lexer::getSourceText(CharSourceRange::getTokenRange( +Result.Compare->getSourceRange()), +*Match.SourceManager, +Match.Context->getLangOpts()) == + Lexer::getSourceText( + CharSourceRange::getTokenRange( + InnerResult.Compare->getSourceRange()), + *Match.SourceManager, Match.Context->getLangOpts())) +processInnerResult = true; + + if (processInnerResult) { +Result.Args.insert(Result.Args.end(), InnerResult.Args.begin(), + InnerResult.Args.end()); +continue; + } +} + +if (Arg == Result.Compare)
[clang-tools-extra] [clang-tidy] add check to suggest replacement of nested std::min or std::max with initializer lists (PR #85572)
@@ -0,0 +1,199 @@ +//===--- MinMaxUseInitializerListCheck.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 "MinMaxUseInitializerListCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +MinMaxUseInitializerListCheck::MinMaxUseInitializerListCheck( +StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context), + Inserter(Options.getLocalOrGlobal("IncludeStyle", +utils::IncludeSorter::IS_LLVM), + areDiagsSelfContained()) {} + +void MinMaxUseInitializerListCheck::storeOptions( +ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IncludeStyle", Inserter.getStyle()); +} + +void MinMaxUseInitializerListCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::max"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::max"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::max")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::max"))) + .bind("topCall"), + this); + + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::min"))), + anyOf(hasArgument( +0, callExpr(callee(functionDecl(hasName("::std::min"), +hasArgument( +1, callExpr(callee(functionDecl(hasName("::std::min")), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::min"))) + .bind("topCall"), + this); +} + +void MinMaxUseInitializerListCheck::registerPPCallbacks( +const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + Inserter.registerPreprocessor(PP); +} + +void MinMaxUseInitializerListCheck::check( +const MatchFinder::MatchResult &Match) { + const CallExpr *TopCall = Match.Nodes.getNodeAs("topCall"); + MinMaxUseInitializerListCheck::FindArgsResult Result = + findArgs(Match, TopCall); + + if (!Result.First || !Result.Last || Result.Args.size() <= 2) { +return; + } + + std::string ReplacementText = generateReplacement(Match, TopCall, Result); + + diag(TopCall->getBeginLoc(), + "do not use nested std::%0 calls, use %1 instead") + << TopCall->getDirectCallee()->getName() << ReplacementText + << FixItHint::CreateReplacement( + CharSourceRange::getTokenRange(TopCall->getBeginLoc(), +TopCall->getEndLoc()), + ReplacementText) + << Inserter.createMainFileIncludeInsertion(""); 5chmidti wrote: The location of `TopCall` may be inside a header, so this include would be in the wrong file. Please use `createIncludeInsertion(Match.SourceManager->getFileID(TopCall->getBeginLoc()), "")` https://github.com/llvm/llvm-project/pull/85572 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add check to suggest replacement of nested std::min or std::max with initializer lists (PR #85572)
https://github.com/5chmidti edited https://github.com/llvm/llvm-project/pull/85572 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [libcxx] [clang] Enable sized deallocation by default in C++14 onwards (PR #83774)
https://github.com/wangpc-pp updated https://github.com/llvm/llvm-project/pull/83774 >From f1653805def59bc6eb23052b3ade80c900b4daaa Mon Sep 17 00:00:00 2001 From: wangpc Date: Fri, 14 Jul 2023 10:38:14 +0800 Subject: [PATCH 1/4] [clang] Enable sized deallocation by default in C++14 onwards Since C++14 has been released for about nine years and most standard libraries have implemented sized deallocation functions, it's time to make this feature default again. Differential Revision: https://reviews.llvm.org/D112921 --- .../clangd/unittests/FindTargetTests.cpp | 4 +- .../checkers/misc/new-delete-overloads.cpp| 10 - clang/docs/ReleaseNotes.rst | 5 + clang/include/clang/Driver/Options.td | 5 +- clang/lib/Driver/ToolChains/Clang.cpp | 13 +- clang/lib/Driver/ToolChains/Darwin.cpp| 58 - clang/lib/Driver/ToolChains/Darwin.h | 4 + clang/lib/Driver/ToolChains/ZOS.cpp | 6 + clang/test/AST/ast-dump-expr-json.cpp | 2 +- clang/test/AST/ast-dump-expr.cpp | 2 +- clang/test/AST/ast-dump-stmt-json.cpp | 244 +- clang/test/Analysis/cxxnewexpr-callback.cpp | 4 +- .../basic.stc.dynamic.deallocation/p2.cpp | 2 +- clang/test/CXX/drs/dr292.cpp | 17 +- .../test/CXX/expr/expr.unary/expr.new/p14.cpp | 2 +- .../CodeGenCXX/cxx1y-sized-deallocation.cpp | 10 +- .../CodeGenCXX/cxx1z-aligned-allocation.cpp | 6 +- .../CodeGenCXX/cxx2a-destroying-delete.cpp| 4 +- clang/test/CodeGenCXX/delete-two-arg.cpp | 4 +- clang/test/CodeGenCXX/delete.cpp | 12 +- clang/test/CodeGenCXX/dllimport.cpp | 4 +- clang/test/CodeGenCXX/new.cpp | 6 +- .../coro-aligned-alloc-2.cpp | 2 - .../CodeGenCoroutines/coro-aligned-alloc.cpp | 6 +- clang/test/CodeGenCoroutines/coro-alloc.cpp | 6 +- clang/test/CodeGenCoroutines/coro-cleanup.cpp | 6 +- clang/test/CodeGenCoroutines/coro-dealloc.cpp | 2 - clang/test/CodeGenCoroutines/coro-gro.cpp | 3 +- clang/test/CodeGenCoroutines/pr56919.cpp | 9 +- clang/test/Lexer/cxx-features.cpp | 20 +- clang/test/PCH/cxx1z-aligned-alloc.cpp| 10 +- clang/test/SemaCXX/MicrosoftExtensions.cpp| 8 +- .../SemaCXX/builtin-operator-new-delete.cpp | 2 +- .../test/SemaCXX/cxx1y-sized-deallocation.cpp | 2 +- .../unavailable_aligned_allocation.cpp| 15 +- .../StaticAnalyzer/CallEventTest.cpp | 2 +- clang/www/cxx_status.html | 11 +- .../support.dynamic/libcpp_deallocate.sh.cpp | 3 + .../sized_delete_array14.pass.cpp | 8 +- .../new.delete.single/sized_delete14.pass.cpp | 8 +- 40 files changed, 436 insertions(+), 111 deletions(-) diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp index 0af6036734ba53..1b7b96281dfaa5 100644 --- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -839,7 +839,9 @@ TEST_F(TargetDeclTest, OverloadExpr) { [[delete]] x; } )cpp"; - EXPECT_DECLS("CXXDeleteExpr", "void operator delete(void *) noexcept"); + // Sized deallocation is enabled by default in C++14 onwards. + EXPECT_DECLS("CXXDeleteExpr", + "void operator delete(void *, unsigned long) noexcept"); } TEST_F(TargetDeclTest, DependentExprs) { diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/new-delete-overloads.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/new-delete-overloads.cpp index 78f021144b2e19..f86fe8a4c5b14f 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/new-delete-overloads.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/new-delete-overloads.cpp @@ -12,16 +12,6 @@ struct S { // CHECK-MESSAGES: :[[@LINE+1]]:7: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope void *operator new(size_t size) noexcept(false); -struct T { - // Sized deallocations are not enabled by default, and so this new/delete pair - // does not match. However, we expect only one warning, for the new, because - // the operator delete is a placement delete and we do not warn on mismatching - // placement operations. - // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope - void *operator new(size_t size) noexcept; - void operator delete(void *ptr, size_t) noexcept; // ok only if sized deallocation is enabled -}; - struct U { void *operator new(size_t size) noexcept; void operator delete(void *ptr) noexcept; diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index d6e179ca9d6904..489679d8c0c681 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -83,6 +83,11 @@ secti
[clang] [Clang][analyzer] add documentation for optin performance padding (padding checker) #73675 (PR #86411)
https://github.com/komalverma04 updated https://github.com/llvm/llvm-project/pull/86411 >From b6ca6f0ef83d03e299d6ee9a8ed9b8044477914e Mon Sep 17 00:00:00 2001 From: komalverma04 <114138604+komalverm...@users.noreply.github.com> Date: Sat, 23 Mar 2024 11:14:44 -0700 Subject: [PATCH 1/4] Update checkers.rst Modification of documentation to demonstrate utilization of AllowedPad within PaddingChecker, along with its use and effects on code analysis. --- clang/docs/analyzer/checkers.rst | 22 -- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index fe211514914272..64b09bc6ecd1d8 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -804,10 +804,28 @@ Check for performance anti-patterns when using Grand Central Dispatch. .. _optin-performance-Padding: -optin.performance.Padding -" +optin.performance.Padding (PaddingChecker) +""" Check for excessively padded structs. +.. code-block:: objc + + struct TestStruct { + int data1; // 4 bytes + char data2; // 1 byte + char padding[27]; // 27 bytes of padding +}; // Total size: 32 bytes + + void TestFunction() { + struct TestStruct struct1; // Warning is generated due to excessive padding. +} + + // Reports are only generated if the excessive padding exceeds 'AllowedPad' in bytes. + + // AllowedPad: Default Value: 24 bytes + + Usage: `AllowedPad=` + .. _optin-portability-UnixAPI: optin.portability.UnixAPI >From 403115cd960653a3afe0491d2855d35d377d9312 Mon Sep 17 00:00:00 2001 From: komalverma04 <114138604+komalverm...@users.noreply.github.com> Date: Sat, 23 Mar 2024 11:20:46 -0700 Subject: [PATCH 2/4] Update Checkers.td Changed NotDocumented to HasDocumentation for Padding Checker under performance checker. --- clang/include/clang/StaticAnalyzer/Checkers/Checkers.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index 686e5e99f4a62c..c0e4e9a70c2ef3 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -908,7 +908,7 @@ def PaddingChecker : Checker<"Padding">, "24", Released> ]>, - Documentation; + Documentation; } // end: "padding" >From cdef12fa6a6b6c4833bc2017dae9557ee7115c92 Mon Sep 17 00:00:00 2001 From: komalverma04 Date: Sun, 24 Mar 2024 20:39:56 +0530 Subject: [PATCH 3/4] Update checkers.rst Made Indentation consistent and added description on limitation of checker. --- clang/docs/analyzer/checkers.rst | 44 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index 64b09bc6ecd1d8..85f3f33d68bc5d 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -804,27 +804,37 @@ Check for performance anti-patterns when using Grand Central Dispatch. .. _optin-performance-Padding: -optin.performance.Padding (PaddingChecker) -""" +optin.performance.Padding (C, C++, objC) + Check for excessively padded structs. -.. code-block:: objc - - struct TestStruct { - int data1; // 4 bytes - char data2; // 1 byte - char padding[27]; // 27 bytes of padding -}; // Total size: 32 bytes - - void TestFunction() { - struct TestStruct struct1; // Warning is generated due to excessive padding. -} - - // Reports are only generated if the excessive padding exceeds 'AllowedPad' in bytes. +This checker detects structs with excessive padding, which can lead to wasted memory and decreased performance. Padding bytes are added by compilers to align data within the struct for performance optimization or memory alignment purposes. However, excessive padding can significantly increase the size of the struct without adding useful data, leading to inefficient memory usage, cache misses, and decreased performance. + +.. code-block:: C + + #include + // #pragma pack(1) // Uncomment it to disable structure padding + struct TestStruct { + char data1; // 1 byte + char data2; // 1 byte + int data3; // 4 bytes + }; // Total size: 6 bytes + + int main () { + struct TestStruct struct1; + print("Structure size: %d",sizeof(struct1)); // Structure size: 8 + return 0; + } + +Total memory used is 8 bytes due to structure padding. In this case, padding is of 2 bytes. Padding is done to decrease the number of CPU cycles needed to access data members of the structure; it increases the performance of the process
[clang-tools-extra] [clang-tidy] Ignore expresions in unevaluated context in bugprone-inc-dec-in-conditions (PR #85849)
https://github.com/PiotrZSL updated https://github.com/llvm/llvm-project/pull/85849 >From 2bd3d15a9e4a9a34bb9edb12815207093c0f3157 Mon Sep 17 00:00:00 2001 From: Piotr Zegar Date: Tue, 19 Mar 2024 19:09:38 + Subject: [PATCH 1/2] [clang-tidy] Ignore expresions in unevaluated context in bugprone-inc-dec-in-conditions Skip checking for references to variable in unevaluated context, like decltype, static_assert and so on. Closes #85838 --- .../clang-tidy/bugprone/IncDecInConditionsCheck.cpp | 7 ++- clang-tools-extra/docs/ReleaseNotes.rst | 4 .../checkers/bugprone/inc-dec-in-conditions.cpp | 9 + 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp index 16f43128d55e87..c9990cf6d10fd5 100644 --- a/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp @@ -31,6 +31,10 @@ void IncDecInConditionsCheck::registerMatchers(MatchFinder *Finder) { anyOf(binaryOperator(anyOf(isComparisonOperator(), isLogicalOperator())), cxxOperatorCallExpr(isComparisonOperator(; + auto IsInUnevaluatedContext = + expr(anyOf(hasAncestor(expr(matchers::hasUnevaluatedContext())), + hasAncestor(typeLoc(; + Finder->addMatcher( expr( OperatorMatcher, unless(isExpansionInSystemHeader()), @@ -47,7 +51,8 @@ void IncDecInConditionsCheck::registerMatchers(MatchFinder *Finder) { hasDescendant( expr(unless(equalsBoundNode("operand")), matchers::isStatementIdenticalToBoundNode( - "operand")) + "operand"), + unless(IsInUnevaluatedContext)) .bind("second") .bind("operator"))), this); diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 44680f79de6f54..8803be56d4fd1a 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -132,6 +132,10 @@ Changes in existing checks ` check by detecting side effect from calling a method with non-const reference parameters. +- Improved :doc:`bugprone-inc-dec-in-conditions + ` check to ignore code + within unevaluated contexts, such as ``decltype``. + - Improved :doc:`bugprone-non-zero-enum-to-bool-conversion ` check by eliminating false positives resulting from direct usage of bitwise operators diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inc-dec-in-conditions.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inc-dec-in-conditions.cpp index 82af039973c3bb..a9cb27a47f35b5 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inc-dec-in-conditions.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inc-dec-in-conditions.cpp @@ -68,3 +68,12 @@ bool doubleCheck(Container x) { // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: decrementing and referencing a variable in a complex condition can cause unintended side-effects due to C++'s order of evaluation, consider moving the modification outside of the condition to avoid misunderstandings [bugprone-inc-dec-in-conditions] // CHECK-MESSAGES: :[[@LINE-2]]:31: warning: incrementing and referencing a variable in a complex condition can cause unintended side-effects due to C++'s order of evaluation, consider moving the modification outside of the condition to avoid misunderstandings [bugprone-inc-dec-in-conditions] } + +namespace PR85838 { + void test() + { +auto foo = 0; +auto bar = 0; +if (++foo < static_cast(bar)) {} + } +} >From f8e1862b5e1bec5af8f71bcddb6ef44169f65ffa Mon Sep 17 00:00:00 2001 From: Piotr Zegar Date: Sun, 24 Mar 2024 15:43:07 + Subject: [PATCH 2/2] Add checking for unevaluated context also on operand side --- .../clang-tidy/bugprone/IncDecInConditionsCheck.cpp | 1 + .../test/clang-tidy/checkers/bugprone/inc-dec-in-conditions.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp index c9990cf6d10fd5..9b3b01eb026833 100644 --- a/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp @@ -46,6 +46,7 @@ void IncDecInConditionsCheck::registerMatchers(MatchFinder *Finder) { cxxOperatorCallExpr( isPrePostOperator(), hasUnaryOperand(expr().bind("operand", + unless(IsInUnevaluatedContext),
[clang-tools-extra] [clang-tidy] Ignore expresions in unevaluated context in bugprone-inc-dec-in-conditions (PR #85849)
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/85849 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Ignore expresions in unevaluated context in bugprone-inc-dec-in-conditions (PR #85849)
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/85849 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][analyzer] add documentation for optin performance padding (padding checker) #73675 (PR #86411)
https://github.com/AtariDreams requested changes to this pull request. Capitalize the O in ObjC https://github.com/llvm/llvm-project/pull/86411 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [mlir] [CodeGen][LLVM] Make the `va_list` related intrinsics generic. (PR #85460)
https://github.com/arichardson approved this pull request. https://github.com/llvm/llvm-project/pull/85460 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][analyzer] add documentation for optin performance padding (padding checker) #73675 (PR #86411)
https://github.com/komalverma04 updated https://github.com/llvm/llvm-project/pull/86411 >From b6ca6f0ef83d03e299d6ee9a8ed9b8044477914e Mon Sep 17 00:00:00 2001 From: komalverma04 <114138604+komalverm...@users.noreply.github.com> Date: Sat, 23 Mar 2024 11:14:44 -0700 Subject: [PATCH 1/5] Update checkers.rst Modification of documentation to demonstrate utilization of AllowedPad within PaddingChecker, along with its use and effects on code analysis. --- clang/docs/analyzer/checkers.rst | 22 -- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index fe211514914272..64b09bc6ecd1d8 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -804,10 +804,28 @@ Check for performance anti-patterns when using Grand Central Dispatch. .. _optin-performance-Padding: -optin.performance.Padding -" +optin.performance.Padding (PaddingChecker) +""" Check for excessively padded structs. +.. code-block:: objc + + struct TestStruct { + int data1; // 4 bytes + char data2; // 1 byte + char padding[27]; // 27 bytes of padding +}; // Total size: 32 bytes + + void TestFunction() { + struct TestStruct struct1; // Warning is generated due to excessive padding. +} + + // Reports are only generated if the excessive padding exceeds 'AllowedPad' in bytes. + + // AllowedPad: Default Value: 24 bytes + + Usage: `AllowedPad=` + .. _optin-portability-UnixAPI: optin.portability.UnixAPI >From 403115cd960653a3afe0491d2855d35d377d9312 Mon Sep 17 00:00:00 2001 From: komalverma04 <114138604+komalverm...@users.noreply.github.com> Date: Sat, 23 Mar 2024 11:20:46 -0700 Subject: [PATCH 2/5] Update Checkers.td Changed NotDocumented to HasDocumentation for Padding Checker under performance checker. --- clang/include/clang/StaticAnalyzer/Checkers/Checkers.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index 686e5e99f4a62c..c0e4e9a70c2ef3 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -908,7 +908,7 @@ def PaddingChecker : Checker<"Padding">, "24", Released> ]>, - Documentation; + Documentation; } // end: "padding" >From cdef12fa6a6b6c4833bc2017dae9557ee7115c92 Mon Sep 17 00:00:00 2001 From: komalverma04 Date: Sun, 24 Mar 2024 20:39:56 +0530 Subject: [PATCH 3/5] Update checkers.rst Made Indentation consistent and added description on limitation of checker. --- clang/docs/analyzer/checkers.rst | 44 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index 64b09bc6ecd1d8..85f3f33d68bc5d 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -804,27 +804,37 @@ Check for performance anti-patterns when using Grand Central Dispatch. .. _optin-performance-Padding: -optin.performance.Padding (PaddingChecker) -""" +optin.performance.Padding (C, C++, objC) + Check for excessively padded structs. -.. code-block:: objc - - struct TestStruct { - int data1; // 4 bytes - char data2; // 1 byte - char padding[27]; // 27 bytes of padding -}; // Total size: 32 bytes - - void TestFunction() { - struct TestStruct struct1; // Warning is generated due to excessive padding. -} - - // Reports are only generated if the excessive padding exceeds 'AllowedPad' in bytes. +This checker detects structs with excessive padding, which can lead to wasted memory and decreased performance. Padding bytes are added by compilers to align data within the struct for performance optimization or memory alignment purposes. However, excessive padding can significantly increase the size of the struct without adding useful data, leading to inefficient memory usage, cache misses, and decreased performance. + +.. code-block:: C + + #include + // #pragma pack(1) // Uncomment it to disable structure padding + struct TestStruct { + char data1; // 1 byte + char data2; // 1 byte + int data3; // 4 bytes + }; // Total size: 6 bytes + + int main () { + struct TestStruct struct1; + print("Structure size: %d",sizeof(struct1)); // Structure size: 8 + return 0; + } + +Total memory used is 8 bytes due to structure padding. In this case, padding is of 2 bytes. Padding is done to decrease the number of CPU cycles needed to access data members of the structure; it increases the performance of the process
[clang-tools-extra] [clang-tidy] Ignore expresions in unevaluated context in bugprone-inc-dec-in-conditions (PR #85849)
https://github.com/5chmidti approved this pull request. https://github.com/llvm/llvm-project/pull/85849 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Match against all plugins when parsing microsoft attributes (PR #86426)
https://github.com/Sirraide edited https://github.com/llvm/llvm-project/pull/86426 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] remove double impelementation of log, sin, trunc intrinsics (PR #86440)
https://github.com/aabysswalker edited https://github.com/llvm/llvm-project/pull/86440 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][analyzer] add documentation for optin performance padding (padding checker) #73675 (PR #86411)
komalverma04 wrote: @AtariDreams Thank you for pointing out. I apologies for that mistake. Please review it, if there are more changes. https://github.com/llvm/llvm-project/pull/86411 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Added bugprone-exception-rethrow check (PR #86448)
https://github.com/PiotrZSL created https://github.com/llvm/llvm-project/pull/86448 Identifies problematic exception rethrowing, especially with caught exception variables or empty throw statements outside catch blocks. Closes #71292 >From 05cf976fd14e3d2a7e716e26e80e8958dff4222c Mon Sep 17 00:00:00 2001 From: Piotr Zegar Date: Sun, 24 Mar 2024 18:39:54 + Subject: [PATCH] [clang-tidy] Added bugprone-exception-rethrow check Identifies problematic exception rethrowing, especially with caught exception variables or empty throw statements outside catch blocks. Closes #71292 --- .../bugprone/BugproneTidyModule.cpp | 3 + .../clang-tidy/bugprone/CMakeLists.txt| 1 + .../bugprone/ExceptionRethrowCheck.cpp| 50 ++ .../bugprone/ExceptionRethrowCheck.h | 37 ++ clang-tools-extra/docs/ReleaseNotes.rst | 6 ++ .../checks/bugprone/exception-rethrow.rst | 68 +++ .../docs/clang-tidy/checks/list.rst | 1 + .../checkers/bugprone/exception-rethrow.cpp | 60 8 files changed, 226 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 2931325d8b5798..adaa77fdbfbde0 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -26,6 +26,7 @@ #include "EasilySwappableParametersCheck.h" #include "EmptyCatchCheck.h" #include "ExceptionEscapeCheck.h" +#include "ExceptionRethrowCheck.h" #include "FoldInitTypeCheck.h" #include "ForwardDeclarationNamespaceCheck.h" #include "ForwardingReferenceOverloadCheck.h" @@ -126,6 +127,8 @@ class BugproneModule : public ClangTidyModule { CheckFactories.registerCheck("bugprone-empty-catch"); CheckFactories.registerCheck( "bugprone-exception-escape"); +CheckFactories.registerCheck( +"bugprone-exception-rethrow"); CheckFactories.registerCheck("bugprone-fold-init-type"); CheckFactories.registerCheck( "bugprone-forward-declaration-namespace"); diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 081ba67efe1538..7c7288f75e1888 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -20,6 +20,7 @@ add_clang_library(clangTidyBugproneModule EasilySwappableParametersCheck.cpp EmptyCatchCheck.cpp ExceptionEscapeCheck.cpp + ExceptionRethrowCheck.cpp FoldInitTypeCheck.cpp ForwardDeclarationNamespaceCheck.cpp ForwardingReferenceOverloadCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp new file mode 100644 index 00..4855ccc2724a92 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp @@ -0,0 +1,50 @@ +//===--- ExceptionRethrowCheck.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 "ExceptionRethrowCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { +AST_MATCHER(VarDecl, isExceptionVariable) { return Node.isExceptionVariable(); } +} // namespace + +void ExceptionRethrowCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + cxxThrowExpr(unless(isExpansionInSystemHeader()), + anyOf(unless(has(expr())), + has(declRefExpr(to(varDecl(isExceptionVariable()), + optionally(hasAncestor(cxxCatchStmt().bind("catch" + .bind("throw"), + this); +} + +void ExceptionRethrowCheck::check(const MatchFinder::MatchResult &Result) { + const auto *MatchedThrow = Result.Nodes.getNodeAs("throw"); + + if (const Expr *ThrownObject = MatchedThrow->getSubExpr()) { +diag(MatchedThrow->getThrowLoc(), + "throwing a copy of the caught %0 exception, remove the argument to " + "throw the original exception object") +<< ThrownObject->getType().getNonReferenceType(); +return; + } + + const bool HasCatchAnsestor = + Result.Nodes.getNodeAs("catch") != nullptr; + if (!HasCatchAnsestor) { +