[clang] 9154a32 - [clang-format][doc] Fix typos
Author: Owen Pan Date: 2024-05-05T00:18:55-07:00 New Revision: 9154a324bfce5dee27cb04708bd250b030d6cdd2 URL: https://github.com/llvm/llvm-project/commit/9154a324bfce5dee27cb04708bd250b030d6cdd2 DIFF: https://github.com/llvm/llvm-project/commit/9154a324bfce5dee27cb04708bd250b030d6cdd2.diff LOG: [clang-format][doc] Fix typos Added: Modified: clang/docs/ClangFormatStyleOptions.rst clang/include/clang/Format/Format.h Removed: diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 39f7cded36edbf..ce9035a2770eec 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -935,8 +935,8 @@ the configuration (without a prefix: ``Auto``). default: return ""; } - * ``bool AlignCaseColons`` Whether aligned case labels are aligned on the colon, or on the -, or on the tokens after the colon. + * ``bool AlignCaseColons`` Whether aligned case labels are aligned on the colon, or on the tokens +after the colon. .. code-block:: c++ diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 48f5fb44157570..8ebdc86b98329c 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -375,8 +375,8 @@ struct FormatStyle { /// } /// \endcode bool AcrossComments; -/// Whether aligned case labels are aligned on the colon, or on the -/// , or on the tokens after the colon. +/// Whether aligned case labels are aligned on the colon, or on the tokens +/// after the colon. /// \code /// true: /// switch (level) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Improve modernize-use-std-print diagnostic (PR #91071)
https://github.com/mikecrowe updated https://github.com/llvm/llvm-project/pull/91071 >From d25fa679a70947d42fe3125858741508475d67c0 Mon Sep 17 00:00:00 2001 From: Mike Crowe Date: Sat, 4 May 2024 17:41:37 +0100 Subject: [PATCH] [clang-tidy] Improve modernize-use-std-print diagnostic Include the source range of the printf function in the diagnostic so it gets underlined in the output. --- clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp index 660996aba7b70d..aa60c904a363da 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp @@ -138,7 +138,8 @@ void UseStdPrintCheck::check(const MatchFinder::MatchResult &Result) { if (!Converter.canApply()) { diag(PrintfCall->getBeginLoc(), "unable to use '%0' instead of %1 because %2") -<< ReplacementFunction << OldFunction->getIdentifier() +<< PrintfCall->getSourceRange() << ReplacementFunction +<< OldFunction->getIdentifier() << Converter.conversionNotPossibleReason(); return; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Improve modernize-use-std-print diagnostic (PR #91071)
mikecrowe wrote: @5chmidti wrote: > LGTM, thanks Please can you land this for me since I don't have permission to do so myself? (Assuming you do have permission.) Thanks. https://github.com/llvm/llvm-project/pull/91071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][docs] Fix modernize-use-std-print docs (PR #91069)
https://github.com/mikecrowe updated https://github.com/llvm/llvm-project/pull/91069 >From 442cc7464ea4972d25e6fe518ac466b540a399eb Mon Sep 17 00:00:00 2001 From: Mike Crowe Date: Sat, 4 May 2024 17:21:02 +0100 Subject: [PATCH] [clang-tidy][docs] Fix modernize-use-std-print docs The set of functions for the PrintfLikeFunctions and FprintfLikeFunctions options replaces the default, so remove the word "extra" from the description which implies that they are in addition to the default. --- .../docs/clang-tidy/checks/modernize/use-std-print.rst| 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-print.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-print.rst index 9bb691e9d9512e..79648a1104bca2 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-print.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-print.rst @@ -118,7 +118,7 @@ Options .. option:: PrintfLikeFunctions - A semicolon-separated list of (fully qualified) extra function names to + A semicolon-separated list of (fully qualified) function names to replace, with the requirement that the first parameter contains the printf-style format string and the arguments to be formatted follow immediately afterwards. If neither this option nor @@ -128,7 +128,7 @@ Options .. option:: FprintfLikeFunctions - A semicolon-separated list of (fully qualified) extra function names to + A semicolon-separated list of (fully qualified) function names to replace, with the requirement that the first parameter is retained, the second parameter contains the printf-style format string and the arguments to be formatted follow immediately afterwards. If neither this ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] No longer require complete types with __builtin_launder (PR #91070)
https://github.com/cor3ntin commented: Should we try to force an instantiation in codegen for complete-but-not-yet-instantiated classes? https://github.com/llvm/llvm-project/pull/91070 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 7d913c5 - [clang][Modules] Make `Module::Requirement` a struct (NFC) (#67900)
Author: David Stone Date: 2024-05-05T09:45:04+02:00 New Revision: 7d913c5ea9fd0dd455fe60364a8075aa0924d6b7 URL: https://github.com/llvm/llvm-project/commit/7d913c5ea9fd0dd455fe60364a8075aa0924d6b7 DIFF: https://github.com/llvm/llvm-project/commit/7d913c5ea9fd0dd455fe60364a8075aa0924d6b7.diff LOG: [clang][Modules] Make `Module::Requirement` a struct (NFC) (#67900) `Module::Requirement` was defined as a `std::pair`. This required a comment to explain what the data members mean and makes the usage harder to understand. Replace this with a struct with two members, `FeatureName` and `RequiredState`. - Co-authored-by: cor3ntin Added: Modified: clang/include/clang/Basic/Module.h clang/lib/Basic/Module.cpp clang/lib/Lex/PPDirectives.cpp clang/lib/Serialization/ASTWriter.cpp Removed: diff --git a/clang/include/clang/Basic/Module.h b/clang/include/clang/Basic/Module.h index 9f62c058ca0da0..2d62d05cd91900 100644 --- a/clang/include/clang/Basic/Module.h +++ b/clang/include/clang/Basic/Module.h @@ -284,9 +284,10 @@ class alignas(8) Module { /// found on the file system. SmallVector MissingHeaders; - /// An individual requirement: a feature name and a flag indicating - /// the required state of that feature. - using Requirement = std::pair; + struct Requirement { +std::string FeatureName; +bool RequiredState; + }; /// The set of language features required to use this module. /// diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp index bb212cde878826..045ef580f9c330 100644 --- a/clang/lib/Basic/Module.cpp +++ b/clang/lib/Basic/Module.cpp @@ -140,8 +140,8 @@ bool Module::isUnimportable(const LangOptions &LangOpts, return true; } for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) { - if (hasFeature(Current->Requirements[I].first, LangOpts, Target) != - Current->Requirements[I].second) { + if (hasFeature(Current->Requirements[I].FeatureName, LangOpts, Target) != + Current->Requirements[I].RequiredState) { Req = Current->Requirements[I]; return true; } @@ -319,7 +319,7 @@ bool Module::directlyUses(const Module *Requested) { void Module::addRequirement(StringRef Feature, bool RequiredState, const LangOptions &LangOpts, const TargetInfo &Target) { - Requirements.push_back(Requirement(std::string(Feature), RequiredState)); + Requirements.push_back(Requirement{std::string(Feature), RequiredState}); // If this feature is currently available, we're done. if (hasFeature(Feature, LangOpts, Target) == RequiredState) @@ -504,9 +504,9 @@ void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const { for (unsigned I = 0, N = Requirements.size(); I != N; ++I) { if (I) OS << ", "; - if (!Requirements[I].second) + if (!Requirements[I].RequiredState) OS << "!"; - OS << Requirements[I].first; + OS << Requirements[I].FeatureName; } OS << "\n"; } diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index 0b22139ebe81de..82eb47bcd5bf92 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -1918,7 +1918,8 @@ bool Preprocessor::checkModuleIsAvailable(const LangOptions &LangOpts, // FIXME: Track the location at which the requirement was specified, and // use it here. Diags.Report(M.DefinitionLoc, diag::err_module_unavailable) -<< M.getFullModuleName() << Requirement.second << Requirement.first; +<< M.getFullModuleName() << Requirement.RequiredState +<< Requirement.FeatureName; } return true; } diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 9712ed6e839180..afe98e803b6c24 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -2988,8 +2988,8 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { // Emit the requirements. for (const auto &R : Mod->Requirements) { - RecordData::value_type Record[] = {SUBMODULE_REQUIRES, R.second}; - Stream.EmitRecordWithBlob(RequiresAbbrev, Record, R.first); + RecordData::value_type Record[] = {SUBMODULE_REQUIRES, R.RequiredState}; + Stream.EmitRecordWithBlob(RequiresAbbrev, Record, R.FeatureName); } // Emit the umbrella header, if there is one. ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Modules] Make `Module::Requirement` a struct (PR #67900)
https://github.com/cor3ntin closed https://github.com/llvm/llvm-project/pull/67900 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][docs] Fix modernize-use-std-print docs (PR #91069)
mikecrowe wrote: @5chmidti wrote: > LGTM, thanks Please can you land this for me since I don't have permission to do so myself? (Assuming you do have permission.) Thanks. https://github.com/llvm/llvm-project/pull/91069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Handle Java switch expressions (PR #91112)
https://github.com/owenca created https://github.com/llvm/llvm-project/pull/91112 Also adds AllowShortCaseExpressionOnASingleLine option and AlignCaseArrows suboption of AlignConsecutiveShortCaseStatements. Fixes #55903. >From be8569c3721337317635a2f0640237a2d5acd73a Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Sun, 5 May 2024 00:21:55 -0700 Subject: [PATCH] [clang-format] Handle Java switch expressions Also adds AllowShortCaseExpressionOnASingleLine option and AlignCaseArrows suboption of AlignConsecutiveShortCaseStatements. Fixes #55903. --- clang/docs/ClangFormatStyleOptions.rst| 36 +++- clang/docs/ReleaseNotes.rst | 3 + clang/include/clang/Format/Format.h | 36 +++- clang/lib/Format/Format.cpp | 4 + clang/lib/Format/FormatToken.h| 3 + clang/lib/Format/TokenAnnotator.cpp | 2 + clang/lib/Format/UnwrappedLineFormatter.cpp | 6 + clang/lib/Format/UnwrappedLineParser.cpp | 46 - clang/lib/Format/UnwrappedLineParser.h| 2 +- clang/lib/Format/WhitespaceManager.cpp| 22 ++- clang/lib/Format/WhitespaceManager.h | 2 +- clang/unittests/Format/ConfigParseTest.cpp| 2 + clang/unittests/Format/FormatTestJava.cpp | 171 ++ clang/unittests/Format/TokenAnnotatorTest.cpp | 18 ++ 14 files changed, 332 insertions(+), 21 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index ce9035a2770eec..f320caf0d21998 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -861,7 +861,8 @@ the configuration (without a prefix: ``Auto``). **AlignConsecutiveShortCaseStatements** (``ShortCaseStatementsAlignmentStyle``) :versionbadge:`clang-format 17` :ref:`¶ ` Style of aligning consecutive short case labels. - Only applies if ``AllowShortCaseLabelsOnASingleLine`` is ``true``. + Only applies if ``AllowShortCaseExpressionOnASingleLine`` or + ``AllowShortCaseLabelsOnASingleLine`` is ``true``. .. code-block:: yaml @@ -935,6 +936,24 @@ the configuration (without a prefix: ``Auto``). default: return ""; } + * ``bool AlignCaseArrows`` Whether to align the case arrows when aligning short case expressions. + +.. code-block:: c++ + + true: + i = switch (day) {\n" +case THURSDAY, SATURDAY -> 8; +case WEDNESDAY -> 9; +default -> 0; + }; + + false: + i = switch (day) {\n" +case THURSDAY, SATURDAY -> 8; +case WEDNESDAY -> 9; +default -> 0; + }; + * ``bool AlignCaseColons`` Whether aligned case labels are aligned on the colon, or on the tokens after the colon. @@ -1692,6 +1711,21 @@ the configuration (without a prefix: ``Auto``). +.. _AllowShortCaseExpressionOnASingleLine: + +**AllowShortCaseExpressionOnASingleLine** (``Boolean``) :versionbadge:`clang-format 19` :ref:`¶ ` + Whether to merge a short switch labeled rule into a single line. + + .. code-block:: c++ + +true: false: +switch (a) { vs. switch (a) { +case 1 -> 1;case 1 -> +default -> 0; 1; +}; default -> + 0; +}; + .. _AllowShortCaseLabelsOnASingleLine: **AllowShortCaseLabelsOnASingleLine** (``Boolean``) :versionbadge:`clang-format 3.6` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b146a9b56884ad..a85095e424b64b 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -834,6 +834,9 @@ clang-format ``BreakTemplateDeclarations``. - ``AlwaysBreakAfterReturnType`` is deprecated and renamed to ``BreakAfterReturnType``. +- Handles Java ``switch`` expressions. +- Adds ``AllowShortCaseExpressionOnASingleLine`` option. +- Adds ``AlignCaseArrows`` suboption to ``AlignConsecutiveShortCaseStatements``. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 8ebdc86b98329c..d08db77c2ab063 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -375,6 +375,23 @@ struct FormatStyle { /// } /// \endcode bool AcrossComments; +/// Whether to align the case arrows when aligning short case expressions. +/// \code +/// true: +/// i = switch (day) {\n" +/// case THURSDAY, SATURDAY -> 8; +/// case WEDNESDAY -> 9; +/// default -> 0; +/// }; +/// +/// false: +/// i = switch (day) {\n" +/// case THURSDAY, SATURDAY -> 8; +/// case WEDNESDAY -> 9; +/// default -> 0; +/// }; +/// \endcode +bool Align
[clang] [clang-format] Handle Java switch expressions (PR #91112)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Owen Pan (owenca) Changes Also adds AllowShortCaseExpressionOnASingleLine option and AlignCaseArrows suboption of AlignConsecutiveShortCaseStatements. Fixes #55903. --- Patch is 26.58 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/91112.diff 14 Files Affected: - (modified) clang/docs/ClangFormatStyleOptions.rst (+35-1) - (modified) clang/docs/ReleaseNotes.rst (+3) - (modified) clang/include/clang/Format/Format.h (+35-1) - (modified) clang/lib/Format/Format.cpp (+4) - (modified) clang/lib/Format/FormatToken.h (+3) - (modified) clang/lib/Format/TokenAnnotator.cpp (+2) - (modified) clang/lib/Format/UnwrappedLineFormatter.cpp (+6) - (modified) clang/lib/Format/UnwrappedLineParser.cpp (+37-9) - (modified) clang/lib/Format/UnwrappedLineParser.h (+1-1) - (modified) clang/lib/Format/WhitespaceManager.cpp (+14-8) - (modified) clang/lib/Format/WhitespaceManager.h (+1-1) - (modified) clang/unittests/Format/ConfigParseTest.cpp (+2) - (modified) clang/unittests/Format/FormatTestJava.cpp (+171) - (modified) clang/unittests/Format/TokenAnnotatorTest.cpp (+18) ``diff diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index ce9035a2770eec..f320caf0d21998 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -861,7 +861,8 @@ the configuration (without a prefix: ``Auto``). **AlignConsecutiveShortCaseStatements** (``ShortCaseStatementsAlignmentStyle``) :versionbadge:`clang-format 17` :ref:`¶ ` Style of aligning consecutive short case labels. - Only applies if ``AllowShortCaseLabelsOnASingleLine`` is ``true``. + Only applies if ``AllowShortCaseExpressionOnASingleLine`` or + ``AllowShortCaseLabelsOnASingleLine`` is ``true``. .. code-block:: yaml @@ -935,6 +936,24 @@ the configuration (without a prefix: ``Auto``). default: return ""; } + * ``bool AlignCaseArrows`` Whether to align the case arrows when aligning short case expressions. + +.. code-block:: c++ + + true: + i = switch (day) {\n" +case THURSDAY, SATURDAY -> 8; +case WEDNESDAY -> 9; +default -> 0; + }; + + false: + i = switch (day) {\n" +case THURSDAY, SATURDAY -> 8; +case WEDNESDAY -> 9; +default -> 0; + }; + * ``bool AlignCaseColons`` Whether aligned case labels are aligned on the colon, or on the tokens after the colon. @@ -1692,6 +1711,21 @@ the configuration (without a prefix: ``Auto``). +.. _AllowShortCaseExpressionOnASingleLine: + +**AllowShortCaseExpressionOnASingleLine** (``Boolean``) :versionbadge:`clang-format 19` :ref:`¶ ` + Whether to merge a short switch labeled rule into a single line. + + .. code-block:: c++ + +true: false: +switch (a) { vs. switch (a) { +case 1 -> 1;case 1 -> +default -> 0; 1; +}; default -> + 0; +}; + .. _AllowShortCaseLabelsOnASingleLine: **AllowShortCaseLabelsOnASingleLine** (``Boolean``) :versionbadge:`clang-format 3.6` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b146a9b56884ad..a85095e424b64b 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -834,6 +834,9 @@ clang-format ``BreakTemplateDeclarations``. - ``AlwaysBreakAfterReturnType`` is deprecated and renamed to ``BreakAfterReturnType``. +- Handles Java ``switch`` expressions. +- Adds ``AllowShortCaseExpressionOnASingleLine`` option. +- Adds ``AlignCaseArrows`` suboption to ``AlignConsecutiveShortCaseStatements``. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 8ebdc86b98329c..d08db77c2ab063 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -375,6 +375,23 @@ struct FormatStyle { /// } /// \endcode bool AcrossComments; +/// Whether to align the case arrows when aligning short case expressions. +/// \code +/// true: +/// i = switch (day) {\n" +/// case THURSDAY, SATURDAY -> 8; +/// case WEDNESDAY -> 9; +/// default -> 0; +/// }; +/// +/// false: +/// i = switch (day) {\n" +/// case THURSDAY, SATURDAY -> 8; +/// case WEDNESDAY -> 9; +/// default -> 0; +/// }; +/// \endcode +bool AlignCaseArrows; /// Whether aligned case labels are aligned on the colon, or on the tokens /// after the colon. /// \code @@ -396,12 +413,14 @@ struct FormatStyle { bool operator==(const ShortCaseSt
[clang] [clang-format] Handle Java switch expressions (PR #91112)
https://github.com/owenca updated https://github.com/llvm/llvm-project/pull/91112 >From be8569c3721337317635a2f0640237a2d5acd73a Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Sun, 5 May 2024 00:21:55 -0700 Subject: [PATCH 1/2] [clang-format] Handle Java switch expressions Also adds AllowShortCaseExpressionOnASingleLine option and AlignCaseArrows suboption of AlignConsecutiveShortCaseStatements. Fixes #55903. --- clang/docs/ClangFormatStyleOptions.rst| 36 +++- clang/docs/ReleaseNotes.rst | 3 + clang/include/clang/Format/Format.h | 36 +++- clang/lib/Format/Format.cpp | 4 + clang/lib/Format/FormatToken.h| 3 + clang/lib/Format/TokenAnnotator.cpp | 2 + clang/lib/Format/UnwrappedLineFormatter.cpp | 6 + clang/lib/Format/UnwrappedLineParser.cpp | 46 - clang/lib/Format/UnwrappedLineParser.h| 2 +- clang/lib/Format/WhitespaceManager.cpp| 22 ++- clang/lib/Format/WhitespaceManager.h | 2 +- clang/unittests/Format/ConfigParseTest.cpp| 2 + clang/unittests/Format/FormatTestJava.cpp | 171 ++ clang/unittests/Format/TokenAnnotatorTest.cpp | 18 ++ 14 files changed, 332 insertions(+), 21 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index ce9035a2770eec..f320caf0d21998 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -861,7 +861,8 @@ the configuration (without a prefix: ``Auto``). **AlignConsecutiveShortCaseStatements** (``ShortCaseStatementsAlignmentStyle``) :versionbadge:`clang-format 17` :ref:`¶ ` Style of aligning consecutive short case labels. - Only applies if ``AllowShortCaseLabelsOnASingleLine`` is ``true``. + Only applies if ``AllowShortCaseExpressionOnASingleLine`` or + ``AllowShortCaseLabelsOnASingleLine`` is ``true``. .. code-block:: yaml @@ -935,6 +936,24 @@ the configuration (without a prefix: ``Auto``). default: return ""; } + * ``bool AlignCaseArrows`` Whether to align the case arrows when aligning short case expressions. + +.. code-block:: c++ + + true: + i = switch (day) {\n" +case THURSDAY, SATURDAY -> 8; +case WEDNESDAY -> 9; +default -> 0; + }; + + false: + i = switch (day) {\n" +case THURSDAY, SATURDAY -> 8; +case WEDNESDAY -> 9; +default -> 0; + }; + * ``bool AlignCaseColons`` Whether aligned case labels are aligned on the colon, or on the tokens after the colon. @@ -1692,6 +1711,21 @@ the configuration (without a prefix: ``Auto``). +.. _AllowShortCaseExpressionOnASingleLine: + +**AllowShortCaseExpressionOnASingleLine** (``Boolean``) :versionbadge:`clang-format 19` :ref:`¶ ` + Whether to merge a short switch labeled rule into a single line. + + .. code-block:: c++ + +true: false: +switch (a) { vs. switch (a) { +case 1 -> 1;case 1 -> +default -> 0; 1; +}; default -> + 0; +}; + .. _AllowShortCaseLabelsOnASingleLine: **AllowShortCaseLabelsOnASingleLine** (``Boolean``) :versionbadge:`clang-format 3.6` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b146a9b56884ad..a85095e424b64b 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -834,6 +834,9 @@ clang-format ``BreakTemplateDeclarations``. - ``AlwaysBreakAfterReturnType`` is deprecated and renamed to ``BreakAfterReturnType``. +- Handles Java ``switch`` expressions. +- Adds ``AllowShortCaseExpressionOnASingleLine`` option. +- Adds ``AlignCaseArrows`` suboption to ``AlignConsecutiveShortCaseStatements``. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 8ebdc86b98329c..d08db77c2ab063 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -375,6 +375,23 @@ struct FormatStyle { /// } /// \endcode bool AcrossComments; +/// Whether to align the case arrows when aligning short case expressions. +/// \code +/// true: +/// i = switch (day) {\n" +/// case THURSDAY, SATURDAY -> 8; +/// case WEDNESDAY -> 9; +/// default -> 0; +/// }; +/// +/// false: +/// i = switch (day) {\n" +/// case THURSDAY, SATURDAY -> 8; +/// case WEDNESDAY -> 9; +/// default -> 0; +/// }; +/// \endcode +bool AlignCaseArrows; /// Whether aligned case labels are aligned on the colon, or on the tokens /// after the colon. /// \code @@ -3
[clang] [clang-format] Handle Java switch expressions (PR #91112)
https://github.com/owenca updated https://github.com/llvm/llvm-project/pull/91112 >From 31a45ace7d828c63b31d0ba20ed07f2a0340c41d Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Sun, 5 May 2024 00:21:55 -0700 Subject: [PATCH] [clang-format] Handle Java switch expressions Also adds AllowShortCaseExpressionOnASingleLine option and AlignCaseArrows suboption of AlignConsecutiveShortCaseStatements. Fixes #55903. --- clang/docs/ClangFormatStyleOptions.rst| 36 +++- clang/docs/ReleaseNotes.rst | 3 + clang/include/clang/Format/Format.h | 36 +++- clang/lib/Format/Format.cpp | 4 + clang/lib/Format/FormatToken.h| 3 + clang/lib/Format/TokenAnnotator.cpp | 2 + clang/lib/Format/UnwrappedLineFormatter.cpp | 6 + clang/lib/Format/UnwrappedLineParser.cpp | 46 - clang/lib/Format/UnwrappedLineParser.h| 2 +- clang/lib/Format/WhitespaceManager.cpp| 22 ++- clang/lib/Format/WhitespaceManager.h | 2 +- clang/unittests/Format/ConfigParseTest.cpp| 2 + clang/unittests/Format/FormatTestJava.cpp | 171 ++ clang/unittests/Format/TokenAnnotatorTest.cpp | 18 ++ 14 files changed, 332 insertions(+), 21 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index ce9035a2770eec..f0f1f44491251c 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -861,7 +861,8 @@ the configuration (without a prefix: ``Auto``). **AlignConsecutiveShortCaseStatements** (``ShortCaseStatementsAlignmentStyle``) :versionbadge:`clang-format 17` :ref:`¶ ` Style of aligning consecutive short case labels. - Only applies if ``AllowShortCaseLabelsOnASingleLine`` is ``true``. + Only applies if ``AllowShortCaseExpressionOnASingleLine`` or + ``AllowShortCaseLabelsOnASingleLine`` is ``true``. .. code-block:: yaml @@ -935,6 +936,24 @@ the configuration (without a prefix: ``Auto``). default: return ""; } + * ``bool AlignCaseArrows`` Whether to align the case arrows when aligning short case expressions. + +.. code-block:: c++ + + true: + i = switch (day) { +case THURSDAY, SATURDAY -> 8; +case WEDNESDAY -> 9; +default -> 0; + }; + + false: + i = switch (day) { +case THURSDAY, SATURDAY -> 8; +case WEDNESDAY -> 9; +default -> 0; + }; + * ``bool AlignCaseColons`` Whether aligned case labels are aligned on the colon, or on the tokens after the colon. @@ -1692,6 +1711,21 @@ the configuration (without a prefix: ``Auto``). +.. _AllowShortCaseExpressionOnASingleLine: + +**AllowShortCaseExpressionOnASingleLine** (``Boolean``) :versionbadge:`clang-format 19` :ref:`¶ ` + Whether to merge a short switch labeled rule into a single line. + + .. code-block:: c++ + +true: false: +switch (a) { vs. switch (a) { +case 1 -> 1;case 1 -> +default -> 0; 1; +}; default -> + 0; +}; + .. _AllowShortCaseLabelsOnASingleLine: **AllowShortCaseLabelsOnASingleLine** (``Boolean``) :versionbadge:`clang-format 3.6` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b146a9b56884ad..a85095e424b64b 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -834,6 +834,9 @@ clang-format ``BreakTemplateDeclarations``. - ``AlwaysBreakAfterReturnType`` is deprecated and renamed to ``BreakAfterReturnType``. +- Handles Java ``switch`` expressions. +- Adds ``AllowShortCaseExpressionOnASingleLine`` option. +- Adds ``AlignCaseArrows`` suboption to ``AlignConsecutiveShortCaseStatements``. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 8ebdc86b98329c..7253f3b57b3003 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -375,6 +375,23 @@ struct FormatStyle { /// } /// \endcode bool AcrossComments; +/// Whether to align the case arrows when aligning short case expressions. +/// \code +/// true: +/// i = switch (day) { +/// case THURSDAY, SATURDAY -> 8; +/// case WEDNESDAY -> 9; +/// default -> 0; +/// }; +/// +/// false: +/// i = switch (day) { +/// case THURSDAY, SATURDAY -> 8; +/// case WEDNESDAY -> 9; +/// default -> 0; +/// }; +/// \endcode +bool AlignCaseArrows; /// Whether aligned case labels are aligned on the colon, or on the tokens /// after the colon. /// \code @@ -396,12 +413,14 @@
[clang] [clang-format] Handle Java switch expressions (PR #91112)
https://github.com/owenca updated https://github.com/llvm/llvm-project/pull/91112 >From beab69244ce686a1d53342979d46f269a46c79de Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Sun, 5 May 2024 00:21:55 -0700 Subject: [PATCH] [clang-format] Handle Java switch expressions Also adds AllowShortCaseExpressionOnASingleLine option and AlignCaseArrows suboption of AlignConsecutiveShortCaseStatements. Fixes #55903. --- clang/docs/ClangFormatStyleOptions.rst| 36 +++- clang/docs/ReleaseNotes.rst | 3 + clang/include/clang/Format/Format.h | 36 +++- clang/lib/Format/Format.cpp | 4 + clang/lib/Format/FormatToken.h| 3 + clang/lib/Format/TokenAnnotator.cpp | 2 + clang/lib/Format/UnwrappedLineFormatter.cpp | 6 + clang/lib/Format/UnwrappedLineParser.cpp | 46 - clang/lib/Format/UnwrappedLineParser.h| 2 +- clang/lib/Format/WhitespaceManager.cpp| 22 ++- clang/lib/Format/WhitespaceManager.h | 2 +- clang/unittests/Format/ConfigParseTest.cpp| 2 + clang/unittests/Format/FormatTestJava.cpp | 171 ++ clang/unittests/Format/TokenAnnotatorTest.cpp | 18 ++ 14 files changed, 332 insertions(+), 21 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index ce9035a2770eec..6d092219877f91 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -861,7 +861,8 @@ the configuration (without a prefix: ``Auto``). **AlignConsecutiveShortCaseStatements** (``ShortCaseStatementsAlignmentStyle``) :versionbadge:`clang-format 17` :ref:`¶ ` Style of aligning consecutive short case labels. - Only applies if ``AllowShortCaseLabelsOnASingleLine`` is ``true``. + Only applies if ``AllowShortCaseExpressionOnASingleLine`` or + ``AllowShortCaseLabelsOnASingleLine`` is ``true``. .. code-block:: yaml @@ -935,6 +936,24 @@ the configuration (without a prefix: ``Auto``). default: return ""; } + * ``bool AlignCaseArrows`` Whether to align the case arrows when aligning short case expressions. + +.. code-block:: java + + true: + i = switch (day) { +case THURSDAY, SATURDAY -> 8; +case WEDNESDAY -> 9; +default -> 0; + }; + + false: + i = switch (day) { +case THURSDAY, SATURDAY -> 8; +case WEDNESDAY -> 9; +default -> 0; + }; + * ``bool AlignCaseColons`` Whether aligned case labels are aligned on the colon, or on the tokens after the colon. @@ -1692,6 +1711,21 @@ the configuration (without a prefix: ``Auto``). +.. _AllowShortCaseExpressionOnASingleLine: + +**AllowShortCaseExpressionOnASingleLine** (``Boolean``) :versionbadge:`clang-format 19` :ref:`¶ ` + Whether to merge a short switch labeled rule into a single line. + + .. code-block:: java + +true: false: +switch (a) { vs. switch (a) { +case 1 -> 1;case 1 -> +default -> 0; 1; +}; default -> + 0; +}; + .. _AllowShortCaseLabelsOnASingleLine: **AllowShortCaseLabelsOnASingleLine** (``Boolean``) :versionbadge:`clang-format 3.6` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b146a9b56884ad..a85095e424b64b 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -834,6 +834,9 @@ clang-format ``BreakTemplateDeclarations``. - ``AlwaysBreakAfterReturnType`` is deprecated and renamed to ``BreakAfterReturnType``. +- Handles Java ``switch`` expressions. +- Adds ``AllowShortCaseExpressionOnASingleLine`` option. +- Adds ``AlignCaseArrows`` suboption to ``AlignConsecutiveShortCaseStatements``. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 8ebdc86b98329c..74893f23210cd0 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -375,6 +375,23 @@ struct FormatStyle { /// } /// \endcode bool AcrossComments; +/// Whether to align the case arrows when aligning short case expressions. +/// \code{.java} +/// true: +/// i = switch (day) { +/// case THURSDAY, SATURDAY -> 8; +/// case WEDNESDAY -> 9; +/// default -> 0; +/// }; +/// +/// false: +/// i = switch (day) { +/// case THURSDAY, SATURDAY -> 8; +/// case WEDNESDAY -> 9; +/// default -> 0; +/// }; +/// \endcode +bool AlignCaseArrows; /// Whether aligned case labels are aligned on the colon, or on the tokens /// after the colon. /// \code @@ -396,12 +
[clang] [clang] Enable FPContract with optnone (PR #91061)
@@ -968,10 +968,7 @@ class FPOptionsOverride { setAllowFPContractAcrossStatement(); } - void setDisallowOptimizations() { -setFPPreciseEnabled(true); -setDisallowFPContract(); - } + void setDisallowOptimizations() { setFPPreciseEnabled(true); } spavloff wrote: Actually this is done by the call to `setFPPreciseEnabled`: https://github.com/spavloff/llvm-project/blob/e518bbfed9eefbe6d9d952dd0354ee974f7a9305/clang/include/clang/Basic/LangOptions.h#L955-L969 https://github.com/llvm/llvm-project/pull/91061 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang] Emit DW_TAG_template_alias for template aliases (PR #87623)
Michael137 wrote: > @Michael137 said: > > > Btw, as a follow-up to this patch should we check that this is compatible > > with dsymutil (i.e., running dsymutil --verify)? I suspect it might need a > > fixup (given LLDB doesn't even support this tag) Yup, dsymutil looks good now, thanks > There's a couple of switches in llvm/lib/DWARFLinker that look like they want > a DW_TAG_template_alias: DependencyTracker::isTypeTableCandidate in DependencyTracker.cpp AcceleratorRecordsSaver::save in AcceleratorRecordsSaver.cpp. I'm not sure what a test for those would look like but I can look into it if you'd like? Good question, I'm not familiar with these either, but would make sense to address these eventually. Though I don't think it's urgent atm since `-gtemplate-alias` isn't the default https://github.com/llvm/llvm-project/pull/87623 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Fix false double free when including 3rd-party headers with overloaded delete operator as system headers (PR #85224)
https://github.com/steakhal updated https://github.com/llvm/llvm-project/pull/85224 >From b3e6a2273e9c35ac4cc3ac16aebcf4ea0d89ef74 Mon Sep 17 00:00:00 2001 From: Ella Ma Date: Thu, 14 Mar 2024 20:41:20 +0800 Subject: [PATCH 1/2] wip: the first workaround --- .../StaticAnalyzer/Checkers/MallocChecker.cpp | 3 ++- .../Inputs/overloaded-delete-in-header.h | 17 + .../overloaded-delete-in-system-header.cpp| 25 +++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 clang/test/Analysis/Inputs/overloaded-delete-in-header.h create mode 100644 clang/test/Analysis/overloaded-delete-in-system-header.cpp diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 03cb7696707fe2..c7ec2b7cc43b30 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -1090,7 +1090,8 @@ static bool isStandardNewDelete(const FunctionDecl *FD) { // If the header for operator delete is not included, it's still defined // in an invalid source location. Check to make sure we don't crash. return !L.isValid() || - FD->getASTContext().getSourceManager().isInSystemHeader(L); + (!FD->hasBody() && // FIXME: Still a false alarm after CTU inlining. + FD->getASTContext().getSourceManager().isInSystemHeader(L)); } //===--===// diff --git a/clang/test/Analysis/Inputs/overloaded-delete-in-header.h b/clang/test/Analysis/Inputs/overloaded-delete-in-header.h new file mode 100644 index 00..5090de0d9bbd6b --- /dev/null +++ b/clang/test/Analysis/Inputs/overloaded-delete-in-header.h @@ -0,0 +1,17 @@ +#ifndef OVERLOADED_DELETE_IN_HEADER +#define OVERLOADED_DELETE_IN_HEADER + +void clang_analyzer_printState(); + +struct DeleteInHeader { + inline void operator delete(void *ptr) { +// No matter whether this header file is included as a system header file +// with -isystem or a user header file with -I, ptr should not be marked as +// released. +clang_analyzer_printState(); + +::operator delete(ptr); // The first place where ptr is marked as released. + } +}; + +#endif // OVERLOADED_DELETE_IN_SYSTEM_HEADER diff --git a/clang/test/Analysis/overloaded-delete-in-system-header.cpp b/clang/test/Analysis/overloaded-delete-in-system-header.cpp new file mode 100644 index 00..f7780b67e93b99 --- /dev/null +++ b/clang/test/Analysis/overloaded-delete-in-system-header.cpp @@ -0,0 +1,25 @@ +// issue 62985 +// When 3rd-party header files are included as system headers, their overloaded +// new and delete operators are also considered as the std ones. However, those +// overloaded operator functions will also be inlined. This makes the same +// symbolic memory marked as released twice, which leads to a false uaf alarm. +// +// The first run, include as system header. False uaf report before fix. +// +// RUN: %clang_analyze_cc1 %s \ +// RUN: -analyzer-checker=core,cplusplus.NewDelete,debug.ExprInspection \ +// RUN: -isystem %S/Inputs/ 2>&1 | \ +// RUN: FileCheck %s +// +// The second run, include as user header. Should always silent. +// +// RUN: %clang_analyze_cc1 %s \ +// RUN: -analyzer-checker=core,cplusplus.NewDelete,debug.ExprInspection \ +// RUN: -I %S/Inputs/ 2>&1 | \ +// RUN: FileCheck %s + +#include "overloaded-delete-in-header.h" + +void deleteInHeader(DeleteInHeader *p) { delete p; } + +// CHECK-NOT: Released >From d7e9b8867a45d329ef0f68fbafe8715acf8ad02f Mon Sep 17 00:00:00 2001 From: Balazs Benics Date: Sun, 5 May 2024 12:34:28 +0200 Subject: [PATCH 2/2] Cleanup test and impl I'd prefer using the definition of FD to check the beginning brace location. --- .../StaticAnalyzer/Checkers/MallocChecker.cpp | 8 +++--- .../Inputs/overloaded-delete-in-header.h | 21 --- .../overloaded-delete-in-system-header.cpp| 26 --- 3 files changed, 21 insertions(+), 34 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 1efc58600f9e63..6c18f2a1d9ee4a 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -1096,13 +1096,15 @@ static bool isStandardNewDelete(const FunctionDecl *FD) { Kind != OO_Array_Delete) return false; + bool HasBody = FD->hasBody(); // Prefer using the definition. + // This is standard if and only if it's not defined in a user file. SourceLocation L = FD->getLocation(); + // If the header for operator delete is not included, it's still defined // in an invalid source location. Check to make sure we don't crash. - return !L.isValid() || - (!FD->hasBody() && // FIXME: Still a false alarm after CTU inlining. - FD->getASTContext().getSourceManager().isInSystemHeader(L)); +
[clang] [analyzer] Fix false double free when including 3rd-party headers with overloaded delete operator as system headers (PR #85224)
steakhal wrote: I had a deeper look at the patch and I think it's good. To be on the safe side, I canonicalize `FD` to prefer decls with definitions if the redeclchain contains a definition. This ensures that if we have a definition, `L` will refer to the beginning of that definition. I'll merge this PR in a couple of days unless someone objects, or you challenge my proposed changes @Snape3058. Thanks for the PR btw. https://github.com/llvm/llvm-project/pull/85224 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Fix false double free when including 3rd-party headers with overloaded delete operator as system headers (PR #85224)
https://github.com/steakhal approved this pull request. https://github.com/llvm/llvm-project/pull/85224 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Fix false double free when including 3rd-party headers with overloaded delete operator as system headers (PR #85224)
https://github.com/steakhal edited https://github.com/llvm/llvm-project/pull/85224 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeGen] Propagate pragma set fast-math flags to floating point builtins (PR #90377)
karka228 wrote: > LGTM. Thanks. I will close the issue #87758. Thanks @andykaylor and @zahiraam for reviewing. https://github.com/llvm/llvm-project/pull/90377 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Check for label location bindings in `DereferenceChecker` (PR #91119)
https://github.com/Rajveer100 created https://github.com/llvm/llvm-project/pull/91119 Resolves #89264 Values should not be stored in addresses of labels, this throws a fatal error when this happens. >From 36b1ee31d8d740cdbee6a1787d7ef81d6abeb8ad Mon Sep 17 00:00:00 2001 From: Rajveer Date: Sun, 5 May 2024 18:05:00 +0530 Subject: [PATCH] [clang][analyzer] Check for label location bindings in `DereferenceChecker` Resolves #89264 --- .../StaticAnalyzer/Checkers/DereferenceChecker.cpp | 7 +++ clang/test/Analysis/Issue89264.c| 13 + 2 files changed, 20 insertions(+) create mode 100644 clang/test/Analysis/Issue89264.c diff --git a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp index 1cebfbbee77dae..a1770e15ad7d52 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp @@ -286,6 +286,13 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S, // If we're binding to a reference, check if the value is known to be null. if (V.isUndef()) return; + + // One should never write to label addresses. + if (auto Label = L.getAs()) { +llvm::errs() << "WRITING TO LABEL: " << L << "\n"; +llvm::errs() << "Fatal Error: " << "Dereference of the address of a label" << "\n"; +return; + } const MemRegion *MR = L.getAsRegion(); const TypedValueRegion *TVR = dyn_cast_or_null(MR); diff --git a/clang/test/Analysis/Issue89264.c b/clang/test/Analysis/Issue89264.c new file mode 100644 index 00..1592bc20ee56f2 --- /dev/null +++ b/clang/test/Analysis/Issue89264.c @@ -0,0 +1,13 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s + +void clang_analyzer_dump(char); +void clang_analyzer_dump_ptr(char*); + +// https://github.com/llvm/llvm-project/issues/89185 +void binding_to_label_loc() { + char *b = &&MyLabel; +MyLabel: + *b = 0; // no-crash + clang_analyzer_dump_ptr(b); // expected-warning {{&&MyLabel}} + clang_analyzer_dump(*b); // expected-warning {{Unknown}} +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Check for label location bindings in `DereferenceChecker` (PR #91119)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Rajveer Singh Bharadwaj (Rajveer100) Changes Resolves #89264 Values should not be stored in addresses of labels, this throws a fatal error when this happens. --- Full diff: https://github.com/llvm/llvm-project/pull/91119.diff 2 Files Affected: - (modified) clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp (+7) - (added) clang/test/Analysis/Issue89264.c (+13) ``diff diff --git a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp index 1cebfbbee77dae..a1770e15ad7d52 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp @@ -286,6 +286,13 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S, // If we're binding to a reference, check if the value is known to be null. if (V.isUndef()) return; + + // One should never write to label addresses. + if (auto Label = L.getAs()) { +llvm::errs() << "WRITING TO LABEL: " << L << "\n"; +llvm::errs() << "Fatal Error: " << "Dereference of the address of a label" << "\n"; +return; + } const MemRegion *MR = L.getAsRegion(); const TypedValueRegion *TVR = dyn_cast_or_null(MR); diff --git a/clang/test/Analysis/Issue89264.c b/clang/test/Analysis/Issue89264.c new file mode 100644 index 00..1592bc20ee56f2 --- /dev/null +++ b/clang/test/Analysis/Issue89264.c @@ -0,0 +1,13 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s + +void clang_analyzer_dump(char); +void clang_analyzer_dump_ptr(char*); + +// https://github.com/llvm/llvm-project/issues/89185 +void binding_to_label_loc() { + char *b = &&MyLabel; +MyLabel: + *b = 0; // no-crash + clang_analyzer_dump_ptr(b); // expected-warning {{&&MyLabel}} + clang_analyzer_dump(*b); // expected-warning {{Unknown}} +} `` https://github.com/llvm/llvm-project/pull/91119 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Check for label location bindings in `DereferenceChecker` (PR #91119)
https://github.com/Rajveer100 updated https://github.com/llvm/llvm-project/pull/91119 >From c1d62262d2545e4999f08f2ba28a12c71789926f Mon Sep 17 00:00:00 2001 From: Rajveer Date: Sun, 5 May 2024 18:05:00 +0530 Subject: [PATCH] [clang][analyzer] Check for label location bindings in `DereferenceChecker` Resolves #89264 --- .../StaticAnalyzer/Checkers/DereferenceChecker.cpp | 9 + clang/test/Analysis/Issue89264.c| 13 + 2 files changed, 22 insertions(+) create mode 100644 clang/test/Analysis/Issue89264.c diff --git a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp index 1cebfbbee77dae..36593d84dac583 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp @@ -287,6 +287,15 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S, if (V.isUndef()) return; + // One should never write to label addresses. + if (auto Label = L.getAs()) { +llvm::errs() << "WRITING TO LABEL: " << L << "\n"; +llvm::errs() << "Fatal Error: " + << "Dereference of the address of a label" + << "\n"; +return; + } + const MemRegion *MR = L.getAsRegion(); const TypedValueRegion *TVR = dyn_cast_or_null(MR); if (!TVR) diff --git a/clang/test/Analysis/Issue89264.c b/clang/test/Analysis/Issue89264.c new file mode 100644 index 00..1592bc20ee56f2 --- /dev/null +++ b/clang/test/Analysis/Issue89264.c @@ -0,0 +1,13 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s + +void clang_analyzer_dump(char); +void clang_analyzer_dump_ptr(char*); + +// https://github.com/llvm/llvm-project/issues/89185 +void binding_to_label_loc() { + char *b = &&MyLabel; +MyLabel: + *b = 0; // no-crash + clang_analyzer_dump_ptr(b); // expected-warning {{&&MyLabel}} + clang_analyzer_dump(*b); // expected-warning {{Unknown}} +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Check for label location bindings in `DereferenceChecker` (PR #91119)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff 72eaa0ed9934bfaa2449091bbc6e45648d1396d6 c1d62262d2545e4999f08f2ba28a12c71789926f -- clang/test/Analysis/Issue89264.c clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp `` View the diff from clang-format here. ``diff diff --git a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp index 36593d84da..2d23d23c6c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp @@ -290,8 +290,7 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S, // One should never write to label addresses. if (auto Label = L.getAs()) { llvm::errs() << "WRITING TO LABEL: " << L << "\n"; -llvm::errs() << "Fatal Error: " - << "Dereference of the address of a label" +llvm::errs() << "Fatal Error: " << "Dereference of the address of a label" << "\n"; return; } `` https://github.com/llvm/llvm-project/pull/91119 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Check for label location bindings in `DereferenceChecker` (PR #91119)
https://github.com/Rajveer100 updated https://github.com/llvm/llvm-project/pull/91119 >From dcc23f7751ba2ceb281a9b027907dbf849ba65c6 Mon Sep 17 00:00:00 2001 From: Rajveer Date: Sun, 5 May 2024 18:05:00 +0530 Subject: [PATCH] [clang][analyzer] Check for label location bindings in `DereferenceChecker` Resolves #89264 --- .../StaticAnalyzer/Checkers/DereferenceChecker.cpp | 8 clang/test/Analysis/Issue89264.c| 13 + 2 files changed, 21 insertions(+) create mode 100644 clang/test/Analysis/Issue89264.c diff --git a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp index 1cebfbbee77dae..2d23d23c6c82ba 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp @@ -287,6 +287,14 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S, if (V.isUndef()) return; + // One should never write to label addresses. + if (auto Label = L.getAs()) { +llvm::errs() << "WRITING TO LABEL: " << L << "\n"; +llvm::errs() << "Fatal Error: " << "Dereference of the address of a label" + << "\n"; +return; + } + const MemRegion *MR = L.getAsRegion(); const TypedValueRegion *TVR = dyn_cast_or_null(MR); if (!TVR) diff --git a/clang/test/Analysis/Issue89264.c b/clang/test/Analysis/Issue89264.c new file mode 100644 index 00..1592bc20ee56f2 --- /dev/null +++ b/clang/test/Analysis/Issue89264.c @@ -0,0 +1,13 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s + +void clang_analyzer_dump(char); +void clang_analyzer_dump_ptr(char*); + +// https://github.com/llvm/llvm-project/issues/89185 +void binding_to_label_loc() { + char *b = &&MyLabel; +MyLabel: + *b = 0; // no-crash + clang_analyzer_dump_ptr(b); // expected-warning {{&&MyLabel}} + clang_analyzer_dump(*b); // expected-warning {{Unknown}} +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Check for label location bindings in `DereferenceChecker` (PR #91119)
Rajveer100 wrote: @steakhal https://github.com/llvm/llvm-project/pull/91119 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Check for label location bindings in `DereferenceChecker` (PR #91119)
https://github.com/steakhal requested changes to this pull request. The `llvm::errs()` are for only debugging stuff. The print to the stderr. However, to form a bug report you need to use the `reportBug` here, and you also need to define a new `BugType` for representing this bug kind. Once that's done, you should have a fatal bug report at the dereference location, causing the path to sink and never reach the next statement where we would dump the value associated with that variable. The test is already present in the tree, as `clang/test/Analysis/gh-issue-89185.c`. If you implementation is correct, that test should fail because we report a new bug there. https://github.com/llvm/llvm-project/pull/91119 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [SCCP] Swap out range metadata to range attribute (PR #90134)
jsji wrote: With this, range attribute may prevent us from doing tailcall. eg: https://godbolt.org/z/7cfTqe4Wq A fix is proposed here: https://github.com/llvm/llvm-project/pull/91122 Please help to have a look. Thanks. https://github.com/llvm/llvm-project/pull/90134 ___ 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 `modernize-use-uniform-initializer` check (PR #91124)
https://github.com/AMS21 created https://github.com/llvm/llvm-project/pull/91124 Finds usage of C-Style initialization that can be rewritten with C++-11 uniform initializers. Background: For an upcoming project it will be a requirement for us to use C++-11 uniform initializers when ever possible instead of C-Style initialization. To help automate this (and hopefully prevent any point loss due to that requirement) I wrote this clang-tidy check. >From b46ceac9284c92b4ac55a5c489a0b7a8bff8d32e Mon Sep 17 00:00:00 2001 From: AMS21 Date: Tue, 16 Apr 2024 08:56:13 +0200 Subject: [PATCH] [clang-tidy] Add `modernize-use-uniform-initializer` check Finds usage of C-Style initialization that can be rewritten with C++-11 uniform initializers. --- .../clang-tidy/modernize/CMakeLists.txt | 1 + .../modernize/ModernizeTidyModule.cpp | 3 + .../modernize/UseUniformInitializerCheck.cpp | 318 ++ .../modernize/UseUniformInitializerCheck.h| 37 ++ .../clang-tidy/utils/LexerUtils.cpp | 23 ++ .../clang-tidy/utils/LexerUtils.h | 4 + clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 1 + .../modernize/use-uniform-initializer.rst | 34 ++ .../modernize/use-uniform-initializer.cpp | 174 ++ 10 files changed, 601 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-uniform-initializer.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/use-uniform-initializer.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index 8005d6e91c060c..ee88eeda2eaa32 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -46,6 +46,7 @@ add_clang_library(clangTidyModernizeModule UseTrailingReturnTypeCheck.cpp UseTransparentFunctorsCheck.cpp UseUncaughtExceptionsCheck.cpp + UseUniformInitializerCheck.cpp UseUsingCheck.cpp LINK_LIBS diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 776558433c5baa..ecb88b0bb0fda5 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -47,6 +47,7 @@ #include "UseTrailingReturnTypeCheck.h" #include "UseTransparentFunctorsCheck.h" #include "UseUncaughtExceptionsCheck.h" +#include "UseUniformInitializerCheck.h" #include "UseUsingCheck.h" using namespace clang::ast_matchers; @@ -117,6 +118,8 @@ class ModernizeModule : public ClangTidyModule { "modernize-use-transparent-functors"); CheckFactories.registerCheck( "modernize-use-uncaught-exceptions"); +CheckFactories.registerCheck( +"modernize-use-uniform-initializer"); CheckFactories.registerCheck("modernize-use-using"); } }; diff --git a/clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp new file mode 100644 index 00..187470523cfaf0 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp @@ -0,0 +1,318 @@ +//===--- UseUniformInitializerCheck.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 "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} + +using name
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
llvmbot wrote: @llvm/pr-subscribers-clang-tidy Author: None (AMS21) Changes Finds usage of C-Style initialization that can be rewritten with C++-11 uniform initializers. Background: For an upcoming project it will be a requirement for us to use C++-11 uniform initializers when ever possible instead of C-Style initialization. To help automate this (and hopefully prevent any point loss due to that requirement) I wrote this clang-tidy check. --- Patch is 26.49 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/91124.diff 10 Files Affected: - (modified) clang-tools-extra/clang-tidy/modernize/CMakeLists.txt (+1) - (modified) clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp (+3) - (added) clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp (+318) - (added) clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.h (+37) - (modified) clang-tools-extra/clang-tidy/utils/LexerUtils.cpp (+23) - (modified) clang-tools-extra/clang-tidy/utils/LexerUtils.h (+4) - (modified) clang-tools-extra/docs/ReleaseNotes.rst (+6) - (modified) clang-tools-extra/docs/clang-tidy/checks/list.rst (+1) - (added) clang-tools-extra/docs/clang-tidy/checks/modernize/use-uniform-initializer.rst (+34) - (added) clang-tools-extra/test/clang-tidy/checkers/modernize/use-uniform-initializer.cpp (+174) ``diff diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index 8005d6e91c060c..ee88eeda2eaa32 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -46,6 +46,7 @@ add_clang_library(clangTidyModernizeModule UseTrailingReturnTypeCheck.cpp UseTransparentFunctorsCheck.cpp UseUncaughtExceptionsCheck.cpp + UseUniformInitializerCheck.cpp UseUsingCheck.cpp LINK_LIBS diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 776558433c5baa..ecb88b0bb0fda5 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -47,6 +47,7 @@ #include "UseTrailingReturnTypeCheck.h" #include "UseTransparentFunctorsCheck.h" #include "UseUncaughtExceptionsCheck.h" +#include "UseUniformInitializerCheck.h" #include "UseUsingCheck.h" using namespace clang::ast_matchers; @@ -117,6 +118,8 @@ class ModernizeModule : public ClangTidyModule { "modernize-use-transparent-functors"); CheckFactories.registerCheck( "modernize-use-uncaught-exceptions"); +CheckFactories.registerCheck( +"modernize-use-uniform-initializer"); CheckFactories.registerCheck("modernize-use-using"); } }; diff --git a/clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp new file mode 100644 index 00..187470523cfaf0 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp @@ -0,0 +1,318 @@ +//===--- UseUniformInitializerCheck.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 "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +constexpr const StringRef VarDeclID = "VarDecl"; +constexpr const StringRef FieldDeclId = "FieldDecl"; +constexpr const StringRef CtorInitID = "CtorInit"; + +constexpr const StringRef CStyleWarningMessage = +"Use uniform initializer instead of C-style
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
llvmbot wrote: @llvm/pr-subscribers-clang-tools-extra Author: None (AMS21) Changes Finds usage of C-Style initialization that can be rewritten with C++-11 uniform initializers. Background: For an upcoming project it will be a requirement for us to use C++-11 uniform initializers when ever possible instead of C-Style initialization. To help automate this (and hopefully prevent any point loss due to that requirement) I wrote this clang-tidy check. --- Patch is 26.49 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/91124.diff 10 Files Affected: - (modified) clang-tools-extra/clang-tidy/modernize/CMakeLists.txt (+1) - (modified) clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp (+3) - (added) clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp (+318) - (added) clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.h (+37) - (modified) clang-tools-extra/clang-tidy/utils/LexerUtils.cpp (+23) - (modified) clang-tools-extra/clang-tidy/utils/LexerUtils.h (+4) - (modified) clang-tools-extra/docs/ReleaseNotes.rst (+6) - (modified) clang-tools-extra/docs/clang-tidy/checks/list.rst (+1) - (added) clang-tools-extra/docs/clang-tidy/checks/modernize/use-uniform-initializer.rst (+34) - (added) clang-tools-extra/test/clang-tidy/checkers/modernize/use-uniform-initializer.cpp (+174) ``diff diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index 8005d6e91c060c..ee88eeda2eaa32 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -46,6 +46,7 @@ add_clang_library(clangTidyModernizeModule UseTrailingReturnTypeCheck.cpp UseTransparentFunctorsCheck.cpp UseUncaughtExceptionsCheck.cpp + UseUniformInitializerCheck.cpp UseUsingCheck.cpp LINK_LIBS diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 776558433c5baa..ecb88b0bb0fda5 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -47,6 +47,7 @@ #include "UseTrailingReturnTypeCheck.h" #include "UseTransparentFunctorsCheck.h" #include "UseUncaughtExceptionsCheck.h" +#include "UseUniformInitializerCheck.h" #include "UseUsingCheck.h" using namespace clang::ast_matchers; @@ -117,6 +118,8 @@ class ModernizeModule : public ClangTidyModule { "modernize-use-transparent-functors"); CheckFactories.registerCheck( "modernize-use-uncaught-exceptions"); +CheckFactories.registerCheck( +"modernize-use-uniform-initializer"); CheckFactories.registerCheck("modernize-use-using"); } }; diff --git a/clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp new file mode 100644 index 00..187470523cfaf0 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp @@ -0,0 +1,318 @@ +//===--- UseUniformInitializerCheck.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 "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +constexpr const StringRef VarDeclID = "VarDecl"; +constexpr const StringRef FieldDeclId = "FieldDecl"; +constexpr const StringRef CtorInitID = "CtorInit"; + +constexpr const StringRef CStyleWarningMessage = +"Use uniform initializer instead of
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff a415b4dfcc02e3e82b8c8a7836f7c04b9d65dc9b b46ceac9284c92b4ac55a5c489a0b7a8bff8d32e -- clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.h clang-tools-extra/test/clang-tidy/checkers/modernize/use-uniform-initializer.cpp clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp clang-tools-extra/clang-tidy/utils/LexerUtils.cpp clang-tools-extra/clang-tidy/utils/LexerUtils.h `` View the diff from clang-format here. ``diff diff --git a/clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp index 187470523c..204a42d8c8 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp @@ -130,7 +130,8 @@ std::string buildReplacementString(const Expr *InitExpr, const ASTContext &Context) { // TODO: This function does not correctly handle the case where you have in // 'ImplicitCastExpr' as an argument for a 'CXXConstructExpr'. - // In that case the generated code will not compile due to missing explicit cast of the sub expression. + // In that case the generated code will not compile due to missing explicit + // cast of the sub expression. const SourceManager &SM = Context.getSourceManager(); const LangOptions &LangOpts = Context.getLangOpts(); @@ -141,20 +142,21 @@ std::string buildReplacementString(const Expr *InitExpr, const SourceRange ParenRange = ConstructExpr->getParenOrBraceRange(); if (ParenRange.isValid()) -return Lexer::getSourceText(CharSourceRange::getCharRange( - ParenRange.getBegin().getLocWithOffset(1), - ParenRange.getEnd()), - SM, LangOpts) - .trim(); +return Lexer::getSourceText( + CharSourceRange::getCharRange( + ParenRange.getBegin().getLocWithOffset(1), + ParenRange.getEnd()), + SM, LangOpts) +.trim(); // In case the ParenRange is invalid we use Begin/EndLoc const SourceLocation BeginLocation = ConstructExpr->getBeginLoc(); const SourceLocation EndLocation = ConstructExpr->getEndLoc(); - return Lexer::getSourceText(CharSourceRange::getCharRange( - BeginLocation, - EndLocation.getLocWithOffset(1)), - SM, LangOpts) + return Lexer::getSourceText( + CharSourceRange::getCharRange(BeginLocation, + EndLocation.getLocWithOffset(1)), + SM, LangOpts) .trim(); } `` https://github.com/llvm/llvm-project/pull/91124 ___ 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 `modernize-use-uniform-initializer` check (PR #91124)
https://github.com/AMS21 updated https://github.com/llvm/llvm-project/pull/91124 >From 369bb3fe0b47872a06adb89e0414a56c26904e2c Mon Sep 17 00:00:00 2001 From: AMS21 Date: Tue, 16 Apr 2024 08:56:13 +0200 Subject: [PATCH] [clang-tidy] Add `modernize-use-uniform-initializer` check Finds usage of C-Style initialization that can be rewritten with C++-11 uniform initializers. --- .../clang-tidy/modernize/CMakeLists.txt | 1 + .../modernize/ModernizeTidyModule.cpp | 3 + .../modernize/UseUniformInitializerCheck.cpp | 320 ++ .../modernize/UseUniformInitializerCheck.h| 37 ++ .../clang-tidy/utils/LexerUtils.cpp | 23 ++ .../clang-tidy/utils/LexerUtils.h | 4 + clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 1 + .../modernize/use-uniform-initializer.rst | 34 ++ .../modernize/use-uniform-initializer.cpp | 174 ++ 10 files changed, 603 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-uniform-initializer.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/use-uniform-initializer.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index 8005d6e91c060c..ee88eeda2eaa32 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -46,6 +46,7 @@ add_clang_library(clangTidyModernizeModule UseTrailingReturnTypeCheck.cpp UseTransparentFunctorsCheck.cpp UseUncaughtExceptionsCheck.cpp + UseUniformInitializerCheck.cpp UseUsingCheck.cpp LINK_LIBS diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 776558433c5baa..ecb88b0bb0fda5 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -47,6 +47,7 @@ #include "UseTrailingReturnTypeCheck.h" #include "UseTransparentFunctorsCheck.h" #include "UseUncaughtExceptionsCheck.h" +#include "UseUniformInitializerCheck.h" #include "UseUsingCheck.h" using namespace clang::ast_matchers; @@ -117,6 +118,8 @@ class ModernizeModule : public ClangTidyModule { "modernize-use-transparent-functors"); CheckFactories.registerCheck( "modernize-use-uncaught-exceptions"); +CheckFactories.registerCheck( +"modernize-use-uniform-initializer"); CheckFactories.registerCheck("modernize-use-using"); } }; diff --git a/clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp new file mode 100644 index 00..204a42d8c81895 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseUniformInitializerCheck.cpp @@ -0,0 +1,320 @@ +//===--- UseUniformInitializerCheck.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 "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +constexpr const StringRef VarDeclID = "VarDecl"; +constexpr const StringRef FieldDeclId = "FieldDecl"; +constexpr const StringRef CtorInitID = "CtorInit"; + +constexpr const StringRef CStyleWarningMessage = +"Use uniform initializer instead of C-style initializer"; + +constexpr StringR
[clang-tools-extra] [clang-tidy] Improve modernize-use-std-print diagnostic (PR #91071)
https://github.com/PiotrZSL approved this pull request. https://github.com/llvm/llvm-project/pull/91071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 7e4d16d - [clang-tidy] Improve modernize-use-std-print diagnostic (#91071)
Author: Mike Crowe Date: 2024-05-05T17:20:31+02:00 New Revision: 7e4d16d73c22079997dd59d8e7d8f41bdbac5a50 URL: https://github.com/llvm/llvm-project/commit/7e4d16d73c22079997dd59d8e7d8f41bdbac5a50 DIFF: https://github.com/llvm/llvm-project/commit/7e4d16d73c22079997dd59d8e7d8f41bdbac5a50.diff LOG: [clang-tidy] Improve modernize-use-std-print diagnostic (#91071) Include the source range of the printf function in the diagnostic so it gets underlined in the output. Added: Modified: clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp Removed: diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp index 660996aba7b70d..aa60c904a363da 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp @@ -138,7 +138,8 @@ void UseStdPrintCheck::check(const MatchFinder::MatchResult &Result) { if (!Converter.canApply()) { diag(PrintfCall->getBeginLoc(), "unable to use '%0' instead of %1 because %2") -<< ReplacementFunction << OldFunction->getIdentifier() +<< PrintfCall->getSourceRange() << ReplacementFunction +<< OldFunction->getIdentifier() << Converter.conversionNotPossibleReason(); return; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Improve modernize-use-std-print diagnostic (PR #91071)
https://github.com/PiotrZSL closed https://github.com/llvm/llvm-project/pull/91071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 9aad38b - [clang-tidy] fix false-positives for templates in `bugprone-return-const-ref-from-parameter` (#90273)
Author: Julian Schmidt Date: 2024-05-05T17:51:33+02:00 New Revision: 9aad38b61586cab8b125c3f522789267f9b749a9 URL: https://github.com/llvm/llvm-project/commit/9aad38b61586cab8b125c3f522789267f9b749a9 DIFF: https://github.com/llvm/llvm-project/commit/9aad38b61586cab8b125c3f522789267f9b749a9.diff LOG: [clang-tidy] fix false-positives for templates in `bugprone-return-const-ref-from-parameter` (#90273) In the AST for function templates, the return will be a DeclRefExpr, even if the return type differs from that of the returned variable. Protect against false-positives by constraining the canonical return type to be that of the parameter. Also streams the source range of the returned expression into the diagnostic. Added: Modified: clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone/return-const-ref-from-parameter.cpp Removed: diff --git a/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp index 8ae37d4f774d23..b3f7dd6d1c86f8 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp @@ -17,8 +17,11 @@ namespace clang::tidy::bugprone { void ReturnConstRefFromParameterCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( - returnStmt(hasReturnValue(declRefExpr(to(parmVarDecl(hasType( - hasCanonicalType(matchers::isReferenceToConst( + returnStmt( + hasReturnValue(declRefExpr(to(parmVarDecl(hasType(hasCanonicalType( + qualType(matchers::isReferenceToConst()).bind("type"))), + hasAncestor(functionDecl(hasReturnTypeLoc( + loc(qualType(hasCanonicalType(equalsBoundNode("type" .bind("ret"), this); } @@ -28,7 +31,8 @@ void ReturnConstRefFromParameterCheck::check( const auto *R = Result.Nodes.getNodeAs("ret"); diag(R->getRetValue()->getBeginLoc(), "returning a constant reference parameter may cause a use-after-free " - "when the parameter is constructed from a temporary"); + "when the parameter is constructed from a temporary") + << R->getRetValue()->getSourceRange(); } } // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/return-const-ref-from-parameter.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/return-const-ref-from-parameter.cpp index a83a019ec7437d..ca41bdf74a1073 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/return-const-ref-from-parameter.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/return-const-ref-from-parameter.cpp @@ -1,9 +1,18 @@ -// RUN: %check_clang_tidy %s bugprone-return-const-ref-from-parameter %t +// RUN: %check_clang_tidy %s bugprone-return-const-ref-from-parameter %t -- -- -fno-delayed-template-parsing using T = int; using TConst = int const; using TConstRef = int const&; +template +struct Wrapper { Wrapper(T); }; + +template +struct Identity { using type = T; }; + +template +struct ConstRef { using type = const T&; }; + namespace invalid { int const &f1(int const &a) { return a; } @@ -18,8 +27,59 @@ int const &f3(TConstRef a) { return a; } int const &f4(TConst &a) { return a; } // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: returning a constant reference parameter +template +const T& tf1(const T &a) { return a; } +// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: returning a constant reference parameter + +template +const T& itf1(const T &a) { return a; } +// CHECK-MESSAGES: :[[@LINE-1]]:36: warning: returning a constant reference parameter + +template +typename ConstRef::type itf2(const T &a) { return a; } +// CHECK-MESSAGES: :[[@LINE-1]]:54: warning: returning a constant reference parameter + +template +typename ConstRef::type itf3(typename ConstRef::type a) { return a; } +// CHECK-MESSAGES: :[[@LINE-1]]:72: warning: returning a constant reference parameter + +template +const T& itf4(typename ConstRef::type a) { return a; } +// CHECK-MESSAGES: :[[@LINE-1]]:54: warning: returning a constant reference parameter + +void instantiate(const int ¶m, const float ¶mf, int &mut_param, float &mut_paramf) { +itf1(0); +itf1(param); +itf1(paramf); +itf2(0); +itf2(param); +itf2(paramf); +itf3(0); +itf3(param); +itf3(paramf); +itf4(0); +itf4(param); +itf4(paramf); +} + +struct C { +const C& foo(const C&c) { return c; } +// CHECK-MESSAGES: :[[@LINE-1]]:38: warning: returning a constant reference parameter +}; + } // namespace invalid +namespace false_negative_because_dependent_and_not_instantiated { +template +typename Const
[clang-tools-extra] [clang-tidy] fix false-positives for templates in `bugprone-return-const-ref-from-parameter` (PR #90273)
https://github.com/5chmidti closed https://github.com/llvm/llvm-project/pull/90273 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 716eab7 - [clang-tidy][docs] Fix modernize-use-std-print docs (#91069)
Author: Mike Crowe Date: 2024-05-05T17:52:59+02:00 New Revision: 716eab783713cc99046c89478c126b1a2e000940 URL: https://github.com/llvm/llvm-project/commit/716eab783713cc99046c89478c126b1a2e000940 DIFF: https://github.com/llvm/llvm-project/commit/716eab783713cc99046c89478c126b1a2e000940.diff LOG: [clang-tidy][docs] Fix modernize-use-std-print docs (#91069) The set of functions for the PrintfLikeFunctions and FprintfLikeFunctions options replaces the default, so remove the word "extra" from the description which implies that they are in addition to the default. Added: Modified: clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-print.rst Removed: diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-print.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-print.rst index 9bb691e9d9512e..79648a1104bca2 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-print.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-print.rst @@ -118,7 +118,7 @@ Options .. option:: PrintfLikeFunctions - A semicolon-separated list of (fully qualified) extra function names to + A semicolon-separated list of (fully qualified) function names to replace, with the requirement that the first parameter contains the printf-style format string and the arguments to be formatted follow immediately afterwards. If neither this option nor @@ -128,7 +128,7 @@ Options .. option:: FprintfLikeFunctions - A semicolon-separated list of (fully qualified) extra function names to + A semicolon-separated list of (fully qualified) function names to replace, with the requirement that the first parameter is retained, the second parameter contains the printf-style format string and the arguments to be formatted follow immediately afterwards. If neither this ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][docs] Fix modernize-use-std-print docs (PR #91069)
https://github.com/5chmidti closed https://github.com/llvm/llvm-project/pull/91069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AArch64] Support preserve_none calling convention (PR #91046)
https://github.com/antangelo updated https://github.com/llvm/llvm-project/pull/91046 >From 767173a0dfde9858c90867cc5d476da90e5ba898 Mon Sep 17 00:00:00 2001 From: Antonio Abbatangelo Date: Tue, 30 Apr 2024 22:58:18 -0400 Subject: [PATCH 1/3] [AArch64] Support preserve_none calling convention --- clang/include/clang/Basic/Attr.td | 3 +- clang/include/clang/Basic/AttrDocs.td | 19 +- clang/lib/Basic/Targets/AArch64.cpp | 1 + clang/test/CodeGen/preserve-call-conv.c | 6 +- llvm/docs/LangRef.rst | 2 +- .../Target/AArch64/AArch64CallingConvention.h | 3 + .../AArch64/AArch64CallingConvention.td | 27 ++ .../Target/AArch64/AArch64ISelLowering.cpp| 34 +- .../Target/AArch64/AArch64RegisterInfo.cpp| 12 +- .../AArch64/GISel/AArch64CallLowering.cpp | 1 + .../AArch64/dynamic-regmask-preserve-none.ll | 88 + llvm/test/CodeGen/AArch64/preserve.ll | 9 +- llvm/test/CodeGen/AArch64/preserve_nonecc.ll | 92 + .../CodeGen/AArch64/preserve_nonecc_call.ll | 325 ++ .../AArch64/preserve_nonecc_musttail.ll | 11 + .../CodeGen/AArch64/preserve_nonecc_swift.ll | 16 + 16 files changed, 631 insertions(+), 18 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/dynamic-regmask-preserve-none.ll create mode 100644 llvm/test/CodeGen/AArch64/preserve_nonecc.ll create mode 100644 llvm/test/CodeGen/AArch64/preserve_nonecc_call.ll create mode 100644 llvm/test/CodeGen/AArch64/preserve_nonecc_musttail.ll create mode 100644 llvm/test/CodeGen/AArch64/preserve_nonecc_swift.ll diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 0225598cbbe8ad..712c79927304e2 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3038,7 +3038,8 @@ def M68kRTD: DeclOrTypeAttr { let Documentation = [M68kRTDDocs]; } -def PreserveNone : DeclOrTypeAttr, TargetSpecificAttr { +def PreserveNone : DeclOrTypeAttr, + TargetSpecificAttr> { let Spellings = [Clang<"preserve_none">]; let Subjects = SubjectList<[FunctionLike]>; let Documentation = [PreserveNoneDocs]; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index f8253143b596c0..d23465b77e7edd 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -5658,17 +5658,20 @@ experimental at this time. def PreserveNoneDocs : Documentation { let Category = DocCatCallingConvs; let Content = [{ -On X86-64 target, this attribute changes the calling convention of a function. +On X86-64 and AArch64 targets, this attribute changes the calling convention of a function. The ``preserve_none`` calling convention tries to preserve as few general registers as possible. So all general registers are caller saved registers. It also uses more general registers to pass arguments. This attribute doesn't -impact floating-point registers (XMMs/YMMs). Floating-point registers still -follow the c calling convention. - -- Only RSP and RBP are preserved by callee. - -- Register RDI, RSI, RDX, RCX, R8, R9, R11, R12, R13, R14, R15 and RAX now can - be used to pass function arguments. +impact floating-point registers. + +- On X86-64, only RSP and RBP are preserved by the callee. + Registers RDI, RSI, RDX, RCX, R8, R9, R11, R12, R13, R14, R15 and RAX now can + be used to pass function arguments. Floating-point registers (XMMs/YMMs) still + follow the C calling convention. +- On AArch64, only LR and FP are preserved by the callee. + Registers X19-X28 and X0-X17 are used to pass function arguments. + X18, SIMD and floating-point registers follow the AAPCS calling + convention. }]; } diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index c8d243a8fb7aea..e1f7dbf1d9f20b 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -1202,6 +1202,7 @@ AArch64TargetInfo::checkCallingConvention(CallingConv CC) const { case CC_SwiftAsync: case CC_PreserveMost: case CC_PreserveAll: + case CC_PreserveNone: case CC_OpenCLKernel: case CC_AArch64VectorCall: case CC_AArch64SVEPCS: diff --git a/clang/test/CodeGen/preserve-call-conv.c b/clang/test/CodeGen/preserve-call-conv.c index 74bf695e6f331d..65973206403f70 100644 --- a/clang/test/CodeGen/preserve-call-conv.c +++ b/clang/test/CodeGen/preserve-call-conv.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm < %s | FileCheck %s --check-prefixes=CHECK,X86-LINUX -// RUN: %clang_cc1 -triple arm64-unknown-unknown -emit-llvm < %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm < %s | FileCheck %s --check-prefixes=CHECK,LINUX +// RUN: %clang_cc1 -triple arm64-unknown-unknown -emit-llvm < %s | FileCheck %s --check-prefixes=CHECK,LINUX // RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -emit-llvm
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
aganea wrote: Hello, This causes a warning when building LLDB on Windows, `clang::BuiltinType::UnresolvedTemplate` isn't handled in the case in the file indicated below (sorry my locale is French). Would you have a chance to take a look @zyn0217 please? ``` [6325/7521] Building CXX object tools\lldb\source\Plugins\TypeSystem\Clang\CMakeFiles\lldbPluginTypeSystemClang.dir\TypeSystemClang.cpp.obj C:\src\git\llvm-project\lldb\source\Plugins\TypeSystem\Clang\TypeSystemClang.cpp(4999): warning C4062: L'énumérateur 'clang::BuiltinType::UnresolvedTemplate' dans le commutateur de l'énumération 'clang::BuiltinType::Kind' n'est pas géré. C:\src\git\llvm-project\clang\include\clang/AST/Type.h(2983): note: voir la déclaration de 'clang::BuiltinType::Kind' ``` https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AArch64] Support preserve_none calling convention (PR #91046)
@@ -5658,17 +5658,20 @@ experimental at this time. def PreserveNoneDocs : Documentation { let Category = DocCatCallingConvs; let Content = [{ -On X86-64 target, this attribute changes the calling convention of a function. +On X86-64 and AArch64 targets, this attribute changes the calling convention of a function. The ``preserve_none`` calling convention tries to preserve as few general registers as possible. So all general registers are caller saved registers. It also uses more general registers to pass arguments. This attribute doesn't -impact floating-point registers (XMMs/YMMs). Floating-point registers still -follow the c calling convention. - -- Only RSP and RBP are preserved by callee. - -- Register RDI, RSI, RDX, RCX, R8, R9, R11, R12, R13, R14, R15 and RAX now can - be used to pass function arguments. +impact floating-point registers. + +- On X86-64, only RSP and RBP are preserved by the callee. + Registers RDI, RSI, RDX, RCX, R8, R9, R11, R12, R13, R14, R15 and RAX now can + be used to pass function arguments. Floating-point registers (XMMs/YMMs) still + follow the C calling convention. +- On AArch64, only LR and FP are preserved by the callee. + Registers X19-X28 and X0-X17 are used to pass function arguments. pinskia wrote: Even though you removed X16/X17 you seemly forgot to update the documentation. https://github.com/llvm/llvm-project/pull/91046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AArch64] Support preserve_none calling convention (PR #91046)
https://github.com/antangelo updated https://github.com/llvm/llvm-project/pull/91046 >From 767173a0dfde9858c90867cc5d476da90e5ba898 Mon Sep 17 00:00:00 2001 From: Antonio Abbatangelo Date: Tue, 30 Apr 2024 22:58:18 -0400 Subject: [PATCH 1/5] [AArch64] Support preserve_none calling convention --- clang/include/clang/Basic/Attr.td | 3 +- clang/include/clang/Basic/AttrDocs.td | 19 +- clang/lib/Basic/Targets/AArch64.cpp | 1 + clang/test/CodeGen/preserve-call-conv.c | 6 +- llvm/docs/LangRef.rst | 2 +- .../Target/AArch64/AArch64CallingConvention.h | 3 + .../AArch64/AArch64CallingConvention.td | 27 ++ .../Target/AArch64/AArch64ISelLowering.cpp| 34 +- .../Target/AArch64/AArch64RegisterInfo.cpp| 12 +- .../AArch64/GISel/AArch64CallLowering.cpp | 1 + .../AArch64/dynamic-regmask-preserve-none.ll | 88 + llvm/test/CodeGen/AArch64/preserve.ll | 9 +- llvm/test/CodeGen/AArch64/preserve_nonecc.ll | 92 + .../CodeGen/AArch64/preserve_nonecc_call.ll | 325 ++ .../AArch64/preserve_nonecc_musttail.ll | 11 + .../CodeGen/AArch64/preserve_nonecc_swift.ll | 16 + 16 files changed, 631 insertions(+), 18 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/dynamic-regmask-preserve-none.ll create mode 100644 llvm/test/CodeGen/AArch64/preserve_nonecc.ll create mode 100644 llvm/test/CodeGen/AArch64/preserve_nonecc_call.ll create mode 100644 llvm/test/CodeGen/AArch64/preserve_nonecc_musttail.ll create mode 100644 llvm/test/CodeGen/AArch64/preserve_nonecc_swift.ll diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 0225598cbbe8ad..712c79927304e2 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3038,7 +3038,8 @@ def M68kRTD: DeclOrTypeAttr { let Documentation = [M68kRTDDocs]; } -def PreserveNone : DeclOrTypeAttr, TargetSpecificAttr { +def PreserveNone : DeclOrTypeAttr, + TargetSpecificAttr> { let Spellings = [Clang<"preserve_none">]; let Subjects = SubjectList<[FunctionLike]>; let Documentation = [PreserveNoneDocs]; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index f8253143b596c0..d23465b77e7edd 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -5658,17 +5658,20 @@ experimental at this time. def PreserveNoneDocs : Documentation { let Category = DocCatCallingConvs; let Content = [{ -On X86-64 target, this attribute changes the calling convention of a function. +On X86-64 and AArch64 targets, this attribute changes the calling convention of a function. The ``preserve_none`` calling convention tries to preserve as few general registers as possible. So all general registers are caller saved registers. It also uses more general registers to pass arguments. This attribute doesn't -impact floating-point registers (XMMs/YMMs). Floating-point registers still -follow the c calling convention. - -- Only RSP and RBP are preserved by callee. - -- Register RDI, RSI, RDX, RCX, R8, R9, R11, R12, R13, R14, R15 and RAX now can - be used to pass function arguments. +impact floating-point registers. + +- On X86-64, only RSP and RBP are preserved by the callee. + Registers RDI, RSI, RDX, RCX, R8, R9, R11, R12, R13, R14, R15 and RAX now can + be used to pass function arguments. Floating-point registers (XMMs/YMMs) still + follow the C calling convention. +- On AArch64, only LR and FP are preserved by the callee. + Registers X19-X28 and X0-X17 are used to pass function arguments. + X18, SIMD and floating-point registers follow the AAPCS calling + convention. }]; } diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index c8d243a8fb7aea..e1f7dbf1d9f20b 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -1202,6 +1202,7 @@ AArch64TargetInfo::checkCallingConvention(CallingConv CC) const { case CC_SwiftAsync: case CC_PreserveMost: case CC_PreserveAll: + case CC_PreserveNone: case CC_OpenCLKernel: case CC_AArch64VectorCall: case CC_AArch64SVEPCS: diff --git a/clang/test/CodeGen/preserve-call-conv.c b/clang/test/CodeGen/preserve-call-conv.c index 74bf695e6f331d..65973206403f70 100644 --- a/clang/test/CodeGen/preserve-call-conv.c +++ b/clang/test/CodeGen/preserve-call-conv.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm < %s | FileCheck %s --check-prefixes=CHECK,X86-LINUX -// RUN: %clang_cc1 -triple arm64-unknown-unknown -emit-llvm < %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm < %s | FileCheck %s --check-prefixes=CHECK,LINUX +// RUN: %clang_cc1 -triple arm64-unknown-unknown -emit-llvm < %s | FileCheck %s --check-prefixes=CHECK,LINUX // RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -emit-llvm
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,320 @@ +//===--- UseUniformInitializerCheck.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 "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +constexpr const StringRef VarDeclID = "VarDecl"; +constexpr const StringRef FieldDeclId = "FieldDecl"; +constexpr const StringRef CtorInitID = "CtorInit"; + +constexpr const StringRef CStyleWarningMessage = +"Use uniform initializer instead of C-style initializer"; + +constexpr StringRef +getInitializerStyleName(VarDecl::InitializationStyle InitStyle) { + switch (InitStyle) { + case VarDecl::InitializationStyle::CInit: +return "C"; + + case VarDecl::InitializationStyle::CallInit: +return "call"; + + default: +llvm_unreachable("Invalid initializer style!"); + } +} + +SourceRange getParenLocationsForCallInit(const Expr *InitExpr, + const SourceManager &SM, + const LangOptions &LangOpts) { + // We need to handle 'CXXConstructExpr' differently + if (isa(InitExpr)) +return cast(InitExpr)->getParenOrBraceRange(); + + // If the init expression itself is a 'ParenExpr' then + // 'InitExpr->getBeginLoc()' will already point to a '(' which is not the + // opening paren of the 'CallInit' expression. So it that case we need to + // start one character before that. + const bool NeedOffsetForOpenParen = [&]() { +if (!isa(InitExpr)) + return false; + +const clang::StringRef CharBeforeParenExpr = +Lexer::getSourceText(CharSourceRange::getCharRange( + InitExpr->getBeginLoc().getLocWithOffset(-1), + InitExpr->getBeginLoc()), + SM, LangOpts); + +return llvm::isSpace(CharBeforeParenExpr[0]); + }(); + + const SourceLocation OpenParenLoc = utils::lexer::findPreviousTokenKind( + NeedOffsetForOpenParen ? InitExpr->getBeginLoc().getLocWithOffset(-1) + : InitExpr->getBeginLoc(), + SM, LangOpts, tok::l_paren); + const SourceLocation CloseParenLoc = utils::lexer::findNextTokenKind( + InitExpr->getEndLoc(), SM, LangOpts, tok::r_paren); + + return {OpenParenLoc, CloseParenLoc}; +} + +const BuiltinType *getBuiltinType(const Expr *Expr) { + assert(Expr); + return Expr->getType().getCanonicalType().getTypePtr()->getAs(); +} + +bool castRequiresStaticCast(const ImplicitCastExpr *CastExpr) { + const auto *FromExpr = CastExpr->getSubExpr(); + + if (CastExpr->isInstantiationDependent() || + FromExpr->isInstantiationDependent()) +return false; + if (getBuiltinType(CastExpr) == getBuiltinType(FromExpr)) +return false; + + switch (CastExpr->getCastKind()) { + case CastKind::CK_BaseToDerived: + case CastKind::CK_DerivedToBaseMemberPointer: + case CastKind::CK_IntegralCast: + case CastKind::CK_FloatingToIntegral: +return true; + + default: +return false; + } +} + +std::string buildReplacementString(const Expr *InitExpr, + const ASTContext &Context) { + // TODO: This function does not correctly handle the case where you have in + // 'ImplicitCastExpr' as an argument for a 'CXXConstructExpr'. + // In that case the generated code will not compile due to missing explicit + // cast of the sub expression. + + const SourceManager &SM = Context.getSourceManager(); + const LangOptions &LangOpts = Context.getLangOpts(); + + const StringRef InitExprStr = [&]() { +if (isa(InitExpr)) { + const auto *ConstructExpr = llvm::cast(InitExpr); --
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,320 @@ +//===--- UseUniformInitializerCheck.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 "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +constexpr const StringRef VarDeclID = "VarDecl"; +constexpr const StringRef FieldDeclId = "FieldDecl"; +constexpr const StringRef CtorInitID = "CtorInit"; + +constexpr const StringRef CStyleWarningMessage = +"Use uniform initializer instead of C-style initializer"; + +constexpr StringRef +getInitializerStyleName(VarDecl::InitializationStyle InitStyle) { + switch (InitStyle) { + case VarDecl::InitializationStyle::CInit: +return "C"; + + case VarDecl::InitializationStyle::CallInit: +return "call"; + + default: +llvm_unreachable("Invalid initializer style!"); + } +} + +SourceRange getParenLocationsForCallInit(const Expr *InitExpr, + const SourceManager &SM, + const LangOptions &LangOpts) { + // We need to handle 'CXXConstructExpr' differently + if (isa(InitExpr)) +return cast(InitExpr)->getParenOrBraceRange(); PiotrZSL wrote: use dyn_cast https://github.com/llvm/llvm-project/pull/91124 ___ 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 `modernize-use-uniform-initializer` check (PR #91124)
https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/91124 ___ 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 `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,320 @@ +//===--- UseUniformInitializerCheck.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 "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +constexpr const StringRef VarDeclID = "VarDecl"; +constexpr const StringRef FieldDeclId = "FieldDecl"; +constexpr const StringRef CtorInitID = "CtorInit"; + +constexpr const StringRef CStyleWarningMessage = +"Use uniform initializer instead of C-style initializer"; + +constexpr StringRef +getInitializerStyleName(VarDecl::InitializationStyle InitStyle) { + switch (InitStyle) { + case VarDecl::InitializationStyle::CInit: +return "C"; + + case VarDecl::InitializationStyle::CallInit: +return "call"; + + default: +llvm_unreachable("Invalid initializer style!"); + } +} + +SourceRange getParenLocationsForCallInit(const Expr *InitExpr, + const SourceManager &SM, + const LangOptions &LangOpts) { + // We need to handle 'CXXConstructExpr' differently + if (isa(InitExpr)) +return cast(InitExpr)->getParenOrBraceRange(); + + // If the init expression itself is a 'ParenExpr' then + // 'InitExpr->getBeginLoc()' will already point to a '(' which is not the + // opening paren of the 'CallInit' expression. So it that case we need to + // start one character before that. + const bool NeedOffsetForOpenParen = [&]() { +if (!isa(InitExpr)) + return false; + +const clang::StringRef CharBeforeParenExpr = +Lexer::getSourceText(CharSourceRange::getCharRange( + InitExpr->getBeginLoc().getLocWithOffset(-1), + InitExpr->getBeginLoc()), + SM, LangOpts); + +return llvm::isSpace(CharBeforeParenExpr[0]); + }(); + + const SourceLocation OpenParenLoc = utils::lexer::findPreviousTokenKind( + NeedOffsetForOpenParen ? InitExpr->getBeginLoc().getLocWithOffset(-1) + : InitExpr->getBeginLoc(), + SM, LangOpts, tok::l_paren); + const SourceLocation CloseParenLoc = utils::lexer::findNextTokenKind( + InitExpr->getEndLoc(), SM, LangOpts, tok::r_paren); + + return {OpenParenLoc, CloseParenLoc}; +} + +const BuiltinType *getBuiltinType(const Expr *Expr) { + assert(Expr); + return Expr->getType().getCanonicalType().getTypePtr()->getAs(); +} + +bool castRequiresStaticCast(const ImplicitCastExpr *CastExpr) { + const auto *FromExpr = CastExpr->getSubExpr(); + + if (CastExpr->isInstantiationDependent() || + FromExpr->isInstantiationDependent()) +return false; + if (getBuiltinType(CastExpr) == getBuiltinType(FromExpr)) +return false; + + switch (CastExpr->getCastKind()) { + case CastKind::CK_BaseToDerived: + case CastKind::CK_DerivedToBaseMemberPointer: + case CastKind::CK_IntegralCast: + case CastKind::CK_FloatingToIntegral: +return true; + + default: +return false; + } +} + +std::string buildReplacementString(const Expr *InitExpr, + const ASTContext &Context) { + // TODO: This function does not correctly handle the case where you have in + // 'ImplicitCastExpr' as an argument for a 'CXXConstructExpr'. + // In that case the generated code will not compile due to missing explicit + // cast of the sub expression. + + const SourceManager &SM = Context.getSourceManager(); + const LangOptions &LangOpts = Context.getLangOpts(); + + const StringRef InitExprStr = [&]() { +if (isa(InitExpr)) { + const auto *ConstructExpr = llvm::cast(InitExpr); + +
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,174 @@ +// RUN: %check_clang_tidy -std=c++11 %s modernize-use-uniform-initializer %t + +int cinit_0 = 0; +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int cinit_0 {0}; + +int cinit_1=0; +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int cinit_1{0}; + +int callinit_0(0); +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_0{0}; + +int callinit_1 ( 0 ); +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_1 {0}; + +int callinit_2 ( ((3 + 1 + 4) + 1 + 5) ); +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_2 {((3 + 1 + 4) + 1 + 5)}; + +int callinit_3((9-2)+(6+5)); +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_3{(9-2)+(6+5)}; + +int callinit_4 ((3 * 5 + (8 - 9) )); +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_4 {(3 * 5 + (8 - 9) )}; + +int callinit_5((7 + (-9))); +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_5{(7 + (-9))}; + +int mixed_0 = {0}; +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int mixed_0 {0}; + +int mixed_1={0}; +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int mixed_1{0}; + +int noinit; + +int correct_0{0}; + +int correct_1 {0}; + +struct CInitList_0 { +CInitList_0() : x(0) {} +// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: CInitList_0() : x{0} {} + +int x; +}; + +struct CInitList_1 { +CInitList_1():x(0) {} +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: CInitList_1():x{0} {} + +int x; +}; + +struct CInitList_2 { +CInitList_2() : x ( 0 ) {} +// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: CInitList_2() : x {0} {} + +int x; +}; + +struct Correct_0 { +Correct_0() : x{0} {} + +int x; +}; + +struct Correct_1 { +Correct_1():x{0} {} + +int x; +}; + +struct InClassInitializers { +int cinit_0 = 0; +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int cinit_0 {0}; + +int cinit_1=0; +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int cinit_1{0}; + +int mixed_0 = {0}; +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] PiotrZSL wrote: diagnostic in lower case https://github.com/llvm/llvm-project/pull/91124 ___ 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 `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,320 @@ +//===--- UseUniformInitializerCheck.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 "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +constexpr const StringRef VarDeclID = "VarDecl"; +constexpr const StringRef FieldDeclId = "FieldDecl"; +constexpr const StringRef CtorInitID = "CtorInit"; + +constexpr const StringRef CStyleWarningMessage = +"Use uniform initializer instead of C-style initializer"; + +constexpr StringRef +getInitializerStyleName(VarDecl::InitializationStyle InitStyle) { + switch (InitStyle) { + case VarDecl::InitializationStyle::CInit: +return "C"; + + case VarDecl::InitializationStyle::CallInit: +return "call"; + + default: +llvm_unreachable("Invalid initializer style!"); + } +} + +SourceRange getParenLocationsForCallInit(const Expr *InitExpr, PiotrZSL wrote: static (generic for all functions) https://github.com/llvm/llvm-project/pull/91124 ___ 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 `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,320 @@ +//===--- UseUniformInitializerCheck.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 "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +constexpr const StringRef VarDeclID = "VarDecl"; +constexpr const StringRef FieldDeclId = "FieldDecl"; +constexpr const StringRef CtorInitID = "CtorInit"; + +constexpr const StringRef CStyleWarningMessage = +"Use uniform initializer instead of C-style initializer"; + +constexpr StringRef +getInitializerStyleName(VarDecl::InitializationStyle InitStyle) { + switch (InitStyle) { + case VarDecl::InitializationStyle::CInit: +return "C"; + + case VarDecl::InitializationStyle::CallInit: +return "call"; + + default: +llvm_unreachable("Invalid initializer style!"); + } +} + +SourceRange getParenLocationsForCallInit(const Expr *InitExpr, + const SourceManager &SM, + const LangOptions &LangOpts) { + // We need to handle 'CXXConstructExpr' differently + if (isa(InitExpr)) +return cast(InitExpr)->getParenOrBraceRange(); + + // If the init expression itself is a 'ParenExpr' then + // 'InitExpr->getBeginLoc()' will already point to a '(' which is not the + // opening paren of the 'CallInit' expression. So it that case we need to + // start one character before that. + const bool NeedOffsetForOpenParen = [&]() { +if (!isa(InitExpr)) + return false; + +const clang::StringRef CharBeforeParenExpr = +Lexer::getSourceText(CharSourceRange::getCharRange( + InitExpr->getBeginLoc().getLocWithOffset(-1), + InitExpr->getBeginLoc()), + SM, LangOpts); + +return llvm::isSpace(CharBeforeParenExpr[0]); + }(); + + const SourceLocation OpenParenLoc = utils::lexer::findPreviousTokenKind( + NeedOffsetForOpenParen ? InitExpr->getBeginLoc().getLocWithOffset(-1) + : InitExpr->getBeginLoc(), + SM, LangOpts, tok::l_paren); + const SourceLocation CloseParenLoc = utils::lexer::findNextTokenKind( + InitExpr->getEndLoc(), SM, LangOpts, tok::r_paren); + + return {OpenParenLoc, CloseParenLoc}; +} + +const BuiltinType *getBuiltinType(const Expr *Expr) { + assert(Expr); + return Expr->getType().getCanonicalType().getTypePtr()->getAs(); +} + +bool castRequiresStaticCast(const ImplicitCastExpr *CastExpr) { + const auto *FromExpr = CastExpr->getSubExpr(); + + if (CastExpr->isInstantiationDependent() || + FromExpr->isInstantiationDependent()) +return false; + if (getBuiltinType(CastExpr) == getBuiltinType(FromExpr)) +return false; + + switch (CastExpr->getCastKind()) { + case CastKind::CK_BaseToDerived: + case CastKind::CK_DerivedToBaseMemberPointer: + case CastKind::CK_IntegralCast: + case CastKind::CK_FloatingToIntegral: +return true; + + default: +return false; + } +} + +std::string buildReplacementString(const Expr *InitExpr, + const ASTContext &Context) { + // TODO: This function does not correctly handle the case where you have in + // 'ImplicitCastExpr' as an argument for a 'CXXConstructExpr'. + // In that case the generated code will not compile due to missing explicit + // cast of the sub expression. + + const SourceManager &SM = Context.getSourceManager(); + const LangOptions &LangOpts = Context.getLangOpts(); + + const StringRef InitExprStr = [&]() { +if (isa(InitExpr)) { + const auto *ConstructExpr = llvm::cast(InitExpr); + +
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
https://github.com/PiotrZSL commented: Overall, i would see this as readability check. And I would see this as configurable check, so I could select one of: ` = 10;`, or `(10);` or `{10};` and stick to that convention. Other thing, in project not so long ago we had issues with {} initialization. Thing was that there were let say `std::vector variable{0x12345}`, and problem were that Object had constructor that take int as argument, and when developer expected to create something like this: `std::vector variable{{0x12345}}`, in fact created std::Vector that consumed few GB of memory. At that point idea were to restrict usage of `{}` for common containers, and report this as possible miss-spell. With this check, developers could run into more issues like this or containers that accept std::initialization list but also got normal containers. Using different initialization for different things usually helps protect against that. For example I do not think that `int callinit_5{(7 + (-9))};` is better than `int callinit_5 = 7 + (-9);`. And what I learn over years is that C++ standard is a one big trashbin, and if something is put there, it doesn't mean it's better. Just look into modernize-use-trailing-return-type, that check enforces something "new", but still on github alone there is over 3800 clang-tidy config files with this check explicitly disabled. So if you want to make this check actually usable, make it readability, and add config option to enforce specific style, note that there is also open issue for a check that would enforce `int a = 0;` instead of `int a = {}`; So you could somehow merge that. Overall check is +- fine, and if you want it it's ok, but I feat that it may end up as one of those "allways disable" checks, and it may not have to many users. https://github.com/llvm/llvm-project/pull/91124 ___ 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 `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,320 @@ +//===--- UseUniformInitializerCheck.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 "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} PiotrZSL wrote: put those into anonymous namespace under clang::tidy::modernize https://github.com/llvm/llvm-project/pull/91124 ___ 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 `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,174 @@ +// RUN: %check_clang_tidy -std=c++11 %s modernize-use-uniform-initializer %t + +int cinit_0 = 0; +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int cinit_0 {0}; + +int cinit_1=0; +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int cinit_1{0}; + +int callinit_0(0); +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_0{0}; + +int callinit_1 ( 0 ); +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_1 {0}; + +int callinit_2 ( ((3 + 1 + 4) + 1 + 5) ); +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_2 {((3 + 1 + 4) + 1 + 5)}; + +int callinit_3((9-2)+(6+5)); +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_3{(9-2)+(6+5)}; + +int callinit_4 ((3 * 5 + (8 - 9) )); +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_4 {(3 * 5 + (8 - 9) )}; + +int callinit_5((7 + (-9))); +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_5{(7 + (-9))}; + +int mixed_0 = {0}; +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int mixed_0 {0}; + +int mixed_1={0}; +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int mixed_1{0}; + +int noinit; + +int correct_0{0}; + +int correct_1 {0}; + +struct CInitList_0 { +CInitList_0() : x(0) {} +// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: CInitList_0() : x{0} {} + +int x; +}; + +struct CInitList_1 { +CInitList_1():x(0) {} +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: CInitList_1():x{0} {} + +int x; +}; + +struct CInitList_2 { +CInitList_2() : x ( 0 ) {} +// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: CInitList_2() : x {0} {} + +int x; +}; + +struct Correct_0 { +Correct_0() : x{0} {} + +int x; +}; + +struct Correct_1 { +Correct_1():x{0} {} + +int x; +}; + +struct InClassInitializers { +int cinit_0 = 0; +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int cinit_0 {0}; + +int cinit_1=0; +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int cinit_1{0}; + +int mixed_0 = {0}; +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int mixed_0 {0}; + +int mixed_1={0}; +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int mixed_1{0}; + +int noinit; + +int correct_0 {0}; + +int correct_1{0}; +}; + +// Defaulted function arguments cannot use the uniform initializer +void f(int x = 0) {} + +struct A { +A() = default; +A(int) {} +A(int, int) {} +}; + +A a_0; +A a_1{}; +A a_2(); // This is not a variable declaration it is actually a function definition (most vexing parse) +A a_3{21}; +A a_4{ 21 }; +A a_5(42); +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: A a_5{42}; +A a_6 ( 42 ); +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: A a_6 {42}; +A a_7{0, 1}; +A a_8{ 0, 1 }; +A a_9(0, 1); +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: A a_9{0, 1}; +A a_10( 1, 0 ); +// CHECK
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,320 @@ +//===--- UseUniformInitializerCheck.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 "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +constexpr const StringRef VarDeclID = "VarDecl"; +constexpr const StringRef FieldDeclId = "FieldDecl"; +constexpr const StringRef CtorInitID = "CtorInit"; + +constexpr const StringRef CStyleWarningMessage = +"Use uniform initializer instead of C-style initializer"; + +constexpr StringRef +getInitializerStyleName(VarDecl::InitializationStyle InitStyle) { + switch (InitStyle) { + case VarDecl::InitializationStyle::CInit: +return "C"; + + case VarDecl::InitializationStyle::CallInit: +return "call"; + + default: +llvm_unreachable("Invalid initializer style!"); + } +} + +SourceRange getParenLocationsForCallInit(const Expr *InitExpr, + const SourceManager &SM, + const LangOptions &LangOpts) { + // We need to handle 'CXXConstructExpr' differently + if (isa(InitExpr)) +return cast(InitExpr)->getParenOrBraceRange(); + + // If the init expression itself is a 'ParenExpr' then + // 'InitExpr->getBeginLoc()' will already point to a '(' which is not the + // opening paren of the 'CallInit' expression. So it that case we need to + // start one character before that. + const bool NeedOffsetForOpenParen = [&]() { +if (!isa(InitExpr)) + return false; + +const clang::StringRef CharBeforeParenExpr = +Lexer::getSourceText(CharSourceRange::getCharRange( + InitExpr->getBeginLoc().getLocWithOffset(-1), + InitExpr->getBeginLoc()), + SM, LangOpts); + +return llvm::isSpace(CharBeforeParenExpr[0]); + }(); + + const SourceLocation OpenParenLoc = utils::lexer::findPreviousTokenKind( + NeedOffsetForOpenParen ? InitExpr->getBeginLoc().getLocWithOffset(-1) + : InitExpr->getBeginLoc(), + SM, LangOpts, tok::l_paren); + const SourceLocation CloseParenLoc = utils::lexer::findNextTokenKind( + InitExpr->getEndLoc(), SM, LangOpts, tok::r_paren); + + return {OpenParenLoc, CloseParenLoc}; +} + +const BuiltinType *getBuiltinType(const Expr *Expr) { + assert(Expr); + return Expr->getType().getCanonicalType().getTypePtr()->getAs(); +} + +bool castRequiresStaticCast(const ImplicitCastExpr *CastExpr) { + const auto *FromExpr = CastExpr->getSubExpr(); + + if (CastExpr->isInstantiationDependent() || + FromExpr->isInstantiationDependent()) +return false; + if (getBuiltinType(CastExpr) == getBuiltinType(FromExpr)) +return false; + + switch (CastExpr->getCastKind()) { + case CastKind::CK_BaseToDerived: + case CastKind::CK_DerivedToBaseMemberPointer: + case CastKind::CK_IntegralCast: + case CastKind::CK_FloatingToIntegral: +return true; + + default: +return false; + } +} + +std::string buildReplacementString(const Expr *InitExpr, + const ASTContext &Context) { + // TODO: This function does not correctly handle the case where you have in + // 'ImplicitCastExpr' as an argument for a 'CXXConstructExpr'. + // In that case the generated code will not compile due to missing explicit + // cast of the sub expression. + + const SourceManager &SM = Context.getSourceManager(); + const LangOptions &LangOpts = Context.getLangOpts(); + + const StringRef InitExprStr = [&]() { +if (isa(InitExpr)) { + const auto *ConstructExpr = llvm::cast(InitExpr); + +
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,320 @@ +//===--- UseUniformInitializerCheck.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 "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +constexpr const StringRef VarDeclID = "VarDecl"; +constexpr const StringRef FieldDeclId = "FieldDecl"; +constexpr const StringRef CtorInitID = "CtorInit"; + +constexpr const StringRef CStyleWarningMessage = +"Use uniform initializer instead of C-style initializer"; + +constexpr StringRef +getInitializerStyleName(VarDecl::InitializationStyle InitStyle) { PiotrZSL wrote: static https://github.com/llvm/llvm-project/pull/91124 ___ 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 `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,320 @@ +//===--- UseUniformInitializerCheck.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 "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +constexpr const StringRef VarDeclID = "VarDecl"; +constexpr const StringRef FieldDeclId = "FieldDecl"; +constexpr const StringRef CtorInitID = "CtorInit"; + +constexpr const StringRef CStyleWarningMessage = +"Use uniform initializer instead of C-style initializer"; + +constexpr StringRef +getInitializerStyleName(VarDecl::InitializationStyle InitStyle) { + switch (InitStyle) { + case VarDecl::InitializationStyle::CInit: +return "C"; + + case VarDecl::InitializationStyle::CallInit: +return "call"; + + default: +llvm_unreachable("Invalid initializer style!"); + } +} + +SourceRange getParenLocationsForCallInit(const Expr *InitExpr, + const SourceManager &SM, + const LangOptions &LangOpts) { + // We need to handle 'CXXConstructExpr' differently + if (isa(InitExpr)) +return cast(InitExpr)->getParenOrBraceRange(); + + // If the init expression itself is a 'ParenExpr' then + // 'InitExpr->getBeginLoc()' will already point to a '(' which is not the + // opening paren of the 'CallInit' expression. So it that case we need to + // start one character before that. + const bool NeedOffsetForOpenParen = [&]() { +if (!isa(InitExpr)) + return false; + +const clang::StringRef CharBeforeParenExpr = +Lexer::getSourceText(CharSourceRange::getCharRange( + InitExpr->getBeginLoc().getLocWithOffset(-1), + InitExpr->getBeginLoc()), + SM, LangOpts); + +return llvm::isSpace(CharBeforeParenExpr[0]); + }(); + + const SourceLocation OpenParenLoc = utils::lexer::findPreviousTokenKind( + NeedOffsetForOpenParen ? InitExpr->getBeginLoc().getLocWithOffset(-1) + : InitExpr->getBeginLoc(), + SM, LangOpts, tok::l_paren); + const SourceLocation CloseParenLoc = utils::lexer::findNextTokenKind( + InitExpr->getEndLoc(), SM, LangOpts, tok::r_paren); + + return {OpenParenLoc, CloseParenLoc}; +} + +const BuiltinType *getBuiltinType(const Expr *Expr) { + assert(Expr); + return Expr->getType().getCanonicalType().getTypePtr()->getAs(); PiotrZSL wrote: would be nice to check if type isn't null & expr in same time https://github.com/llvm/llvm-project/pull/91124 ___ 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 `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,320 @@ +//===--- UseUniformInitializerCheck.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 "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +constexpr const StringRef VarDeclID = "VarDecl"; +constexpr const StringRef FieldDeclId = "FieldDecl"; +constexpr const StringRef CtorInitID = "CtorInit"; + +constexpr const StringRef CStyleWarningMessage = +"Use uniform initializer instead of C-style initializer"; + +constexpr StringRef +getInitializerStyleName(VarDecl::InitializationStyle InitStyle) { + switch (InitStyle) { + case VarDecl::InitializationStyle::CInit: +return "C"; + + case VarDecl::InitializationStyle::CallInit: +return "call"; + + default: +llvm_unreachable("Invalid initializer style!"); + } +} + +SourceRange getParenLocationsForCallInit(const Expr *InitExpr, + const SourceManager &SM, + const LangOptions &LangOpts) { + // We need to handle 'CXXConstructExpr' differently + if (isa(InitExpr)) +return cast(InitExpr)->getParenOrBraceRange(); + + // If the init expression itself is a 'ParenExpr' then + // 'InitExpr->getBeginLoc()' will already point to a '(' which is not the + // opening paren of the 'CallInit' expression. So it that case we need to + // start one character before that. + const bool NeedOffsetForOpenParen = [&]() { +if (!isa(InitExpr)) + return false; + +const clang::StringRef CharBeforeParenExpr = +Lexer::getSourceText(CharSourceRange::getCharRange( + InitExpr->getBeginLoc().getLocWithOffset(-1), + InitExpr->getBeginLoc()), + SM, LangOpts); + +return llvm::isSpace(CharBeforeParenExpr[0]); + }(); + + const SourceLocation OpenParenLoc = utils::lexer::findPreviousTokenKind( + NeedOffsetForOpenParen ? InitExpr->getBeginLoc().getLocWithOffset(-1) + : InitExpr->getBeginLoc(), + SM, LangOpts, tok::l_paren); + const SourceLocation CloseParenLoc = utils::lexer::findNextTokenKind( + InitExpr->getEndLoc(), SM, LangOpts, tok::r_paren); + + return {OpenParenLoc, CloseParenLoc}; +} + +const BuiltinType *getBuiltinType(const Expr *Expr) { + assert(Expr); + return Expr->getType().getCanonicalType().getTypePtr()->getAs(); +} + +bool castRequiresStaticCast(const ImplicitCastExpr *CastExpr) { + const auto *FromExpr = CastExpr->getSubExpr(); + + if (CastExpr->isInstantiationDependent() || + FromExpr->isInstantiationDependent()) +return false; + if (getBuiltinType(CastExpr) == getBuiltinType(FromExpr)) +return false; + + switch (CastExpr->getCastKind()) { + case CastKind::CK_BaseToDerived: + case CastKind::CK_DerivedToBaseMemberPointer: + case CastKind::CK_IntegralCast: + case CastKind::CK_FloatingToIntegral: +return true; + + default: +return false; + } +} + +std::string buildReplacementString(const Expr *InitExpr, + const ASTContext &Context) { + // TODO: This function does not correctly handle the case where you have in + // 'ImplicitCastExpr' as an argument for a 'CXXConstructExpr'. + // In that case the generated code will not compile due to missing explicit + // cast of the sub expression. + + const SourceManager &SM = Context.getSourceManager(); + const LangOptions &LangOpts = Context.getLangOpts(); + + const StringRef InitExprStr = [&]() { +if (isa(InitExpr)) { + const auto *ConstructExpr = llvm::cast(InitExpr); + +
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,320 @@ +//===--- UseUniformInitializerCheck.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 "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +constexpr const StringRef VarDeclID = "VarDecl"; +constexpr const StringRef FieldDeclId = "FieldDecl"; +constexpr const StringRef CtorInitID = "CtorInit"; + +constexpr const StringRef CStyleWarningMessage = +"Use uniform initializer instead of C-style initializer"; + +constexpr StringRef +getInitializerStyleName(VarDecl::InitializationStyle InitStyle) { + switch (InitStyle) { + case VarDecl::InitializationStyle::CInit: +return "C"; + + case VarDecl::InitializationStyle::CallInit: +return "call"; + + default: +llvm_unreachable("Invalid initializer style!"); + } +} + +SourceRange getParenLocationsForCallInit(const Expr *InitExpr, + const SourceManager &SM, + const LangOptions &LangOpts) { + // We need to handle 'CXXConstructExpr' differently + if (isa(InitExpr)) +return cast(InitExpr)->getParenOrBraceRange(); + + // If the init expression itself is a 'ParenExpr' then + // 'InitExpr->getBeginLoc()' will already point to a '(' which is not the + // opening paren of the 'CallInit' expression. So it that case we need to + // start one character before that. + const bool NeedOffsetForOpenParen = [&]() { +if (!isa(InitExpr)) + return false; + +const clang::StringRef CharBeforeParenExpr = +Lexer::getSourceText(CharSourceRange::getCharRange( + InitExpr->getBeginLoc().getLocWithOffset(-1), + InitExpr->getBeginLoc()), + SM, LangOpts); PiotrZSL wrote: you could try to check where previous token ends. https://github.com/llvm/llvm-project/pull/91124 ___ 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 `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,34 @@ +.. title:: clang-tidy - modernize-use-uniform-initializer + +modernize-use-uniform-initializer += + +Finds usage of C-Style initialization that can be rewritten with +C++-11 uniform initializers. + +Example +--- + +.. code-block:: c++ + + int foo = 21; + int bar(42); + + struct Baz { +Baz() : x(3) {} + +int x; + }; PiotrZSL wrote: add example with in-class initialization https://github.com/llvm/llvm-project/pull/91124 ___ 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 `modernize-use-uniform-initializer` check (PR #91124)
@@ -84,6 +84,29 @@ SourceLocation findNextTerminator(SourceLocation Start, const SourceManager &SM, return findNextAnyTokenKind(Start, SM, LangOpts, tok::comma, tok::semi); } +SourceLocation findNextTokenKind(SourceLocation Start, const SourceManager &SM, + const LangOptions &LangOpts, + tok::TokenKind TK) { + while (true) { +std::optional CurrentToken = +Lexer::findNextToken(Start, SM, LangOpts); + +if (!CurrentToken) + return {}; + +Token PotentialMatch = *CurrentToken; +if (PotentialMatch.is(TK)) + return PotentialMatch.getLocation(); + +// If we reach the end of the file, and eof is not the target token, we stop +// the loop, otherwise we will get infinite loop (findNextToken will return +// eof on eof). +if (PotentialMatch.is(tok::eof)) + return {}; +Start = PotentialMatch.getLastLoc(); + } PiotrZSL wrote: instead of re-implementing this you could just call findNextTokenSkippingComments in loop https://github.com/llvm/llvm-project/pull/91124 ___ 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 `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,174 @@ +// RUN: %check_clang_tidy -std=c++11 %s modernize-use-uniform-initializer %t + +int cinit_0 = 0; +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int cinit_0 {0}; + +int cinit_1=0; +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int cinit_1{0}; + +int callinit_0(0); +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_0{0}; + +int callinit_1 ( 0 ); +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_1 {0}; + +int callinit_2 ( ((3 + 1 + 4) + 1 + 5) ); +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_2 {((3 + 1 + 4) + 1 + 5)}; + +int callinit_3((9-2)+(6+5)); +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_3{(9-2)+(6+5)}; + +int callinit_4 ((3 * 5 + (8 - 9) )); +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_4 {(3 * 5 + (8 - 9) )}; + +int callinit_5((7 + (-9))); +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_5{(7 + (-9))}; + +int mixed_0 = {0}; +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int mixed_0 {0}; + +int mixed_1={0}; +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int mixed_1{0}; + +int noinit; + +int correct_0{0}; + +int correct_1 {0}; + +struct CInitList_0 { +CInitList_0() : x(0) {} +// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: CInitList_0() : x{0} {} + +int x; +}; + +struct CInitList_1 { +CInitList_1():x(0) {} +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: CInitList_1():x{0} {} + +int x; +}; + +struct CInitList_2 { +CInitList_2() : x ( 0 ) {} +// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: CInitList_2() : x {0} {} + +int x; +}; + +struct Correct_0 { +Correct_0() : x{0} {} + +int x; +}; + +struct Correct_1 { +Correct_1():x{0} {} + +int x; +}; + +struct InClassInitializers { +int cinit_0 = 0; +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int cinit_0 {0}; + +int cinit_1=0; +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int cinit_1{0}; + +int mixed_0 = {0}; +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int mixed_0 {0}; + +int mixed_1={0}; +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int mixed_1{0}; + +int noinit; + +int correct_0 {0}; + +int correct_1{0}; +}; + +// Defaulted function arguments cannot use the uniform initializer +void f(int x = 0) {} + +struct A { +A() = default; +A(int) {} +A(int, int) {} +}; + +A a_0; +A a_1{}; +A a_2(); // This is not a variable declaration it is actually a function definition (most vexing parse) +A a_3{21}; +A a_4{ 21 }; +A a_5(42); +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: A a_5{42}; +A a_6 ( 42 ); +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: A a_6 {42}; +A a_7{0, 1}; +A a_8{ 0, 1 }; +A a_9(0, 1); +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: A a_9{0, 1}; +A a_10( 1, 0 ); +// CHECK
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
https://github.com/PiotrZSL requested changes to this pull request. Fix pointed out nits https://github.com/llvm/llvm-project/pull/91124 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
zyn0217 wrote: @aganea Oops, this is an oversight I think, because I don't build lldb locally nor run its tests... I'm proposing a PR https://github.com/llvm/llvm-project/pull/91132, can you help me confirm if that works? https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 7e59223 - [test] %clang_cc1: remove redundant actions
Author: Fangrui Song Date: 2024-05-05T10:46:06-07:00 New Revision: 7e59223ac4b045178c287a56154113d5989572f4 URL: https://github.com/llvm/llvm-project/commit/7e59223ac4b045178c287a56154113d5989572f4 DIFF: https://github.com/llvm/llvm-project/commit/7e59223ac4b045178c287a56154113d5989572f4.diff LOG: [test] %clang_cc1: remove redundant actions ParseFrontendArgs takes the last OPT_Action_Group option. The other actions are overridden. Added: Modified: clang/test/AST/arithmetic-fence-builtin.c clang/test/ASTMerge/codegen-exprs/test.c clang/test/CXX/module/module.private.frag/p1.cpp clang/test/CodeGen/PowerPC/builtins-ppc-fpconstrained.c clang/test/CodeGen/PowerPC/builtins-ppc-vec-ins-error.c clang/test/CodeGen/PowerPC/vector-bool-pixel-altivec-init-no-parentheses.c clang/test/CodeGen/PowerPC/vector-bool-pixel-altivec-init.c clang/test/CodeGen/PowerPC/vector-compat-pixel-bool-ternary.c clang/test/CodeGen/PowerPC/vector-compat-pixel-bool.c clang/test/CodeGen/PowerPC/vector-compat-ternary.c clang/test/CodeGen/PowerPC/vector-compat.c clang/test/CodeGen/aarch64-ABI-align-packed-assembly.c clang/test/CodeGen/aarch64-neon-intrinsics.c clang/test/CodeGen/aarch64-v8.2a-fp16-intrinsics-constrained.c clang/test/CodeGen/builtins-nvptx-native-half-type-err.c clang/test/CodeGen/builtins-nvptx-native-half-type.c clang/test/CodeGen/math-builtins-long.c clang/test/CodeGen/pch-dllexport.cpp clang/test/CodeGen/thinlto-loop-vectorize-pm.c clang/test/CodeGenCXX/module-intializer.cpp clang/test/CodeGenOpenCL/builtins-amdgcn-raytracing.cl clang/test/CodeGenSYCL/function-attrs.cpp clang/test/CoverageMapping/pr32679.cpp clang/test/Frontend/output-paths.c clang/test/Headers/ms-arm64-intrin.cpp clang/test/Modules/cxx20-10-5-ex1.cpp clang/test/Modules/cxx20-importing-function-bodies.cppm clang/test/Modules/cxx20-include-translation.cpp clang/test/Modules/eagerly-load-cxx-named-modules.cppm clang/test/Modules/load-module-with-errors.m clang/test/Modules/no-import-func-body.cppm clang/test/Modules/odr_using_dependent_name.cppm clang/test/Modules/pr59780.cppm clang/test/Modules/pr61067.cppm clang/test/SemaCUDA/call-kernel-from-kernel.cu clang/test/SemaCUDA/constexpr-variables.cu Removed: diff --git a/clang/test/AST/arithmetic-fence-builtin.c b/clang/test/AST/arithmetic-fence-builtin.c index acdefade0748a2..2450bb4d59d514 100644 --- a/clang/test/AST/arithmetic-fence-builtin.c +++ b/clang/test/AST/arithmetic-fence-builtin.c @@ -20,33 +20,31 @@ // RUN: | FileCheck %s --strict-whitespace --check-prefixes=CHECK,CHECK2 // // Tests with serialization: -// RUN: %clang_cc1 -ast-dump -triple i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-pch -o %t %s // RUN: %clang_cc1 -triple i386-pc-linux-gnu -include-pch %t -ast-dump-all /dev/null \ // RUN: | FileCheck %s --strict-whitespace // -// RUN: %clang_cc1 -ast-dump -triple aarch64-unknown-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -triple aarch64-unknown-linux-gnu -emit-pch -o %t %s // RUN: %clang_cc1 -triple aarch64-unknown-linux-gnu -include-pch %t -ast-dump-all /dev/null \ // RUN: | FileCheck %s --strict-whitespace // -// RUN: %clang_cc1 -ast-dump -triple i386-pc-linux-gnu -DFAST -mreassociate %s \ +// RUN: %clang_cc1 -triple i386-pc-linux-gnu -DFAST -mreassociate %s \ // RUN: -emit-pch -o %t // RUN: %clang_cc1 -triple i386-pc-linux-gnu -include-pch %t -ast-dump-all /dev/null \ // RUN: | FileCheck %s --strict-whitespace --check-prefixes=CHECK,CHECK1 // -// RUN: %clang_cc1 -ast-dump -triple aarch64-unknown-linux-gnu -DFAST -mreassociate %s \ +// RUN: %clang_cc1 -triple aarch64-unknown-linux-gnu -DFAST -mreassociate %s \ // RUN: -emit-pch -o %t // RUN: %clang_cc1 -triple aarch64-unknown-linux-gnu -include-pch %t -ast-dump-all /dev/null \ // RUN: | FileCheck %s --strict-whitespace --check-prefixes=CHECK,CHECK1 // -// RUN: %clang_cc1 -ast-dump -triple i386-pc-linux-gnu -DFAST -mreassociate %s \ -// RUN: -fprotect-parens \ -// RUN: -emit-pch -o %t +// RUN: %clang_cc1 -triple i386-pc-linux-gnu -DFAST -mreassociate %s \ +// RUN: -fprotect-parens -emit-pch -o %t // RUN: %clang_cc1 -triple i386-pc-linux-gnu -include-pch %t -ast-dump-all /dev/null -fprotect-parens\ // RUN: | FileCheck %s --strict-whitespace --check-prefixes=CHECK,CHECK2 // -// RUN: %clang_cc1 -ast-dump -triple aarch64-unknown-linux-gnu -DFAST -mreassociate %s \ -// RUN: -fprotect-parens \ -// RUN: -emit-pch -o %t +// RUN: %clang_cc1 -triple aarch64-unknown-linux-gnu -DFAST -mreassociate %s \ +// RUN: -fprotect-parens -emit-pch -o %t // RUN: %clang_cc1 -triple aarch64-unknown-linux-gnu -include-pch %t -ast-dump-all /dev/null -fprotect-parens\ // RUN: | FileCheck %s --strict-whitespace --check-prefixes=CHECK,CHECK2
[clang] [llvm] [ARM] Armv8-R does not require fp64 or neon. (PR #88287)
chrisnc wrote: If there's no other feedback, could someone hit the merge button for me? https://github.com/llvm/llvm-project/pull/88287 ___ 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 `modernize-use-uniform-initializer` check (PR #91124)
carlosgalvezp wrote: Regarding the problem of {} initialization and std::vector, I believe we could restrict this check to not warn on classes that have a constructor taking a `std:: initializer_list`. I believe AUTOSAR has an exception for that. https://github.com/llvm/llvm-project/pull/91124 ___ 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 `modernize-use-uniform-initializer` check (PR #91124)
carlosgalvezp wrote: Consider also that this check should probably not apply to variables of type `auto`, see AUTOSAR rule A8-5-3. https://github.com/llvm/llvm-project/pull/91124 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] d33937b - [test] %clang_cc1: remove redundant actions
Author: Fangrui Song Date: 2024-05-05T11:42:04-07:00 New Revision: d33937b6236767137a1ec3393d0933f10eed4ffe URL: https://github.com/llvm/llvm-project/commit/d33937b6236767137a1ec3393d0933f10eed4ffe DIFF: https://github.com/llvm/llvm-project/commit/d33937b6236767137a1ec3393d0933f10eed4ffe.diff LOG: [test] %clang_cc1: remove redundant actions ParseFrontendArgs takes the last OPT_Action_Group option. The other actions are overridden. Added: Modified: clang/test/CodeGen/SystemZ/align-systemz-02.c clang/test/CodeGen/thinlto-distributed-cfi-devirt.ll clang/test/CodeGen/thinlto-distributed-cfi.ll clang/test/CodeGenCXX/module-intializer.cpp clang/test/Lexer/raw-string-dlim-invalid.cpp clang/test/Modules/prune-non-affecting-module-map-files-textual.c clang/test/PCH/empty-with-headers.c clang/test/PCH/ms-if-exists.cpp Removed: diff --git a/clang/test/CodeGen/SystemZ/align-systemz-02.c b/clang/test/CodeGen/SystemZ/align-systemz-02.c index 013faea61ada24..4b2d32649226e0 100644 --- a/clang/test/CodeGen/SystemZ/align-systemz-02.c +++ b/clang/test/CodeGen/SystemZ/align-systemz-02.c @@ -1,10 +1,10 @@ // RUN: %clang_cc1 -triple s390x-linux-gnu %s -o - -target-feature +vector -emit-llvm \ // RUN:| FileCheck %s -check-prefix=VECIR -// RUN: %clang_cc1 -triple s390x-linux-gnu %s -o - -target-feature +vector -emit-obj -S \ +// RUN: %clang_cc1 -triple s390x-linux-gnu %s -o - -target-feature +vector -S \ // RUN:| FileCheck %s -check-prefix=VECASM // RUN: %clang_cc1 -triple s390x-linux-gnu %s -o - -target-feature -vector -emit-llvm \ // RUN:| FileCheck %s -check-prefix=SCALIR -// RUN: %clang_cc1 -triple s390x-linux-gnu %s -o - -target-feature -vector -emit-obj -S \ +// RUN: %clang_cc1 -triple s390x-linux-gnu %s -o - -target-feature -vector -S \ // RUN:| FileCheck %s -check-prefix=SCALASM // REQUIRES: systemz-registered-target diff --git a/clang/test/CodeGen/thinlto-distributed-cfi-devirt.ll b/clang/test/CodeGen/thinlto-distributed-cfi-devirt.ll index 433fd1fe204304..acbcdcdb4fd024 100644 --- a/clang/test/CodeGen/thinlto-distributed-cfi-devirt.ll +++ b/clang/test/CodeGen/thinlto-distributed-cfi-devirt.ll @@ -38,12 +38,12 @@ ; CHECK-DIS: ^2 = typeid: (name: "_ZTS1A", summary: (typeTestRes: (kind: allOnes, sizeM1BitWidth: 7), wpdResolutions: ((offset: 0, wpdRes: (kind: branchFunnel)), (offset: 8, wpdRes: (kind: singleImpl, singleImplName: "_ZN1A1nEi") ; guid = 7004155349499253778 ; RUN: %clang_cc1 -triple x86_64-grtev4-linux-gnu \ -; RUN: -emit-obj -fthinlto-index=%t.o.thinlto.bc -O2 -Rpass=wholeprogramdevirt \ +; RUN: -fthinlto-index=%t.o.thinlto.bc -O2 -Rpass=wholeprogramdevirt \ ; RUN: -emit-llvm -o - -x ir %t.o 2>&1 | FileCheck %s --check-prefixes=CHECK-IR --check-prefixes=REMARKS ; Check that the devirtualization is suppressed via -wholeprogramdevirt-skip ; RUN: %clang_cc1 -triple x86_64-grtev4-linux-gnu -mllvm -wholeprogramdevirt-skip=_ZN1A1nEi \ -; RUN: -emit-obj -fthinlto-index=%t.o.thinlto.bc -O2 -Rpass=wholeprogramdevirt \ +; RUN: -fthinlto-index=%t.o.thinlto.bc -O2 -Rpass=wholeprogramdevirt \ ; RUN: -emit-llvm -o - -x ir %t.o 2>&1 | FileCheck %s --check-prefixes=SKIP-IR --check-prefixes=SKIP-REMARKS ; REMARKS: single-impl: devirtualized a call to _ZN1A1nEi diff --git a/clang/test/CodeGen/thinlto-distributed-cfi.ll b/clang/test/CodeGen/thinlto-distributed-cfi.ll index 47e56c091a6120..6023ba8f32df91 100644 --- a/clang/test/CodeGen/thinlto-distributed-cfi.ll +++ b/clang/test/CodeGen/thinlto-distributed-cfi.ll @@ -28,7 +28,7 @@ ; CHECK-DIS: ^2 = typeid: (name: "_ZTS1A", summary: (typeTestRes: (kind: single, sizeM1BitWidth: 0))) ; guid = 7004155349499253778 ; RUN: %clang_cc1 -triple x86_64-grtev4-linux-gnu \ -; RUN: -emit-obj -fthinlto-index=%t.o.thinlto.bc \ +; RUN: -fthinlto-index=%t.o.thinlto.bc \ ; RUN: -emit-llvm -o - -x ir %t.o | FileCheck %s --check-prefixes=CHECK-IR ; Ensure that backend does not fail generating native code. diff --git a/clang/test/CodeGenCXX/module-intializer.cpp b/clang/test/CodeGenCXX/module-intializer.cpp index 2be1d5a49843c9..318250a653a7c2 100644 --- a/clang/test/CodeGenCXX/module-intializer.cpp +++ b/clang/test/CodeGenCXX/module-intializer.cpp @@ -14,7 +14,7 @@ // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M-Part.cpp \ // RUN:-emit-module-interface -o M-Part.pcm -// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M-Part.pcm -S \ +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M-Part.pcm \ // RUN:-emit-llvm -o - | FileCheck %s --check-prefix=CHECK-P // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M.cpp \ diff --git a/clang/test/Lexer/raw-string-dlim-invalid.cpp b/clang/test/Lexer/raw-string-dlim-invalid.cpp index da797f00a1d628..8928b398ceb76d 100644 --- a/clang/test/Lexer/raw-string-dlim-invalid.cpp +++ b/clang/te
[clang-tools-extra] [clang-tidy] new check misc-use-internal-linkage (PR #90830)
@@ -0,0 +1,79 @@ +//===--- UseInternalLinkageCheck.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 "UseInternalLinkageCheck.h" +#include "clang/AST/Decl.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchersMacros.h" +#include "clang/Basic/Specifiers.h" +#include "llvm/ADT/STLExtras.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::misc { + +namespace { + +AST_POLYMORPHIC_MATCHER(isFirstDecl, +AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, +VarDecl)) { + return Node.isFirstDecl(); +} 5chmidti wrote: You don't need to make this a polymorphic matcher, `isFirstDecl` is part of `clang::Decl`. https://github.com/llvm/llvm-project/pull/90830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] new check misc-use-internal-linkage (PR #90830)
@@ -0,0 +1,79 @@ +//===--- UseInternalLinkageCheck.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 "UseInternalLinkageCheck.h" +#include "clang/AST/Decl.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchersMacros.h" +#include "clang/Basic/Specifiers.h" +#include "llvm/ADT/STLExtras.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::misc { + +namespace { + +AST_POLYMORPHIC_MATCHER(isFirstDecl, +AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, +VarDecl)) { + return Node.isFirstDecl(); +} + +AST_MATCHER(Decl, isInMainFile) { + return llvm::all_of(Node.redecls(), [&](const Decl *D) { +return Finder->getASTContext().getSourceManager().isInMainFile( +D->getLocation()); + }); +} + +AST_POLYMORPHIC_MATCHER(isExternStorageClass, +AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, +VarDecl)) { + return Node.getStorageClass() == SC_Extern; +} + +} // namespace + +void UseInternalLinkageCheck::registerMatchers(MatchFinder *Finder) { + auto Common = allOf(isFirstDecl(), isInMainFile(), + unless(anyOf( + // 1. internal linkage + isStaticStorageClass(), isInAnonymousNamespace(), + // 2. explicit external linkage + isExternStorageClass(), isExternC(), + // 3. template + isExplicitTemplateSpecialization(), + clang::ast_matchers::isTemplateInstantiation(), + // 4. friend + hasAncestor(friendDecl(); + Finder->addMatcher( + functionDecl(Common, unless(cxxMethodDecl()), unless(isMain())) + .bind("fn"), + this); + Finder->addMatcher(varDecl(Common, hasGlobalStorage()).bind("var"), this); +} + +static constexpr StringRef Message = +"%0 %1 can be made static or moved into an anonymous namespace " +"to enforce internal linkage"; + +void UseInternalLinkageCheck::check(const MatchFinder::MatchResult &Result) { + if (const auto *FD = Result.Nodes.getNodeAs("fn")) { +diag(FD->getLocation(), Message) << "function" << FD; +return; + } + if (const auto *VD = Result.Nodes.getNodeAs("var")) { +diag(VD->getLocation(), Message) << "variable" << VD; +return; + } 5chmidti wrote: Please stream `SourceRange`s into the diagnostics. For the `FunctionDecl` you could use `SourceRange(FD->getBeginLoc(), FD->getTypeSpecEndLoc())`, which would not highlight the body (that would be quite noisy). https://github.com/llvm/llvm-project/pull/90830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] new check misc-use-internal-linkage (PR #90830)
https://github.com/5chmidti edited https://github.com/llvm/llvm-project/pull/90830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] new check misc-use-internal-linkage (PR #90830)
https://github.com/5chmidti commented: Regarding unit build: `google-global-names-in-headers` is one of the checks that check file extensions: https://github.com/llvm/llvm-project/blob/d33937b6236767137a1ec3393d0933f10eed4ffe/clang-tools-extra/clang-tidy/google/GlobalNamesInHeadersCheck.cpp#L42-L44 Nice that there is a check for this now, it looks like there are a few instances of this issue in LLVM as well. https://github.com/llvm/llvm-project/pull/90830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] new check misc-use-internal-linkage (PR #90830)
@@ -0,0 +1,79 @@ +//===--- UseInternalLinkageCheck.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 "UseInternalLinkageCheck.h" +#include "clang/AST/Decl.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchersMacros.h" +#include "clang/Basic/Specifiers.h" +#include "llvm/ADT/STLExtras.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::misc { + +namespace { + +AST_POLYMORPHIC_MATCHER(isFirstDecl, +AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, +VarDecl)) { + return Node.isFirstDecl(); +} + +AST_MATCHER(Decl, isInMainFile) { + return llvm::all_of(Node.redecls(), [&](const Decl *D) { +return Finder->getASTContext().getSourceManager().isInMainFile( +D->getLocation()); + }); +} + +AST_POLYMORPHIC_MATCHER(isExternStorageClass, +AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, +VarDecl)) { + return Node.getStorageClass() == SC_Extern; +} + +} // namespace + +void UseInternalLinkageCheck::registerMatchers(MatchFinder *Finder) { + auto Common = allOf(isFirstDecl(), isInMainFile(), + unless(anyOf( + // 1. internal linkage + isStaticStorageClass(), isInAnonymousNamespace(), + // 2. explicit external linkage + isExternStorageClass(), isExternC(), + // 3. template + isExplicitTemplateSpecialization(), + clang::ast_matchers::isTemplateInstantiation(), 5chmidti wrote: Template instantiations will already be ignored because of the traversal kind https://github.com/llvm/llvm-project/pull/90830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] new check misc-use-internal-linkage (PR #90830)
https://github.com/5chmidti edited https://github.com/llvm/llvm-project/pull/90830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] new check misc-use-internal-linkage (PR #90830)
https://github.com/5chmidti edited https://github.com/llvm/llvm-project/pull/90830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [alpha.webkit.UncountedCallArgsChecker] Allow trivial operator++ (PR #91102)
https://github.com/rniwa updated https://github.com/llvm/llvm-project/pull/91102 >From b3ae3d7a2a8885777b691e7fde237f5745e764a1 Mon Sep 17 00:00:00 2001 From: Ryosuke Niwa Date: Sat, 4 May 2024 20:29:03 -0700 Subject: [PATCH 1/2] [alpha.webkit.UncountedCallArgsChecker] Allow trivial operator++ This PR adds the support for trivial operator++ implementations. T& operator++() and T operator++(int) are trivial if the calle is trivial. Also allow incrementing and decrementing of a POD member variable. --- .../Checkers/WebKit/PtrTypesSemantics.cpp | 17 ++- .../Checkers/WebKit/uncounted-obj-arg.cpp | 28 +++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp index 6901dbb415bf76..c219172477a621 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp @@ -316,10 +316,15 @@ class TrivialFunctionAnalysisVisitor if (UO->isIncrementOp() || UO->isDecrementOp()) { // Allow increment or decrement of a POD type. - if (auto *RefExpr = dyn_cast(UO->getSubExpr())) { + auto *SubExpr = UO->getSubExpr(); + if (auto *RefExpr = dyn_cast(SubExpr)) { if (auto *Decl = dyn_cast(RefExpr->getDecl())) return Decl->isLocalVarDeclOrParm() && Decl->getType().isPODType(Decl->getASTContext()); + } else if (auto *ME = dyn_cast(SubExpr)) { +if (auto *Decl = ME->getMemberDecl()) + return Visit(ME->getBase()) && + Decl->getType().isPODType(Decl->getASTContext()); } } // Other operators are non-trivial. @@ -405,6 +410,16 @@ class TrivialFunctionAnalysisVisitor return TrivialFunctionAnalysis::isTrivialImpl(Callee, Cache); } + bool VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *OCE) { +if (!checkArguments(OCE)) + return false; +auto *Callee = OCE->getCalleeDecl(); +if (!Callee) + return false; +// Recursively descend into the callee to confirm that it's trivial as well. +return TrivialFunctionAnalysis::isTrivialImpl(Callee, Cache); + } + bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { if (auto *Expr = E->getExpr()) { if (!Visit(Expr)) diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp index 63a68a994a5c64..2816a9cb823649 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp @@ -137,11 +137,26 @@ class Number { Number(int v) : v(v) { } Number(double); Number operator+(const Number&); + Number& operator++() { ++v; return *this; } + Number operator++(int) { Number returnValue(v); ++v; return returnValue; } const int& value() const { return v; } + void someMethod(); + private: int v; }; +class ComplexNumber { +public: + ComplexNumber() : real(0), complex(0) { } + ComplexNumber& operator++() { real.someMethod(); return *this; } + ComplexNumber operator++(int); + +private: + Number real; + Number complex; +}; + class RefCounted { public: void ref() const; @@ -208,6 +223,9 @@ class RefCounted { unsigned trivial32() { return sizeof(int); } unsigned trivial33() { return ~0xff; } template unsigned trivial34() { return v; } + void trivial35() { v++; } + void trivial36() { ++(*number); } + void trivial37() { (*number)++; } static RefCounted& singleton() { static RefCounted s_RefCounted; @@ -282,9 +300,12 @@ class RefCounted { int nonTrivial13() { return ~otherFunction(); } int nonTrivial14() { int r = 0xff; r |= otherFunction(); return r; } + void nonTrivial15() { ++complex; } + void nonTrivial16() { complex++; } unsigned v { 0 }; Number* number { nullptr }; + ComplexNumber complex; Enum enumValue { Enum::Value1 }; }; @@ -340,6 +361,9 @@ class UnrelatedClass { getFieldTrivial().trivial32(); // no-warning getFieldTrivial().trivial33(); // no-warning getFieldTrivial().trivial34<7>(); // no-warning +getFieldTrivial().trivial35(); // no-warning +getFieldTrivial().trivial36(); // no-warning +getFieldTrivial().trivial37(); // no-warning RefCounted::singleton().trivial18(); // no-warning RefCounted::singleton().someFunction(); // no-warning @@ -374,6 +398,10 @@ class UnrelatedClass { // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} getFieldTrivial().nonTrivial14(); // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} +getFieldTrivial().nonTrivial15(); +// expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} +getFieldTrivial().nonTrivial16(); +// expected-warning@-1{{Call argument for 'this' parameter is unco
[clang] [alpha.webkit.UncountedCallArgsChecker] Allow trivial operator++ (PR #91102)
https://github.com/rniwa edited https://github.com/llvm/llvm-project/pull/91102 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] nonblocking/nonallocating attributes (was: nolock/noalloc) (PR #84983)
@@ -4639,6 +4644,312 @@ class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { } }; +// -- + +class Decl; +class CXXMethodDecl; +struct FunctionEffectDiff; +class FunctionEffectsRef; +class FunctionEffectSet; + +/// Represents an abstract function effect, using just an enumeration describing +/// its kind. +class FunctionEffect { +public: + /// Identifies the particular effect. + enum class Kind : uint8_t { +None = 0, +NonBlocking = 1, +NonAllocating = 2, +Blocking = 3, +Allocating = 4 + }; + + /// Flags describing some behaviors of the effect. + using Flags = unsigned; + enum FlagBit : Flags { +// Can verification inspect callees' implementations? (e.g. nonblocking: +// yes, tcb+types: no). This also implies the need for 2nd-pass +// verification. +FE_InferrableOnCallees = 0x1, + +// Language constructs which effects can diagnose as disallowed. +FE_ExcludeThrow = 0x2, +FE_ExcludeCatch = 0x4, +FE_ExcludeObjCMessageSend = 0x8, +FE_ExcludeStaticLocalVars = 0x10, +FE_ExcludeThreadLocalVars = 0x20 + }; + +private: + LLVM_PREFERRED_TYPE(Kind) + unsigned FKind : 3; + + // Expansion: for hypothetical TCB+types, there could be one Kind for TCB, + // then ~16(?) bits "SubKind" to map to a specific named TCB. SubKind would + // be considered for uniqueness. + +public: + FunctionEffect() : FKind(unsigned(Kind::None)) {} + + explicit FunctionEffect(Kind K) : FKind(unsigned(K)) {} + + /// The kind of the effect. + Kind kind() const { return Kind(FKind); } + + /// Return the opposite kind, for effects which have opposites. + Kind oppositeKind() const; + + /// For serialization. + uint32_t toOpaqueInt32() const { return FKind; } + static FunctionEffect fromOpaqueInt32(uint32_t Value) { +return FunctionEffect(Kind(Value)); + } + + /// Flags describing some behaviors of the effect. + Flags flags() const { +switch (kind()) { +case Kind::NonBlocking: + return FE_InferrableOnCallees | FE_ExcludeThrow | FE_ExcludeCatch | + FE_ExcludeObjCMessageSend | FE_ExcludeStaticLocalVars | + FE_ExcludeThreadLocalVars; +case Kind::NonAllocating: + // Same as NonBlocking, except without FE_ExcludeStaticLocalVars + return FE_InferrableOnCallees | FE_ExcludeThrow | FE_ExcludeCatch | + FE_ExcludeObjCMessageSend | FE_ExcludeThreadLocalVars; +case Kind::Blocking: +case Kind::Allocating: + return 0; +case Kind::None: + break; +} +llvm_unreachable("unknown effect kind"); + } + + /// The description printed in diagnostics, e.g. 'nonblocking'. + StringRef name() const; + + /// Return true if the effect is allowed to be inferred on the callee, + /// which is either a FunctionDecl or BlockDecl. + /// This is only used if the effect has FE_InferrableOnCallees flag set. + /// Example: This allows nonblocking(false) to prevent inference for the + /// function. + bool canInferOnFunction(const Decl &Callee) const; + + // Return false for success. When true is returned for a direct call, then the + // FE_InferrableOnCallees flag may trigger inference rather than an immediate + // diagnostic. Caller should be assumed to have the effect (it may not have it + // explicitly when inferring). + bool shouldDiagnoseFunctionCall(bool Direct, + ArrayRef CalleeFX) const; + + friend bool operator==(const FunctionEffect &LHS, const FunctionEffect &RHS) { +return LHS.FKind == RHS.FKind; + } + friend bool operator!=(const FunctionEffect &LHS, const FunctionEffect &RHS) { +return !(LHS == RHS); + } + friend bool operator<(const FunctionEffect &LHS, const FunctionEffect &RHS) { +return LHS.FKind < RHS.FKind; + } +}; + +/// Wrap a function effect's condition expression in another struct so +/// that FunctionProtoType's TrailingObjects can treat it separately. +class FunctionEffectCondition { + Expr *Cond = nullptr; // if null, unconditional + +public: + FunctionEffectCondition() = default; + FunctionEffectCondition(Expr *E) : Cond(E) {} // implicit OK + + Expr *expr() const { return Cond; } + + bool operator==(const FunctionEffectCondition &RHS) const { +return Cond == RHS.Cond; + } +}; + +/// A FunctionEffect plus a potential boolean expression determining whether +/// the effect is declared (e.g. nonblocking(expr)). Generally the condition +/// expression when present, is dependent. +struct FunctionEffectWithCondition { + FunctionEffect Effect; + FunctionEffectCondition Cond; + + /// Return a textual description of the effect, and its condition, if any. + std::string description() const; +}; + +struct FunctionEffectDiff { + enum class Kind { Added, Removed, ConditionMismatch }; + + FunctionEffect::Kind EffectKind; + Kind DiffKind; + FunctionEffectWithCondition Old; // invalid when Adde
[clang] nonblocking/nonallocating attributes (was: nolock/noalloc) (PR #84983)
@@ -4639,6 +4644,312 @@ class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { } }; +// -- + +class Decl; +class CXXMethodDecl; +struct FunctionEffectDiff; +class FunctionEffectsRef; +class FunctionEffectSet; + +/// Represents an abstract function effect, using just an enumeration describing +/// its kind. +class FunctionEffect { +public: + /// Identifies the particular effect. + enum class Kind : uint8_t { +None = 0, +NonBlocking = 1, +NonAllocating = 2, +Blocking = 3, +Allocating = 4 + }; + + /// Flags describing some behaviors of the effect. + using Flags = unsigned; + enum FlagBit : Flags { +// Can verification inspect callees' implementations? (e.g. nonblocking: +// yes, tcb+types: no). This also implies the need for 2nd-pass +// verification. +FE_InferrableOnCallees = 0x1, + +// Language constructs which effects can diagnose as disallowed. +FE_ExcludeThrow = 0x2, +FE_ExcludeCatch = 0x4, +FE_ExcludeObjCMessageSend = 0x8, +FE_ExcludeStaticLocalVars = 0x10, +FE_ExcludeThreadLocalVars = 0x20 + }; + +private: + LLVM_PREFERRED_TYPE(Kind) + unsigned FKind : 3; + + // Expansion: for hypothetical TCB+types, there could be one Kind for TCB, + // then ~16(?) bits "SubKind" to map to a specific named TCB. SubKind would + // be considered for uniqueness. + +public: + FunctionEffect() : FKind(unsigned(Kind::None)) {} + + explicit FunctionEffect(Kind K) : FKind(unsigned(K)) {} + + /// The kind of the effect. + Kind kind() const { return Kind(FKind); } + + /// Return the opposite kind, for effects which have opposites. + Kind oppositeKind() const; + + /// For serialization. + uint32_t toOpaqueInt32() const { return FKind; } + static FunctionEffect fromOpaqueInt32(uint32_t Value) { +return FunctionEffect(Kind(Value)); + } + + /// Flags describing some behaviors of the effect. + Flags flags() const { +switch (kind()) { +case Kind::NonBlocking: + return FE_InferrableOnCallees | FE_ExcludeThrow | FE_ExcludeCatch | + FE_ExcludeObjCMessageSend | FE_ExcludeStaticLocalVars | + FE_ExcludeThreadLocalVars; +case Kind::NonAllocating: + // Same as NonBlocking, except without FE_ExcludeStaticLocalVars + return FE_InferrableOnCallees | FE_ExcludeThrow | FE_ExcludeCatch | + FE_ExcludeObjCMessageSend | FE_ExcludeThreadLocalVars; +case Kind::Blocking: +case Kind::Allocating: + return 0; +case Kind::None: + break; +} +llvm_unreachable("unknown effect kind"); + } + + /// The description printed in diagnostics, e.g. 'nonblocking'. + StringRef name() const; + + /// Return true if the effect is allowed to be inferred on the callee, + /// which is either a FunctionDecl or BlockDecl. + /// This is only used if the effect has FE_InferrableOnCallees flag set. + /// Example: This allows nonblocking(false) to prevent inference for the + /// function. + bool canInferOnFunction(const Decl &Callee) const; + + // Return false for success. When true is returned for a direct call, then the + // FE_InferrableOnCallees flag may trigger inference rather than an immediate + // diagnostic. Caller should be assumed to have the effect (it may not have it + // explicitly when inferring). + bool shouldDiagnoseFunctionCall(bool Direct, + ArrayRef CalleeFX) const; + + friend bool operator==(const FunctionEffect &LHS, const FunctionEffect &RHS) { +return LHS.FKind == RHS.FKind; + } + friend bool operator!=(const FunctionEffect &LHS, const FunctionEffect &RHS) { +return !(LHS == RHS); + } + friend bool operator<(const FunctionEffect &LHS, const FunctionEffect &RHS) { +return LHS.FKind < RHS.FKind; + } +}; + +/// Wrap a function effect's condition expression in another struct so +/// that FunctionProtoType's TrailingObjects can treat it separately. +class FunctionEffectCondition { + Expr *Cond = nullptr; // if null, unconditional + +public: + FunctionEffectCondition() = default; + FunctionEffectCondition(Expr *E) : Cond(E) {} // implicit OK + + Expr *expr() const { return Cond; } + + bool operator==(const FunctionEffectCondition &RHS) const { +return Cond == RHS.Cond; + } +}; + +/// A FunctionEffect plus a potential boolean expression determining whether +/// the effect is declared (e.g. nonblocking(expr)). Generally the condition +/// expression when present, is dependent. +struct FunctionEffectWithCondition { + FunctionEffect Effect; + FunctionEffectCondition Cond; + + /// Return a textual description of the effect, and its condition, if any. + std::string description() const; +}; + +struct FunctionEffectDiff { + enum class Kind { Added, Removed, ConditionMismatch }; + + FunctionEffect::Kind EffectKind; + Kind DiffKind; + FunctionEffectWithCondition Old; // invalid when Adde
[clang] nonblocking/nonallocating attributes (was: nolock/noalloc) (PR #84983)
@@ -4639,6 +4644,312 @@ class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { } }; +// -- + +class Decl; +class CXXMethodDecl; +struct FunctionEffectDiff; +class FunctionEffectsRef; +class FunctionEffectSet; + +/// Represents an abstract function effect, using just an enumeration describing +/// its kind. +class FunctionEffect { +public: + /// Identifies the particular effect. + enum class Kind : uint8_t { +None = 0, +NonBlocking = 1, +NonAllocating = 2, +Blocking = 3, +Allocating = 4 + }; + + /// Flags describing some behaviors of the effect. + using Flags = unsigned; + enum FlagBit : Flags { +// Can verification inspect callees' implementations? (e.g. nonblocking: +// yes, tcb+types: no). This also implies the need for 2nd-pass +// verification. +FE_InferrableOnCallees = 0x1, + +// Language constructs which effects can diagnose as disallowed. +FE_ExcludeThrow = 0x2, +FE_ExcludeCatch = 0x4, +FE_ExcludeObjCMessageSend = 0x8, +FE_ExcludeStaticLocalVars = 0x10, +FE_ExcludeThreadLocalVars = 0x20 + }; + +private: + LLVM_PREFERRED_TYPE(Kind) + unsigned FKind : 3; + + // Expansion: for hypothetical TCB+types, there could be one Kind for TCB, + // then ~16(?) bits "SubKind" to map to a specific named TCB. SubKind would + // be considered for uniqueness. + +public: + FunctionEffect() : FKind(unsigned(Kind::None)) {} + + explicit FunctionEffect(Kind K) : FKind(unsigned(K)) {} + + /// The kind of the effect. + Kind kind() const { return Kind(FKind); } + + /// Return the opposite kind, for effects which have opposites. + Kind oppositeKind() const; + + /// For serialization. + uint32_t toOpaqueInt32() const { return FKind; } + static FunctionEffect fromOpaqueInt32(uint32_t Value) { +return FunctionEffect(Kind(Value)); + } + + /// Flags describing some behaviors of the effect. + Flags flags() const { +switch (kind()) { +case Kind::NonBlocking: + return FE_InferrableOnCallees | FE_ExcludeThrow | FE_ExcludeCatch | + FE_ExcludeObjCMessageSend | FE_ExcludeStaticLocalVars | + FE_ExcludeThreadLocalVars; +case Kind::NonAllocating: + // Same as NonBlocking, except without FE_ExcludeStaticLocalVars + return FE_InferrableOnCallees | FE_ExcludeThrow | FE_ExcludeCatch | + FE_ExcludeObjCMessageSend | FE_ExcludeThreadLocalVars; +case Kind::Blocking: +case Kind::Allocating: + return 0; +case Kind::None: + break; +} +llvm_unreachable("unknown effect kind"); + } + + /// The description printed in diagnostics, e.g. 'nonblocking'. + StringRef name() const; + + /// Return true if the effect is allowed to be inferred on the callee, + /// which is either a FunctionDecl or BlockDecl. + /// This is only used if the effect has FE_InferrableOnCallees flag set. + /// Example: This allows nonblocking(false) to prevent inference for the + /// function. + bool canInferOnFunction(const Decl &Callee) const; + + // Return false for success. When true is returned for a direct call, then the + // FE_InferrableOnCallees flag may trigger inference rather than an immediate + // diagnostic. Caller should be assumed to have the effect (it may not have it + // explicitly when inferring). + bool shouldDiagnoseFunctionCall(bool Direct, + ArrayRef CalleeFX) const; + + friend bool operator==(const FunctionEffect &LHS, const FunctionEffect &RHS) { +return LHS.FKind == RHS.FKind; + } + friend bool operator!=(const FunctionEffect &LHS, const FunctionEffect &RHS) { +return !(LHS == RHS); + } + friend bool operator<(const FunctionEffect &LHS, const FunctionEffect &RHS) { +return LHS.FKind < RHS.FKind; + } +}; + +/// Wrap a function effect's condition expression in another struct so +/// that FunctionProtoType's TrailingObjects can treat it separately. +class FunctionEffectCondition { + Expr *Cond = nullptr; // if null, unconditional + +public: + FunctionEffectCondition() = default; + FunctionEffectCondition(Expr *E) : Cond(E) {} // implicit OK + + Expr *expr() const { return Cond; } + + bool operator==(const FunctionEffectCondition &RHS) const { +return Cond == RHS.Cond; + } +}; + +/// A FunctionEffect plus a potential boolean expression determining whether +/// the effect is declared (e.g. nonblocking(expr)). Generally the condition +/// expression when present, is dependent. +struct FunctionEffectWithCondition { + FunctionEffect Effect; + FunctionEffectCondition Cond; + + /// Return a textual description of the effect, and its condition, if any. + std::string description() const; +}; + +struct FunctionEffectDiff { dougsonos wrote: Moved to Sema https://github.com/llvm/llvm-project/pull/84983 ___ cfe-commits mailing list
[clang] nonblocking/nonallocating attributes (was: nolock/noalloc) (PR #84983)
@@ -4639,6 +4644,312 @@ class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { } }; +// -- + +class Decl; +class CXXMethodDecl; +struct FunctionEffectDiff; +class FunctionEffectsRef; +class FunctionEffectSet; dougsonos wrote: Cleaned up https://github.com/llvm/llvm-project/pull/84983 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] nonblocking/nonallocating attributes (was: nolock/noalloc) (PR #84983)
https://github.com/dougsonos edited https://github.com/llvm/llvm-project/pull/84983 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 57f13b5 - [HLSL] Remove overridden -S
Author: Fangrui Song Date: 2024-05-05T12:53:34-07:00 New Revision: 57f13b51bdb373534ba5e507868b353a015107de URL: https://github.com/llvm/llvm-project/commit/57f13b51bdb373534ba5e507868b353a015107de DIFF: https://github.com/llvm/llvm-project/commit/57f13b51bdb373534ba5e507868b353a015107de.diff LOG: [HLSL] Remove overridden -S The cc1 option -S (https://reviews.llvm.org/D124983) is overridden by the latter -emit-llvm. Added: Modified: clang/lib/Driver/ToolChains/HLSL.cpp clang/test/Driver/dxc_fcgl.hlsl Removed: diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp b/clang/lib/Driver/ToolChains/HLSL.cpp index 1169b5d8c92dd6..558e4db46f8182 100644 --- a/clang/lib/Driver/ToolChains/HLSL.cpp +++ b/clang/lib/Driver/ToolChains/HLSL.cpp @@ -218,8 +218,7 @@ HLSLToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch, } } if (A->getOption().getID() == options::OPT_emit_pristine_llvm) { - // Translate fcgl into -S -emit-llvm and -disable-llvm-passes. - DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_S)); + // Translate -fcgl into -emit-llvm and -disable-llvm-passes. DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_emit_llvm)); DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_disable_llvm_passes)); diff --git a/clang/test/Driver/dxc_fcgl.hlsl b/clang/test/Driver/dxc_fcgl.hlsl index 567bad1bc13b5a..cfbf2503ddaaeb 100644 --- a/clang/test/Driver/dxc_fcgl.hlsl +++ b/clang/test/Driver/dxc_fcgl.hlsl @@ -1,6 +1,6 @@ // RUN: not %clang_dxc -fcgl -T lib_6_7 foo.hlsl -### %s 2>&1 | FileCheck %s -// Make sure fcgl option flag which translated into "-S" "-emit-llvm" "-disable-llvm-passes". +// Make sure fcgl option flag which translated into "-emit-llvm" "-disable-llvm-passes". // CHECK:"-S" // CHECK-SAME:"-emit-llvm" "-disable-llvm-passes" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Implement P2809: Trivial infinite loops are not Undefined Behavior (PR #90066)
@@ -908,6 +908,69 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { incrementProfileCounter(&S); } +bool CodeGenFunction::checkIfLoopMustProgress(const Expr *ControllingExpression, + bool HasEmptyBody) { + if (CGM.getCodeGenOpts().getFiniteLoops() == + CodeGenOptions::FiniteLoopsKind::Never) +return false; + + // Now apply rules for plain C (see 6.8.5.6 in C11). + // Loops with constant conditions do not have to make progress in any C + // version. + // As an extension, we consisider loops whose constant expression + // can be constant-folded. + Expr::EvalResult Result; + bool CondIsConstInt = efriedma-quic wrote: So... we treat it as a manifestly constant-evaluated for the purpose of checking whether the loop is trivial, but then flips to not manifestly constant-evaluated for the actual evaluation at runtime? The wording could use some clarification... Due to the way Sema::CheckForImmediateInvocation works, once we decide an expression is not manifestly constant-evaluated, we can't actually constant-evaluate it, I think; the AST is modified. Maybe we can run constant-evaluation before Sema::CheckForImmediateInvocation runs, though. https://github.com/llvm/llvm-project/pull/90066 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] cc1: Report an error for multiple actions unless separated by -main-file-name (PR #91140)
https://github.com/MaskRay created https://github.com/llvm/llvm-project/pull/91140 When multiple actions are specified, the last one is used and others are overridden. This might lead to confusion if the user is used to driver's `-S -emit-llvm` behavior. ``` %clang_cc1 -S -emit-llvm a.c # -S is overridden %clang_cc1 -emit-llvm -S a.c # -emit-llvm is overridden %clang_cc1 -fsyntax-only -S a.c # -fsyntax-only is overridden ``` However, we want to continue supporting overriding the driver action with -Xclang: * `clang -c -Xclang -ast-dump a.c` (`%clang -cc1 -emit-obj ... -main-file-name a.c ... -ast-dump`) * `clang -c -xc++ -Xclang -emit-module stl.modulemap` As an exception, we allow -ast-dump* options to be composed together (e.g. `-ast-dump -ast-dump-lookups` in AST/ast-dump-lookups.cpp). >From c8677337fbcc6a1456466e65dd847f9317f16a4f Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 5 May 2024 13:06:36 -0700 Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?= =?UTF-8?q?l=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.5-bogner --- .../clang/Basic/DiagnosticFrontendKinds.td| 2 ++ clang/lib/Frontend/CompilerInvocation.cpp | 24 +++ clang/test/Frontend/multiple-actions.c| 7 ++ 3 files changed, 33 insertions(+) create mode 100644 clang/test/Frontend/multiple-actions.c diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index fcffadacc8e631..48c174cfa9e8a5 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -134,6 +134,8 @@ def err_fe_no_pch_in_dir : Error< "no suitable precompiled header file found in directory '%0'">; def err_fe_action_not_available : Error< "action %0 not compiled in">; +def err_fe_invalid_multiple_actions : Error< +"action %0 is specified, another action is not allowed: %1">; def err_fe_invalid_alignment : Error< "invalid value '%1' in '%0'; alignment must be a power of 2">; def err_fe_invalid_exception_model diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 8312abc3603953..4a4c02b03ce938 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -2841,6 +2841,30 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, } Opts.ProgramAction = *ProgramAction; + +// Catch common mistakes when multiple actions are specified for cc1 (e.g. +// -S -emit-llvm means -emit-llvm while -emit-llvm -S means -S). However, to +// support driver `-c -Xclang ACTION` (-cc1 -emit-llvm file -main-file-name +// X ACTION), we suppress the error when the two actions are separated by +// -main-file-name. +// +// As an exception, accept composable -ast-dump*. +if (!A->getSpelling().starts_with("-ast-dump")) { + const Arg *SavedAction = nullptr; + for (const Arg *AA : + Args.filtered(OPT_Action_Group, OPT_main_file_name)) { +if (AA->getOption().matches(OPT_main_file_name)) { + SavedAction = nullptr; +} else if (!SavedAction) { + SavedAction = AA; +} else { + if (!A->getOption().matches(OPT_ast_dump_EQ)) +Diags.Report(diag::err_fe_invalid_multiple_actions) +<< A->getSpelling() << SavedAction->getSpelling(); + break; +} + } +} } if (const Arg* A = Args.getLastArg(OPT_plugin)) { diff --git a/clang/test/Frontend/multiple-actions.c b/clang/test/Frontend/multiple-actions.c new file mode 100644 index 00..5dd9ac3c8754f7 --- /dev/null +++ b/clang/test/Frontend/multiple-actions.c @@ -0,0 +1,7 @@ +// RUN: not %clang_cc1 -S -emit-llvm -main-file-name %s 2>&1 | FileCheck %s --check-prefix=ERR1 --implicit-check-not=error: +// ERR1: error: action -emit-llvm is specified, another action is not allowed: -S + +// RUN: not %clang_cc1 -main-file-name %s -emit-llvm-only -emit-llvm -S 2>&1 | FileCheck %s --check-prefix=ERR2 --implicit-check-not=error: +// ERR2: error: action -S is specified, another action is not allowed: -emit-llvm-only + +// RUN: %clang_cc1 -S -main-file-name %s -emit-llvm -o /dev/null ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] cc1: Report an error for multiple actions unless separated by -main-file-name (PR #91140)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Fangrui Song (MaskRay) Changes When multiple actions are specified, the last one is used and others are overridden. This might lead to confusion if the user is used to driver's `-S -emit-llvm` behavior. ``` %clang_cc1 -S -emit-llvm a.c # -S is overridden %clang_cc1 -emit-llvm -S a.c # -emit-llvm is overridden %clang_cc1 -fsyntax-only -S a.c # -fsyntax-only is overridden ``` However, we want to continue supporting overriding the driver action with -Xclang: * `clang -c -Xclang -ast-dump a.c` (`%clang -cc1 -emit-obj ... -main-file-name a.c ... -ast-dump`) * `clang -c -xc++ -Xclang -emit-module stl.modulemap` As an exception, we allow -ast-dump* options to be composed together (e.g. `-ast-dump -ast-dump-lookups` in AST/ast-dump-lookups.cpp). --- Full diff: https://github.com/llvm/llvm-project/pull/91140.diff 3 Files Affected: - (modified) clang/include/clang/Basic/DiagnosticFrontendKinds.td (+2) - (modified) clang/lib/Frontend/CompilerInvocation.cpp (+24) - (added) clang/test/Frontend/multiple-actions.c (+7) ``diff diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index fcffadacc8e631..48c174cfa9e8a5 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -134,6 +134,8 @@ def err_fe_no_pch_in_dir : Error< "no suitable precompiled header file found in directory '%0'">; def err_fe_action_not_available : Error< "action %0 not compiled in">; +def err_fe_invalid_multiple_actions : Error< +"action %0 is specified, another action is not allowed: %1">; def err_fe_invalid_alignment : Error< "invalid value '%1' in '%0'; alignment must be a power of 2">; def err_fe_invalid_exception_model diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 8312abc3603953..4a4c02b03ce938 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -2841,6 +2841,30 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, } Opts.ProgramAction = *ProgramAction; + +// Catch common mistakes when multiple actions are specified for cc1 (e.g. +// -S -emit-llvm means -emit-llvm while -emit-llvm -S means -S). However, to +// support driver `-c -Xclang ACTION` (-cc1 -emit-llvm file -main-file-name +// X ACTION), we suppress the error when the two actions are separated by +// -main-file-name. +// +// As an exception, accept composable -ast-dump*. +if (!A->getSpelling().starts_with("-ast-dump")) { + const Arg *SavedAction = nullptr; + for (const Arg *AA : + Args.filtered(OPT_Action_Group, OPT_main_file_name)) { +if (AA->getOption().matches(OPT_main_file_name)) { + SavedAction = nullptr; +} else if (!SavedAction) { + SavedAction = AA; +} else { + if (!A->getOption().matches(OPT_ast_dump_EQ)) +Diags.Report(diag::err_fe_invalid_multiple_actions) +<< A->getSpelling() << SavedAction->getSpelling(); + break; +} + } +} } if (const Arg* A = Args.getLastArg(OPT_plugin)) { diff --git a/clang/test/Frontend/multiple-actions.c b/clang/test/Frontend/multiple-actions.c new file mode 100644 index 00..5dd9ac3c8754f7 --- /dev/null +++ b/clang/test/Frontend/multiple-actions.c @@ -0,0 +1,7 @@ +// RUN: not %clang_cc1 -S -emit-llvm -main-file-name %s 2>&1 | FileCheck %s --check-prefix=ERR1 --implicit-check-not=error: +// ERR1: error: action -emit-llvm is specified, another action is not allowed: -S + +// RUN: not %clang_cc1 -main-file-name %s -emit-llvm-only -emit-llvm -S 2>&1 | FileCheck %s --check-prefix=ERR2 --implicit-check-not=error: +// ERR2: error: action -S is specified, another action is not allowed: -emit-llvm-only + +// RUN: %clang_cc1 -S -main-file-name %s -emit-llvm -o /dev/null `` https://github.com/llvm/llvm-project/pull/91140 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] solve crash due to function overloading. (PR #90255)
@@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm < %s efriedma-quic wrote: Have you seen https://llvm.org/docs/TestingGuide.html#regression-test-structure ? If you have any ideas for improving the documentation, please let me know (or better, propose a patch; it's generated from llvm/docs/TestingGuide.rst). https://github.com/llvm/llvm-project/pull/90255 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][dataflow] Fix crash when `operator=` result type is not destination type. (PR #90898)
https://github.com/Xazax-hun approved this pull request. https://github.com/llvm/llvm-project/pull/90898 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][dataflow] Fix crash when `operator=` result type is not destination type. (PR #90898)
@@ -556,14 +556,23 @@ class TransferVisitor : public ConstStmtVisitor { copyRecord(*LocSrc, *LocDst, Env); - // If the expr is a glvalue, we can reasonably assume the operator is - // returning T& and thus we can assign it `LocDst`. - if (S->isGLValue()) { + // The assignment operator can have an arbitrary return type. We model the + // return value only if the return type is the same as or a base class of + // the destination type. + if (S->getType().getCanonicalType().getUnqualifiedType() != + LocDst->getType().getCanonicalType().getUnqualifiedType()) { +auto ReturnDecl = S->getType()->getAsCXXRecordDecl(); +auto DstDecl = LocDst->getType()->getAsCXXRecordDecl(); +if (ReturnDecl == nullptr || DstDecl == nullptr) + return; +if (!DstDecl->isDerivedFrom(ReturnDecl)) Xazax-hun wrote: Would we want to create a fresh storage location here? https://github.com/llvm/llvm-project/pull/90898 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Don't allow comma in front of structural enum (PR #91056)
llvmbot wrote: @llvm/pr-subscribers-clang-format Author: Emilia Kond (rymiel) Changes Assume that a comma in front of `enum` means it is actually a part of an elaborated type in a template parameter list. Fixes https://github.com/llvm/llvm-project/issues/47782 --- Full diff: https://github.com/llvm/llvm-project/pull/91056.diff 2 Files Affected: - (modified) clang/lib/Format/UnwrappedLineParser.cpp (+3-2) - (modified) clang/unittests/Format/TokenAnnotatorTest.cpp (+4) ``diff diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index e8a8dd58d07eea..b5415fa9ecab55 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1763,8 +1763,9 @@ void UnwrappedLineParser::parseStructuralElement( break; } case tok::kw_enum: - // Ignore if this is part of "template enum". - if (Previous && Previous->isOneOf(tok::less, tok::arrow)) { + // Ignore if this is part of "template enum" or + // "template <..., enum ...>". + if (Previous && Previous->isOneOf(tok::less, tok::arrow, tok::comma)) { nextToken(); break; } diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 01daf8dee505bc..b424424b85777b 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -489,6 +489,10 @@ TEST_F(TokenAnnotatorTest, UnderstandsStructs) { EXPECT_TOKEN(Tokens[24], tok::amp, TT_UnaryOperator); EXPECT_TOKEN(Tokens[27], tok::l_square, TT_ArraySubscriptLSquare); EXPECT_TOKEN(Tokens[32], tok::r_brace, TT_StructRBrace); + + Tokens = annotate("template struct S {};"); + ASSERT_EQ(Tokens.size(), 15u) << Tokens; + EXPECT_TOKEN(Tokens[11], tok::l_brace, TT_StructLBrace); } TEST_F(TokenAnnotatorTest, UnderstandsUnions) { `` https://github.com/llvm/llvm-project/pull/91056 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][AArch64] Fixed incorrect _BitInt alignment (PR #90602)
https://github.com/efriedma-quic edited https://github.com/llvm/llvm-project/pull/90602 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][AArch64] Fixed incorrect _BitInt alignment (PR #90602)
https://github.com/efriedma-quic commented: LG https://github.com/llvm/llvm-project/pull/90602 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][AArch64] Fixed incorrect _BitInt alignment (PR #90602)
@@ -518,6 +518,16 @@ class TargetInfo : public TransferrableTargetInfo, /// getInt128Align() - Returns the alignment of Int128. unsigned getInt128Align() const { return Int128Align; } + /// getBitIntAlign/Width - Return aligned size of '_BitInt' and + /// 'unsigned _BitInt' for this target, in bits. + unsigned getBitIntWidth(unsigned NumBits) const { +return llvm::alignTo(NumBits, getBitIntAlign(NumBits)); + } + virtual unsigned getBitIntAlign(unsigned NumBits) const { efriedma-quic wrote: Instead of making this virtual, maybe it makes sense to add a field `std::optional BitIntMaxAlign` to TargetInfo? I expect the logic here besides the max width to be consistent across all targets. https://github.com/llvm/llvm-project/pull/90602 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][AArch64] Fixed incorrect _BitInt alignment (PR #90602)
@@ -1674,4 +1679,4 @@ void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { Builder.defineMacro("__RENDERSCRIPT__"); AArch64leTargetInfo::getTargetDefines(Opts, Builder); -} +} efriedma-quic wrote: Missing newline? https://github.com/llvm/llvm-project/pull/90602 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Revert "Revert "[OpenMP][TR12] change property of map-type modifier."… (PR #91141)
https://github.com/jyu2-git created https://github.com/llvm/llvm-project/pull/91141 … (#90885)" This reverts commit eea81aa29848361eb5b24f24d2af643fdeb9adfd. Also change isMapType as @vitalybuka suggested. Hope this fix sanitizer build problem. >From 563c1254162d7b42fd7579514f45df326216f508 Mon Sep 17 00:00:00 2001 From: Jennifer Yu Date: Sun, 5 May 2024 10:44:40 -0700 Subject: [PATCH] Revert "Revert "[OpenMP][TR12] change property of map-type modifier." (#90885)" This reverts commit eea81aa29848361eb5b24f24d2af643fdeb9adfd. --- .../clang/Basic/DiagnosticParseKinds.td | 5 + clang/lib/Parse/ParseOpenMP.cpp | 51 +++-- clang/test/OpenMP/target_ast_print.cpp| 58 ++ clang/test/OpenMP/target_map_messages.cpp | 105 ++ 4 files changed, 165 insertions(+), 54 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index fdffb35ea0d955..44bc4e0e130de8 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1438,6 +1438,9 @@ def err_omp_decl_in_declare_simd_variant : Error< def err_omp_sink_and_source_iteration_not_allowd: Error<" '%0 %select{sink:|source:}1' must be with '%select{omp_cur_iteration - 1|omp_cur_iteration}1'">; def err_omp_unknown_map_type : Error< "incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'">; +def err_omp_more_one_map_type : Error<"map type is already specified">; +def note_previous_map_type_specified_here +: Note<"map type '%0' is previous specified here">; def err_omp_unknown_map_type_modifier : Error< "incorrect map type modifier, expected one of: 'always', 'close', 'mapper'" "%select{|, 'present'|, 'present', 'iterator'}0%select{|, 'ompx_hold'}1">; @@ -1445,6 +1448,8 @@ def err_omp_map_type_missing : Error< "missing map type">; def err_omp_map_type_modifier_missing : Error< "missing map type modifier">; +def err_omp_map_modifier_specification_list : Error< + "empty modifier-specification-list is not allowed">; def err_omp_declare_simd_inbranch_notinbranch : Error< "unexpected '%0' clause, '%1' is specified already">; def err_omp_expected_clause_argument diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 18ba1185ee8de7..5265d8f1922c31 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -4228,13 +4228,20 @@ bool Parser::parseMapperModifier(SemaOpenMP::OpenMPVarListDataTy &Data) { return T.consumeClose(); } +static OpenMPMapClauseKind isMapType(Parser &P); + /// Parse map-type-modifiers in map clause. -/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list) +/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] [map-type] : ] list) /// where, map-type-modifier ::= always | close | mapper(mapper-identifier) | /// present +/// where, map-type ::= alloc | delete | from | release | to | tofrom bool Parser::parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data) { + bool HasMapType = false; + SourceLocation PreMapLoc = Tok.getLocation(); + StringRef PreMapName = ""; while (getCurToken().isNot(tok::colon)) { OpenMPMapModifierKind TypeModifier = isMapModifier(*this); +OpenMPMapClauseKind MapKind = isMapType(*this); if (TypeModifier == OMPC_MAP_MODIFIER_always || TypeModifier == OMPC_MAP_MODIFIER_close || TypeModifier == OMPC_MAP_MODIFIER_present || @@ -4257,6 +4264,19 @@ bool Parser::parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data) { Diag(Data.MapTypeModifiersLoc.back(), diag::err_omp_missing_comma) << "map type modifier"; +} else if (getLangOpts().OpenMP >= 60 && MapKind != OMPC_MAP_unknown) { + if (!HasMapType) { +HasMapType = true; +Data.ExtraModifier = MapKind; +MapKind = OMPC_MAP_unknown; +PreMapLoc = Tok.getLocation(); +PreMapName = Tok.getIdentifierInfo()->getName(); + } else { +Diag(Tok, diag::err_omp_more_one_map_type); +Diag(PreMapLoc, diag::note_previous_map_type_specified_here) +<< PreMapName; + } + ConsumeToken(); } else { // For the case of unknown map-type-modifier or a map-type. // Map-type is followed by a colon; the function returns when it @@ -4267,8 +4287,14 @@ bool Parser::parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data) { continue; } // Potential map-type token as it is followed by a colon. - if (PP.LookAhead(0).is(tok::colon)) -return false; + if (PP.LookAhead(0).is(tok::colon)) { +if (getLangOpts().OpenMP >= 60) { + break; +} else { + return false; +} + } + Diag(Tok, diag::err_omp_unknown_map_type_modifier) << (getLangOpts().OpenMP >= 51 ? (getLangOpts().OpenMP >= 52 ? 2 : 1)
[clang] [clang-format] Don't allow comma in front of structural enum (PR #91056)
https://github.com/owenca approved this pull request. https://github.com/llvm/llvm-project/pull/91056 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Revert "Revert "[OpenMP][TR12] change property of map-type modifier."… (PR #91141)
llvmbot wrote: @llvm/pr-subscribers-clang Author: None (jyu2-git) Changes … (#90885)" This reverts commit eea81aa29848361eb5b24f24d2af643fdeb9adfd. Also change isMapType as @vitalybuka suggested. Hope this fix sanitizer build problem. --- Patch is 29.74 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/91141.diff 4 Files Affected: - (modified) clang/include/clang/Basic/DiagnosticParseKinds.td (+5) - (modified) clang/lib/Parse/ParseOpenMP.cpp (+43-8) - (modified) clang/test/OpenMP/target_ast_print.cpp (+58) - (modified) clang/test/OpenMP/target_map_messages.cpp (+59-46) ``diff diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index fdffb35ea0d955..44bc4e0e130de8 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1438,6 +1438,9 @@ def err_omp_decl_in_declare_simd_variant : Error< def err_omp_sink_and_source_iteration_not_allowd: Error<" '%0 %select{sink:|source:}1' must be with '%select{omp_cur_iteration - 1|omp_cur_iteration}1'">; def err_omp_unknown_map_type : Error< "incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'">; +def err_omp_more_one_map_type : Error<"map type is already specified">; +def note_previous_map_type_specified_here +: Note<"map type '%0' is previous specified here">; def err_omp_unknown_map_type_modifier : Error< "incorrect map type modifier, expected one of: 'always', 'close', 'mapper'" "%select{|, 'present'|, 'present', 'iterator'}0%select{|, 'ompx_hold'}1">; @@ -1445,6 +1448,8 @@ def err_omp_map_type_missing : Error< "missing map type">; def err_omp_map_type_modifier_missing : Error< "missing map type modifier">; +def err_omp_map_modifier_specification_list : Error< + "empty modifier-specification-list is not allowed">; def err_omp_declare_simd_inbranch_notinbranch : Error< "unexpected '%0' clause, '%1' is specified already">; def err_omp_expected_clause_argument diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 18ba1185ee8de7..5265d8f1922c31 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -4228,13 +4228,20 @@ bool Parser::parseMapperModifier(SemaOpenMP::OpenMPVarListDataTy &Data) { return T.consumeClose(); } +static OpenMPMapClauseKind isMapType(Parser &P); + /// Parse map-type-modifiers in map clause. -/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list) +/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] [map-type] : ] list) /// where, map-type-modifier ::= always | close | mapper(mapper-identifier) | /// present +/// where, map-type ::= alloc | delete | from | release | to | tofrom bool Parser::parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data) { + bool HasMapType = false; + SourceLocation PreMapLoc = Tok.getLocation(); + StringRef PreMapName = ""; while (getCurToken().isNot(tok::colon)) { OpenMPMapModifierKind TypeModifier = isMapModifier(*this); +OpenMPMapClauseKind MapKind = isMapType(*this); if (TypeModifier == OMPC_MAP_MODIFIER_always || TypeModifier == OMPC_MAP_MODIFIER_close || TypeModifier == OMPC_MAP_MODIFIER_present || @@ -4257,6 +4264,19 @@ bool Parser::parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data) { Diag(Data.MapTypeModifiersLoc.back(), diag::err_omp_missing_comma) << "map type modifier"; +} else if (getLangOpts().OpenMP >= 60 && MapKind != OMPC_MAP_unknown) { + if (!HasMapType) { +HasMapType = true; +Data.ExtraModifier = MapKind; +MapKind = OMPC_MAP_unknown; +PreMapLoc = Tok.getLocation(); +PreMapName = Tok.getIdentifierInfo()->getName(); + } else { +Diag(Tok, diag::err_omp_more_one_map_type); +Diag(PreMapLoc, diag::note_previous_map_type_specified_here) +<< PreMapName; + } + ConsumeToken(); } else { // For the case of unknown map-type-modifier or a map-type. // Map-type is followed by a colon; the function returns when it @@ -4267,8 +4287,14 @@ bool Parser::parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data) { continue; } // Potential map-type token as it is followed by a colon. - if (PP.LookAhead(0).is(tok::colon)) -return false; + if (PP.LookAhead(0).is(tok::colon)) { +if (getLangOpts().OpenMP >= 60) { + break; +} else { + return false; +} + } + Diag(Tok, diag::err_omp_unknown_map_type_modifier) << (getLangOpts().OpenMP >= 51 ? (getLangOpts().OpenMP >= 52 ? 2 : 1) : 0) @@ -4278,6 +4304,14 @@ bool Parser::parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data) { if (getCurToken().is(tok::comma)) Consume
[clang] [llvm] [clang backend] In AArch64's DataLayout, specify a minimum function alignment of 4. (PR #90702)
https://github.com/efriedma-quic approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/90702 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [clang backend] In AArch64's DataLayout, specify a minimum function alignment of 4. (PR #90702)
efriedma-quic wrote: Which email address do you want the commit associated with? The GitHub "squash and merge" button wants to attribute it to your "sonosphere.com" address, but it looks like the commits themselves are using an "apple.com" address. https://github.com/llvm/llvm-project/pull/90702 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits