diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 37aea5f6657f01f9b3da1a81bedf3103ad8bddd1..45da8af51bb9cefa6312b8966bf6cd63a6dcc09e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -119,6 +119,10 @@ clang/test/AST/Interp/ @tbaederr /mlir/test/python/ @ftynse @makslevental @stellaraccident /mlir/python/ @ftynse @makslevental @stellaraccident +# MLIR Mem2Reg/SROA +/mlir/**/Transforms/Mem2Reg.* @moxinilian +/mlir/**/Transforms/SROA.* @moxinilian + # BOLT /bolt/ @aaupov @maksfb @rafaelauler @ayermolo @dcci diff --git a/bolt/test/AArch64/constant_island_pie_update.s b/bolt/test/AArch64/constant_island_pie_update.s index 0ab67d07a854ec49da550bfd0aa882c875a672b1..313e103b19c05a85e0ad0d8bb898d0d935d5b8b5 100644 --- a/bolt/test/AArch64/constant_island_pie_update.s +++ b/bolt/test/AArch64/constant_island_pie_update.s @@ -18,7 +18,7 @@ # RUN: llvm-objdump -j .text -d --show-all-symbols %t.relr.bolt | FileCheck %s # RUN: llvm-objdump -j .text -d %t.relr.bolt | \ # RUN: FileCheck %s --check-prefix=ADDENDCHECK -# RUN: llvm-readelf -rsW %t.relr.bolt | FileCheck --check-prefix=ELFCHECK %s +# RUN: llvm-readelf -rsW %t.relr.bolt | FileCheck --check-prefix=RELRELFCHECK %s # RUN: llvm-readelf -SW %t.relr.bolt | FileCheck --check-prefix=RELRSZCHECK %s // Check that the CI value was updated @@ -51,6 +51,12 @@ # ELFCHECK-NEXT: {{.*}} R_AARCH64_RELATIVE # ELFCHECK: {{.*}}[[#OFF]] {{.*}} $d +# RELRELFCHECK: $d{{$}} +# RELRELFCHECK-NEXT: $d + 0x8{{$}} +# RELRELFCHECK-NEXT: $d + 0x18{{$}} +# RELRELFCHECK-NEXT: mytextP +# RELRELFCHECK-EMPTY: + // Check that .relr.dyn size is 2 bytes to ensure that last 3 relocations were // encoded as a bitmap so the total section size for 3 relocations is 2 bytes. # RELRSZCHECK: .relr.dyn RELR [[#%x,ADDR:]] [[#%x,OFF:]] {{0*}}10 diff --git a/clang-tools-extra/clang-doc/Representation.cpp b/clang-tools-extra/clang-doc/Representation.cpp index 84233c36e15d989f8aca8a1023377e5566c6464b..2afff2929cf79c2bda5d40c26951f49d47c788f3 100644 --- a/clang-tools-extra/clang-doc/Representation.cpp +++ b/clang-tools-extra/clang-doc/Representation.cpp @@ -380,8 +380,8 @@ ClangDocContext::ClangDocContext(tooling::ExecutionContext *ECtx, this->SourceRoot = std::string(SourceRootDir); if (!RepositoryUrl.empty()) { this->RepositoryUrl = std::string(RepositoryUrl); - if (!RepositoryUrl.empty() && RepositoryUrl.find("http://") != 0 && - RepositoryUrl.find("https://") != 0) + if (!RepositoryUrl.empty() && !RepositoryUrl.starts_with("http://") && + !RepositoryUrl.starts_with("https://")) this->RepositoryUrl->insert(0, "https://"); } } diff --git a/clang-tools-extra/clang-tidy/GlobList.cpp b/clang-tools-extra/clang-tidy/GlobList.cpp index dfe3f7c505b1747126de68ea3075999c3b1ff4f6..8f09ee075bbd6e854301fbefa01e65693604bd55 100644 --- a/clang-tools-extra/clang-tidy/GlobList.cpp +++ b/clang-tools-extra/clang-tidy/GlobList.cpp @@ -19,12 +19,17 @@ static bool consumeNegativeIndicator(StringRef &GlobList) { return GlobList.consume_front("-"); } -// Converts first glob from the comma-separated list of globs to Regex and -// removes it and the trailing comma from the GlobList. -static llvm::Regex consumeGlob(StringRef &GlobList) { +// Extracts the first glob from the comma-separated list of globs, +// removes it and the trailing comma from the GlobList and +// returns the extracted glob. +static llvm::StringRef extractNextGlob(StringRef &GlobList) { StringRef UntrimmedGlob = GlobList.substr(0, GlobList.find_first_of(",\n")); StringRef Glob = UntrimmedGlob.trim(); GlobList = GlobList.substr(UntrimmedGlob.size() + 1); + return Glob; +} + +static llvm::Regex createRegexFromGlob(StringRef &Glob) { SmallString<128> RegexText("^"); StringRef MetaChars("()^$|*+?.[]\\{}"); for (char C : Glob) { @@ -43,7 +48,8 @@ GlobList::GlobList(StringRef Globs, bool KeepNegativeGlobs /* =true */) { do { GlobListItem Item; Item.IsPositive = !consumeNegativeIndicator(Globs); - Item.Regex = consumeGlob(Globs); + Item.Text = extractNextGlob(Globs); + Item.Regex = createRegexFromGlob(Item.Text); if (Item.IsPositive || KeepNegativeGlobs) Items.push_back(std::move(Item)); } while (!Globs.empty()); diff --git a/clang-tools-extra/clang-tidy/GlobList.h b/clang-tools-extra/clang-tidy/GlobList.h index 44af182e43b0024c16153d20c757f84795c67b13..4317928270adff9496579f934be576b990a03565 100644 --- a/clang-tools-extra/clang-tidy/GlobList.h +++ b/clang-tools-extra/clang-tidy/GlobList.h @@ -44,8 +44,12 @@ private: struct GlobListItem { bool IsPositive; llvm::Regex Regex; + llvm::StringRef Text; }; SmallVector Items; + +public: + const SmallVectorImpl &getItems() const { return Items; }; }; /// A \p GlobList that caches search results, so that search is performed only diff --git a/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp index 5260a8b4ecb0bad3358ddb2bbc519a5be82ad26d..32f5edddfe80b158d96df4fa569ee59dfe0ad210 100644 --- a/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp @@ -8,7 +8,9 @@ #include "LambdaFunctionNameCheck.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/DeclCXX.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Lex/MacroInfo.h" #include "clang/Lex/Preprocessor.h" @@ -56,6 +58,8 @@ private: LambdaFunctionNameCheck::SourceRangeSet* SuppressMacroExpansions; }; +AST_MATCHER(CXXMethodDecl, isInLambda) { return Node.getParent()->isLambda(); } + } // namespace LambdaFunctionNameCheck::LambdaFunctionNameCheck(StringRef Name, @@ -69,9 +73,13 @@ void LambdaFunctionNameCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void LambdaFunctionNameCheck::registerMatchers(MatchFinder *Finder) { - // Match on PredefinedExprs inside a lambda. - Finder->addMatcher(predefinedExpr(hasAncestor(lambdaExpr())).bind("E"), - this); + Finder->addMatcher( + cxxMethodDecl(isInLambda(), + hasBody(forEachDescendant( + predefinedExpr(hasAncestor(cxxMethodDecl().bind("fn"))) + .bind("E"))), + equalsBoundNode("fn")), + this); } void LambdaFunctionNameCheck::registerPPCallbacks( diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp index 9f3d6b6db6cbca1b0cc9aa3b7c71b4746f34d712..f82f4417141d3df287dfafb5182715aa09be7352 100644 --- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp +++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp @@ -454,52 +454,27 @@ static constexpr StringLiteral VerifyConfigWarningEnd = " [-verify-config]\n"; static bool verifyChecks(const StringSet<> &AllChecks, StringRef CheckGlob, StringRef Source) { - llvm::StringRef Cur, Rest; + GlobList Globs(CheckGlob); bool AnyInvalid = false; - for (std::tie(Cur, Rest) = CheckGlob.split(','); - !(Cur.empty() && Rest.empty()); std::tie(Cur, Rest) = Rest.split(',')) { - Cur = Cur.trim(); - if (Cur.empty()) + for (const auto &Item : Globs.getItems()) { + if (Item.Text.starts_with("clang-diagnostic")) continue; - Cur.consume_front("-"); - if (Cur.starts_with("clang-diagnostic")) - continue; - if (Cur.contains('*')) { - SmallString<128> RegexText("^"); - StringRef MetaChars("()^$|*+?.[]\\{}"); - for (char C : Cur) { - if (C == '*') - RegexText.push_back('.'); - else if (MetaChars.contains(C)) - RegexText.push_back('\\'); - RegexText.push_back(C); - } - RegexText.push_back('$'); - llvm::Regex Glob(RegexText); - std::string Error; - if (!Glob.isValid(Error)) { - AnyInvalid = true; - llvm::WithColor::error(llvm::errs(), Source) - << "building check glob '" << Cur << "' " << Error << "'\n"; - continue; - } - if (llvm::none_of(AllChecks.keys(), - [&Glob](StringRef S) { return Glob.match(S); })) { - AnyInvalid = true; + if (llvm::none_of(AllChecks.keys(), + [&Item](StringRef S) { return Item.Regex.match(S); })) { + AnyInvalid = true; + if (Item.Text.contains('*')) llvm::WithColor::warning(llvm::errs(), Source) - << "check glob '" << Cur << "' doesn't match any known check" + << "check glob '" << Item.Text << "' doesn't match any known check" << VerifyConfigWarningEnd; + else { + llvm::raw_ostream &Output = + llvm::WithColor::warning(llvm::errs(), Source) + << "unknown check '" << Item.Text << '\''; + llvm::StringRef Closest = closest(Item.Text, AllChecks); + if (!Closest.empty()) + Output << "; did you mean '" << Closest << '\''; + Output << VerifyConfigWarningEnd; } - } else { - if (AllChecks.contains(Cur)) - continue; - AnyInvalid = true; - llvm::raw_ostream &Output = llvm::WithColor::warning(llvm::errs(), Source) - << "unknown check '" << Cur << '\''; - llvm::StringRef Closest = closest(Cur, AllChecks); - if (!Closest.empty()) - Output << "; did you mean '" << Closest << '\''; - Output << VerifyConfigWarningEnd; } } return AnyInvalid; diff --git a/clang-tools-extra/clangd/unittests/CMakeLists.txt b/clang-tools-extra/clangd/unittests/CMakeLists.txt index e432db8d0912e736743149943c39672998f7f7ed..7f1ae5c43d80c69cd896c886cdd4100467e9b88c 100644 --- a/clang-tools-extra/clangd/unittests/CMakeLists.txt +++ b/clang-tools-extra/clangd/unittests/CMakeLists.txt @@ -2,6 +2,7 @@ set(LLVM_LINK_COMPONENTS support AllTargetsInfos FrontendOpenMP + TargetParser ) if(CLANG_BUILT_STANDALONE) diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp index 0af6036734ba53b49cb8772f508f9415a8aed04f..799a549ff0816e388cb6acdda5e04d1ddb7f38b4 100644 --- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -427,7 +427,7 @@ TEST_F(TargetDeclTest, Types) { [[auto]] X = S{}; )cpp"; // FIXME: deduced type missing in AST. https://llvm.org/PR42914 - EXPECT_DECLS("AutoTypeLoc"); + EXPECT_DECLS("AutoTypeLoc", ); Code = R"cpp( template @@ -727,13 +727,13 @@ TEST_F(TargetDeclTest, BuiltinTemplates) { template using make_integer_sequence = [[__make_integer_seq]]; )cpp"; - EXPECT_DECLS("TemplateSpecializationTypeLoc"); + EXPECT_DECLS("TemplateSpecializationTypeLoc", ); Code = R"cpp( template using type_pack_element = [[__type_pack_element]]; )cpp"; - EXPECT_DECLS("TemplateSpecializationTypeLoc"); + EXPECT_DECLS("TemplateSpecializationTypeLoc", ); } TEST_F(TargetDeclTest, MemberOfTemplate) { @@ -1018,7 +1018,7 @@ TEST_F(TargetDeclTest, DependentTypes) { typedef typename waldo::type::[[next]] type; }; )cpp"; - EXPECT_DECLS("DependentNameTypeLoc"); + EXPECT_DECLS("DependentNameTypeLoc", ); // Similar to above but using mutually recursive templates. Code = R"cpp( @@ -1035,7 +1035,7 @@ TEST_F(TargetDeclTest, DependentTypes) { using type = typename even::type::[[next]]; }; )cpp"; - EXPECT_DECLS("DependentNameTypeLoc"); + EXPECT_DECLS("DependentNameTypeLoc", ); } TEST_F(TargetDeclTest, TypedefCascade) { @@ -1263,14 +1263,14 @@ TEST_F(TargetDeclTest, ObjC) { + ([[id]])sharedInstance; @end )cpp"; - EXPECT_DECLS("TypedefTypeLoc"); + EXPECT_DECLS("TypedefTypeLoc", ); Code = R"cpp( @interface Foo + ([[instancetype]])sharedInstance; @end )cpp"; - EXPECT_DECLS("TypedefTypeLoc"); + EXPECT_DECLS("TypedefTypeLoc", ); } class FindExplicitReferencesTest : public ::testing::Test { diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index a457e6fcae946256ee907b33a206542f29f1c055..f3f9a81f9a8e8275712473681f8f6718b8608b1b 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -103,6 +103,9 @@ Improvements to clang-tidy - Improved :program:`check_clang_tidy.py` script. Added argument `-export-fixes` to aid in clang-tidy and test development. +- Fixed ``--verify-config`` option not properly parsing checks when using the + literal operator in the ``.clang-tidy`` config. + New checks ^^^^^^^^^^ @@ -155,6 +158,10 @@ Changes in existing checks ` check to ignore code within unevaluated contexts, such as ``decltype``. +- Improved :doc:`bugprone-lambda-function-name` + check by ignoring ``__func__`` macro in lambda captures, initializers of + default parameters and nested function declarations. + - Improved :doc:`bugprone-non-zero-enum-to-bool-conversion ` check by eliminating false positives resulting from direct usage of bitwise operators diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 8bc46acad56c8416ba8fad3bf592be0fc021e20e..3a06d7c30c9b79e647e2525a67577acf84121345 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -341,9 +341,9 @@ Clang-Tidy Checks :doc:`portability-std-allocator-const `, :doc:`readability-avoid-const-params-in-decls `, "Yes" :doc:`readability-avoid-nested-conditional-operator `, - :doc:`readability-avoid-return-with-void-value `, + :doc:`readability-avoid-return-with-void-value `, "Yes" :doc:`readability-avoid-unconditional-preprocessor-if `, - :doc:`readability-braces-around-statements `, "Yes" + :doc:`readability-braces-around-statements `, :doc:`readability-const-return-type `, "Yes" :doc:`readability-container-contains `, "Yes" :doc:`readability-container-data-pointer `, "Yes" @@ -529,12 +529,12 @@ Clang-Tidy Checks :doc:`cppcoreguidelines-non-private-member-variables-in-classes `, :doc:`misc-non-private-member-variables-in-classes `, :doc:`cppcoreguidelines-use-default-member-init `, :doc:`modernize-use-default-member-init `, "Yes" :doc:`fuchsia-header-anon-namespaces `, :doc:`google-build-namespaces `, - :doc:`google-readability-braces-around-statements `, :doc:`readability-braces-around-statements `, "Yes" + :doc:`google-readability-braces-around-statements `, :doc:`readability-braces-around-statements `, :doc:`google-readability-function-size `, :doc:`readability-function-size `, :doc:`google-readability-namespace-comments `, :doc:`llvm-namespace-comment `, :doc:`hicpp-avoid-c-arrays `, :doc:`modernize-avoid-c-arrays `, :doc:`hicpp-avoid-goto `, :doc:`cppcoreguidelines-avoid-goto `, - :doc:`hicpp-braces-around-statements `, :doc:`readability-braces-around-statements `, "Yes" + :doc:`hicpp-braces-around-statements `, :doc:`readability-braces-around-statements `, :doc:`hicpp-deprecated-headers `, :doc:`modernize-deprecated-headers `, "Yes" :doc:`hicpp-explicit-conversions `, :doc:`google-explicit-constructor `, "Yes" :doc:`hicpp-function-size `, :doc:`readability-function-size `, diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/lambda-function-name.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/lambda-function-name.cpp index 936ee87a856cd2ff0c36856e81178be3ea916cfa..5c2bb5713239ce1b8a1d9117cf48d1f1e528667a 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/lambda-function-name.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/lambda-function-name.cpp @@ -19,6 +19,22 @@ void Positives() { // CHECK-MESSAGES-NO-CONFIG: :[[@LINE-1]]:8: warning: inside a lambda, '__FUNCTION__' expands to the name of the function call operator; consider capturing the name of the enclosing function explicitly [bugprone-lambda-function-name] [] { EMBED_IN_ANOTHER_MACRO1; }(); // CHECK-MESSAGES-NO-CONFIG: :[[@LINE-1]]:8: warning: inside a lambda, '__func__' expands to the name of the function call operator; consider capturing the name of the enclosing function explicitly [bugprone-lambda-function-name] + [] { + __func__; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: inside a lambda, '__func__' expands to the name of the function call operator; consider capturing the name of the enclosing function explicitly [bugprone-lambda-function-name] + struct S { + void f() { + __func__; + [] { + __func__; + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: inside a lambda, '__func__' expands to the name of the function call operator; consider capturing the name of the enclosing function explicitly [bugprone-lambda-function-name] + }(); + __func__; + } + }; + __func__; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: inside a lambda, '__func__' expands to the name of the function call operator; consider capturing the name of the enclosing function explicitly [bugprone-lambda-function-name] + }(); } #define FUNC_MACRO_WITH_FILE_AND_LINE Foo(__func__, __FILE__, __LINE__) @@ -40,4 +56,7 @@ void Negatives() { [] { FUNC_MACRO_WITH_FILE_AND_LINE; }(); [] { FUNCTION_MACRO_WITH_FILE_AND_LINE; }(); [] { EMBED_IN_ANOTHER_MACRO2; }(); + + [] (const char* func = __func__) { func; }(); + [func=__func__] { func; }(); } diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/verify-config.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/verify-config.cpp index 421f8641281acb2772c657bdf876acb507a7a7ad..3659285986482a998b02f6c593c71564faa7bd3c 100644 --- a/clang-tools-extra/test/clang-tidy/infrastructure/verify-config.cpp +++ b/clang-tools-extra/test/clang-tidy/infrastructure/verify-config.cpp @@ -18,3 +18,15 @@ // CHECK-VERIFY: command-line option '-checks': warning: check glob 'bad*glob' doesn't match any known check [-verify-config] // CHECK-VERIFY: command-line option '-checks': warning: unknown check 'llvm-includeorder'; did you mean 'llvm-include-order' [-verify-config] // CHECK-VERIFY: command-line option '-checks': warning: unknown check 'my-made-up-check' [-verify-config] + +// RUN: echo -e 'Checks: |\n bugprone-argument-comment\n bugprone-assert-side-effect,\n bugprone-bool-pointer-implicit-conversion\n readability-use-anyof*' > %T/MyClangTidyConfig +// RUN: clang-tidy -verify-config \ +// RUN: --config-file=%T/MyClangTidyConfig | FileCheck %s -check-prefix=CHECK-VERIFY-BLOCK-OK +// CHECK-VERIFY-BLOCK-OK: No config errors detected. + +// RUN: echo -e 'Checks: |\n bugprone-arguments-*\n bugprone-assert-side-effects\n bugprone-bool-pointer-implicit-conversion' > %T/MyClangTidyConfigBad +// RUN: not clang-tidy -verify-config \ +// RUN: --config-file=%T/MyClangTidyConfigBad 2>&1 | FileCheck %s -check-prefix=CHECK-VERIFY-BLOCK-BAD +// CHECK-VERIFY-BLOCK-BAD: command-line option '-config': warning: check glob 'bugprone-arguments-*' doesn't match any known check [-verify-config] +// CHECK-VERIFY-BLOCK-BAD: command-line option '-config': warning: unknown check 'bugprone-assert-side-effects'; did you mean 'bugprone-assert-side-effect' [-verify-config] + diff --git a/clang/cmake/caches/Apple-stage2.cmake b/clang/cmake/caches/Apple-stage2.cmake index ede256a2da6b8fd6864bd8584aeddf5126dd5bb9..e919c56739679ebc5e8193e8a1f06e65fc4b1376 100644 --- a/clang/cmake/caches/Apple-stage2.cmake +++ b/clang/cmake/caches/Apple-stage2.cmake @@ -16,6 +16,7 @@ set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "") set(LLVM_ENABLE_MODULES ON CACHE BOOL "") set(LLVM_EXTERNALIZE_DEBUGINFO ON CACHE BOOL "") set(LLVM_ENABLE_EXPORTED_SYMBOLS_IN_EXECUTABLES OFF CACHE BOOL "") +set(LLVM_PLUGIN_SUPPORT OFF CACHE BOOL "") set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "") set(CLANG_SPAWN_CC1 ON CACHE BOOL "") set(BUG_REPORT_URL "http://developer.apple.com/bugreporter/" CACHE STRING "") diff --git a/clang/docs/ClangOffloadBundler.rst b/clang/docs/ClangOffloadBundler.rst index 1f8c85a08f8c79c46b9dc375d9ec167d80a78346..515e6c00a3b8003083508e562812317338314206 100644 --- a/clang/docs/ClangOffloadBundler.rst +++ b/clang/docs/ClangOffloadBundler.rst @@ -518,11 +518,14 @@ The compressed offload bundle begins with a header followed by the compressed bi This is a unique identifier to distinguish compressed offload bundles. The value is the string 'CCOB' (Compressed Clang Offload Bundle). - **Version Number (16-bit unsigned int)**: - This denotes the version of the compressed offload bundle format. The current version is `1`. + This denotes the version of the compressed offload bundle format. The current version is `2`. - **Compression Method (16-bit unsigned int)**: This field indicates the compression method used. The value corresponds to either `zlib` or `zstd`, represented as a 16-bit unsigned integer cast from the LLVM compression enumeration. +- **Total File Size (32-bit unsigned int)**: + This is the total size (in bytes) of the file, including the header. Available in version 2 and above. + - **Uncompressed Binary Size (32-bit unsigned int)**: This is the size (in bytes) of the binary data before it was compressed. diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 3bead159c8f9467dd876174beff98787eb6a890b..84fc4dee02fa803766b66528e53f40057fc8a1df 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -1642,7 +1642,8 @@ The following type trait primitives are supported by Clang. Those traits marked were made trivially relocatable via the ``clang::trivial_abi`` attribute. * ``__is_trivially_equality_comparable`` (Clang): Returns true if comparing two objects of the provided type is known to be equivalent to comparing their - value representations. + object representations. Note that types containing padding bytes are never + trivially equality comparable. * ``__is_unbounded_array`` (C++, GNU, Microsoft, Embarcadero) * ``__is_union`` (C++, GNU, Microsoft, Embarcadero) * ``__is_unsigned`` (C++, Embarcadero): diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 205c6e573d567cef26cc570c25a96452be30881e..2b3bafa1c3054809d1ab3532fcec9d337c44bf07 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -88,6 +88,7 @@ sections with improvements to Clang's support for those languages. C++ Language Changes -------------------- +- Implemented ``_BitInt`` literal suffixes ``__wb`` or ``__WB`` as a Clang extension with ``unsigned`` modifiers also allowed. (#GH85223). C++20 Feature Support ^^^^^^^^^^^^^^^^^^^^^ @@ -179,6 +180,9 @@ C23 Feature Support - Clang now supports `N3018 The constexpr specifier for object definitions` `_. +- Properly promote bit-fields of bit-precise integer types to the field's type + rather than to ``int``. #GH87641 + Non-comprehensive list of changes in this release ------------------------------------------------- @@ -248,6 +252,8 @@ Modified Compiler Flags f3 *c = (f3 *)x; } +- Carved out ``-Wformat`` warning about scoped enums into a subwarning and + make it controlled by ``-Wformat-pedantic``. Fixes #GH88595. Removed Compiler Flags ------------------------- @@ -431,6 +437,10 @@ Bug Fixes in This Version during instantiation, and instead will only diagnose it once, during checking of the function template. +- Clang now allows the value of unroll count to be zero in ``#pragma GCC unroll`` and ``#pragma unroll``. + The values of 0 and 1 block any unrolling of the loop. This keeps the same behavior with GCC. + Fixes (`#88624 `_). + Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -534,6 +544,8 @@ Bug Fixes to C++ Support - Fix an issue caused by not handling invalid cases when substituting into the parameter mapping of a constraint. Fixes (#GH86757). - Fixed a bug that prevented member function templates of class templates declared with a deduced return type from being explicitly specialized for a given implicit instantiation of the class template. +- Fixed a crash when ``this`` is used in a dependent class scope function template specialization + that instantiates to a static member function. - Fix crash when inheriting from a cv-qualified type. Fixes #GH35603 - Fix a crash when the using enum declaration uses an anonymous enumeration. Fixes (#GH86790). @@ -545,6 +557,9 @@ Bug Fixes to C++ Support - Fix a crash in requires expression with templated base class member function. Fixes (#GH84020). - Fix a crash caused by defined struct in a type alias template when the structure has fields with dependent type. Fixes (#GH75221). +- Fix the Itanium mangling of lambdas defined in a member of a local class (#GH88906) +- Fixed a crash when trying to evaluate a user-defined ``static_assert`` message whose ``size()`` + function returns a large or negative value. Fixes (#GH89407). Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -554,6 +569,9 @@ Bug Fixes to AST Handling Miscellaneous Bug Fixes ^^^^^^^^^^^^^^^^^^^^^^^ +- Fixed an infinite recursion in ASTImporter, on return type declared inside + body of C++11 lambda without trailing return (#GH68775). + Miscellaneous Clang Crashes Fixed ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -691,6 +709,8 @@ Static Analyzer - Support C++23 static operator calls. (#GH84972) - Fixed a crash in ``security.cert.env.InvalidPtr`` checker when accidentally matched user-defined ``strerror`` and similar library functions. (GH#88181) +- Fixed a crash when storing through an address that refers to the address of + a label. (GH#89185) New features ^^^^^^^^^^^^ diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h index f5c47d8a7c2113ab5e3303fda5e86dbb27f029d2..216dc9eef08b62c87cde4d19d5af36c2f2680562 100644 --- a/clang/include/clang/AST/ASTNodeTraverser.h +++ b/clang/include/clang/AST/ASTNodeTraverser.h @@ -851,6 +851,12 @@ public: Visit(R); } + void VisitTypeTraitExpr(const TypeTraitExpr *E) { + // Argument types are not children of the TypeTraitExpr. + for (auto *A : E->getArgs()) + Visit(A->getType()); + } + void VisitLambdaExpr(const LambdaExpr *Node) { if (Traversal == TK_IgnoreUnlessSpelledInSource) { for (unsigned I = 0, N = Node->capture_size(); I != N; ++I) { diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 0a9c9e17d3f9f91f8c22608e17de36235afaf2cf..8b121896d66d158d06be1c317d7d1e1698782bc5 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -157,7 +157,7 @@ public: SourceLocation CommentLoc, PragmaMSCommentKind CommentKind, StringRef Arg); - static PragmaCommentDecl *CreateDeserialized(ASTContext &C, unsigned ID, + static PragmaCommentDecl *CreateDeserialized(ASTContext &C, DeclID ID, unsigned ArgSize); PragmaMSCommentKind getCommentKind() const { return CommentKind; } @@ -192,7 +192,7 @@ public: SourceLocation Loc, StringRef Name, StringRef Value); static PragmaDetectMismatchDecl * - CreateDeserialized(ASTContext &C, unsigned ID, unsigned NameValueSize); + CreateDeserialized(ASTContext &C, DeclID ID, unsigned NameValueSize); StringRef getName() const { return getTrailingObjects(); } StringRef getValue() const { return getTrailingObjects() + ValueStart; } @@ -518,7 +518,7 @@ public: static LabelDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II, SourceLocation GnuLabelL); - static LabelDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static LabelDecl *CreateDeserialized(ASTContext &C, DeclID ID); LabelStmt *getStmt() const { return TheStmt; } void setStmt(LabelStmt *T) { TheStmt = T; } @@ -581,7 +581,7 @@ public: IdentifierInfo *Id, NamespaceDecl *PrevDecl, bool Nested); - static NamespaceDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static NamespaceDecl *CreateDeserialized(ASTContext &C, DeclID ID); using redecl_range = redeclarable_base::redecl_range; using redecl_iterator = redeclarable_base::redecl_iterator; @@ -1146,7 +1146,7 @@ public: const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S); - static VarDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static VarDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -1728,7 +1728,7 @@ public: static ImplicitParamDecl *Create(ASTContext &C, QualType T, ImplicitParamKind ParamKind); - static ImplicitParamDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ImplicitParamDecl *CreateDeserialized(ASTContext &C, DeclID ID); ImplicitParamDecl(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, const IdentifierInfo *Id, QualType Type, @@ -1782,7 +1782,7 @@ public: TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg); - static ParmVarDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ParmVarDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -2178,7 +2178,7 @@ public: bool hasWrittenPrototype, ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause); - static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static FunctionDecl *CreateDeserialized(ASTContext &C, DeclID ID); DeclarationNameInfo getNameInfo() const { return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); @@ -3136,7 +3136,7 @@ public: TypeSourceInfo *TInfo, Expr *BW, bool Mutable, InClassInitStyle InitStyle); - static FieldDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static FieldDecl *CreateDeserialized(ASTContext &C, DeclID ID); /// Returns the index of this field within its record, /// as appropriate for passing to ASTRecordLayout::getFieldOffset. @@ -3311,7 +3311,7 @@ public: SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E, const llvm::APSInt &V); - static EnumConstantDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static EnumConstantDecl *CreateDeserialized(ASTContext &C, DeclID ID); const Expr *getInitExpr() const { return (const Expr*) Init; } Expr *getInitExpr() { return (Expr*) Init; } @@ -3357,7 +3357,7 @@ public: QualType T, llvm::MutableArrayRef CH); - static IndirectFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static IndirectFieldDecl *CreateDeserialized(ASTContext &C, DeclID ID); using chain_iterator = ArrayRef::const_iterator; @@ -3542,7 +3542,7 @@ public: static TypedefDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo); - static TypedefDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static TypedefDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3567,7 +3567,7 @@ public: static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo); - static TypeAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static TypeAliasDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3977,7 +3977,7 @@ public: IdentifierInfo *Id, EnumDecl *PrevDecl, bool IsScoped, bool IsScopedUsingClassTag, bool IsFixed); - static EnumDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static EnumDecl *CreateDeserialized(ASTContext &C, DeclID ID); /// Overrides to provide correct range when there's an enum-base specifier /// with forward declarations. @@ -4182,7 +4182,7 @@ public: static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, RecordDecl* PrevDecl = nullptr); - static RecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID); + static RecordDecl *CreateDeserialized(const ASTContext &C, DeclID ID); RecordDecl *getPreviousDecl() { return cast_or_null( @@ -4433,7 +4433,7 @@ public: StringLiteral *Str, SourceLocation AsmLoc, SourceLocation RParenLoc); - static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceLocation getAsmLoc() const { return getLocation(); } SourceLocation getRParenLoc() const { return RParenLoc; } @@ -4469,7 +4469,7 @@ class TopLevelStmtDecl : public Decl, public DeclContext { public: static TopLevelStmtDecl *Create(ASTContext &C, Stmt *Statement); - static TopLevelStmtDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static TopLevelStmtDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; Stmt *getStmt() { return Statement; } @@ -4563,7 +4563,7 @@ protected: public: static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); - static BlockDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static BlockDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceLocation getCaretLocation() const { return getLocation(); } @@ -4717,7 +4717,7 @@ public: static CapturedDecl *Create(ASTContext &C, DeclContext *DC, unsigned NumParams); - static CapturedDecl *CreateDeserialized(ASTContext &C, unsigned ID, + static CapturedDecl *CreateDeserialized(ASTContext &C, DeclID ID, unsigned NumParams); Stmt *getBody() const override; @@ -4851,7 +4851,7 @@ public: SourceLocation EndLoc); /// Create a new, deserialized module import declaration. - static ImportDecl *CreateDeserialized(ASTContext &C, unsigned ID, + static ImportDecl *CreateDeserialized(ASTContext &C, DeclID ID, unsigned NumLocations); /// Retrieve the module that was imported by the import declaration. @@ -4892,7 +4892,7 @@ private: public: static ExportDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation ExportLoc); - static ExportDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ExportDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceLocation getExportLoc() const { return getLocation(); } SourceLocation getRBraceLoc() const { return RBraceLoc; } @@ -4931,7 +4931,7 @@ class EmptyDecl : public Decl { public: static EmptyDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); - static EmptyDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static EmptyDecl *CreateDeserialized(ASTContext &C, DeclID ID); static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Empty; } @@ -4957,7 +4957,7 @@ public: bool CBuffer, SourceLocation KwLoc, IdentifierInfo *ID, SourceLocation IDLoc, SourceLocation LBrace); - static HLSLBufferDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static HLSLBufferDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(getLocStart(), RBraceLoc); diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 1079993f4969456f87d9ba2e2e80fff8b0efa016..161e14fc896922fbacbd018df904a70b8c0b793b 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -349,6 +349,8 @@ protected: LLVM_PREFERRED_TYPE(Linkage) mutable unsigned CacheValidAndLinkage : 3; + using DeclID = uint32_t; + /// Allocate memory for a deserialized declaration. /// /// This routine must be used to allocate memory for any declaration that is @@ -358,7 +360,7 @@ protected: /// \param Ctx The context in which we will allocate memory. /// \param ID The global ID of the deserialized declaration. /// \param Extra The amount of extra space to allocate after the object. - void *operator new(std::size_t Size, const ASTContext &Ctx, unsigned ID, + void *operator new(std::size_t Size, const ASTContext &Ctx, DeclID ID, std::size_t Extra = 0); /// Allocate memory for a non-deserialized declaration. diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 7aed4d5cbc002e2c60d743922f16d507bfb2a2dd..a7644d2a19d2459c0a746a62cb1fc06f5fa5c2d5 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -120,7 +120,7 @@ public: return new (C, DC) AccessSpecDecl(AS, DC, ASLoc, ColonLoc); } - static AccessSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static AccessSpecDecl *CreateDeserialized(ASTContext &C, DeclID ID); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -579,7 +579,7 @@ public: TypeSourceInfo *Info, SourceLocation Loc, unsigned DependencyKind, bool IsGeneric, LambdaCaptureDefault CaptureDefault); - static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID); + static CXXRecordDecl *CreateDeserialized(const ASTContext &C, DeclID ID); bool isDynamicClass() const { return data().Polymorphic || data().NumVBases != 0; @@ -1980,7 +1980,7 @@ public: CXXConstructorDecl *Ctor = nullptr, DeductionCandidate Kind = DeductionCandidate::Normal); - static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, DeclID ID); ExplicitSpecifier getExplicitSpecifier() { return ExplicitSpec; } const ExplicitSpecifier getExplicitSpecifier() const { return ExplicitSpec; } @@ -2035,7 +2035,7 @@ public: static RequiresExprBodyDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc); - static RequiresExprBodyDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static RequiresExprBodyDecl *CreateDeserialized(ASTContext &C, DeclID ID); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2078,7 +2078,7 @@ public: ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, Expr *TrailingRequiresClause = nullptr); - static CXXMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static CXXMethodDecl *CreateDeserialized(ASTContext &C, DeclID ID); bool isStatic() const; bool isInstance() const { return !isStatic(); } @@ -2579,7 +2579,7 @@ public: friend class ASTDeclWriter; friend TrailingObjects; - static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned ID, + static CXXConstructorDecl *CreateDeserialized(ASTContext &C, DeclID ID, uint64_t AllocKind); static CXXConstructorDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, @@ -2822,7 +2822,7 @@ public: bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause = nullptr); - static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID); + static CXXDestructorDecl *CreateDeserialized(ASTContext & C, DeclID ID); void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg); @@ -2881,7 +2881,7 @@ public: bool UsesFPIntrin, bool isInline, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, Expr *TrailingRequiresClause = nullptr); - static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static CXXConversionDecl *CreateDeserialized(ASTContext &C, DeclID ID); ExplicitSpecifier getExplicitSpecifier() { return getCanonicalDecl()->ExplicitSpec; @@ -2948,7 +2948,7 @@ public: SourceLocation ExternLoc, SourceLocation LangLoc, LinkageSpecLanguageIDs Lang, bool HasBraces); - static LinkageSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static LinkageSpecDecl *CreateDeserialized(ASTContext &C, DeclID ID); /// Return the language specified by this linkage specification. LinkageSpecLanguageIDs getLanguage() const { @@ -3096,7 +3096,7 @@ public: SourceLocation IdentLoc, NamedDecl *Nominated, DeclContext *CommonAncestor); - static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(UsingLoc, getLocation()); @@ -3157,7 +3157,7 @@ public: SourceLocation IdentLoc, NamedDecl *Namespace); - static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, DeclID ID); using redecl_range = redeclarable_base::redecl_range; using redecl_iterator = redeclarable_base::redecl_iterator; @@ -3254,7 +3254,7 @@ public: LifetimeExtendedTemporaryDecl(Temp, EDec, Mangling); } static LifetimeExtendedTemporaryDecl *CreateDeserialized(ASTContext &C, - unsigned ID) { + DeclID ID) { return new (C, ID) LifetimeExtendedTemporaryDecl(EmptyShell{}); } @@ -3357,7 +3357,7 @@ public: UsingShadowDecl(UsingShadow, C, DC, Loc, Name, Introducer, Target); } - static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static UsingShadowDecl *CreateDeserialized(ASTContext &C, DeclID ID); using redecl_range = redeclarable_base::redecl_range; using redecl_iterator = redeclarable_base::redecl_iterator; @@ -3566,7 +3566,7 @@ public: const DeclarationNameInfo &NameInfo, bool HasTypenameKeyword); - static UsingDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static UsingDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3645,7 +3645,7 @@ public: UsingDecl *Using, NamedDecl *Target, bool IsVirtual); static ConstructorUsingShadowDecl *CreateDeserialized(ASTContext &C, - unsigned ID); + DeclID ID); /// Override the UsingShadowDecl's getIntroducer, returning the UsingDecl that /// introduced this. @@ -3757,7 +3757,7 @@ public: SourceLocation UsingL, SourceLocation EnumL, SourceLocation NameL, TypeSourceInfo *EnumType); - static UsingEnumDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static UsingEnumDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3830,7 +3830,7 @@ public: NamedDecl *InstantiatedFrom, ArrayRef UsingDecls); - static UsingPackDecl *CreateDeserialized(ASTContext &C, unsigned ID, + static UsingPackDecl *CreateDeserialized(ASTContext &C, DeclID ID, unsigned NumExpansions); SourceRange getSourceRange() const override LLVM_READONLY { @@ -3924,7 +3924,7 @@ public: const DeclarationNameInfo &NameInfo, SourceLocation EllipsisLoc); static UnresolvedUsingValueDecl * - CreateDeserialized(ASTContext &C, unsigned ID); + CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -4015,7 +4015,7 @@ public: SourceLocation EllipsisLoc); static UnresolvedUsingTypenameDecl * - CreateDeserialized(ASTContext &C, unsigned ID); + CreateDeserialized(ASTContext &C, DeclID ID); /// Retrieves the canonical declaration of this declaration. UnresolvedUsingTypenameDecl *getCanonicalDecl() override { @@ -4045,7 +4045,7 @@ public: SourceLocation Loc, DeclarationName Name); static UnresolvedUsingIfExistsDecl *CreateDeserialized(ASTContext &Ctx, - unsigned ID); + DeclID ID); static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingIfExists; } @@ -4073,7 +4073,7 @@ public: SourceLocation StaticAssertLoc, Expr *AssertExpr, Expr *Message, SourceLocation RParenLoc, bool Failed); - static StaticAssertDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static StaticAssertDecl *CreateDeserialized(ASTContext &C, DeclID ID); Expr *getAssertExpr() { return AssertExprAndFailed.getPointer(); } const Expr *getAssertExpr() const { return AssertExprAndFailed.getPointer(); } @@ -4120,7 +4120,7 @@ public: static BindingDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id); - static BindingDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static BindingDecl *CreateDeserialized(ASTContext &C, DeclID ID); /// Get the expression to which this declaration is bound. This may be null /// in two different cases: while parsing the initializer for the @@ -4189,7 +4189,7 @@ public: QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef Bindings); - static DecompositionDecl *CreateDeserialized(ASTContext &C, unsigned ID, + static DecompositionDecl *CreateDeserialized(ASTContext &C, DeclID ID, unsigned NumBindings); ArrayRef bindings() const { @@ -4246,7 +4246,7 @@ public: SourceLocation L, DeclarationName N, QualType T, TypeSourceInfo *TInfo, SourceLocation StartL, IdentifierInfo *Getter, IdentifierInfo *Setter); - static MSPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static MSPropertyDecl *CreateDeserialized(ASTContext &C, DeclID ID); static bool classof(const Decl *D) { return D->getKind() == MSProperty; } @@ -4300,7 +4300,7 @@ private: MSGuidDecl(DeclContext *DC, QualType T, Parts P); static MSGuidDecl *Create(const ASTContext &C, QualType T, Parts P); - static MSGuidDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static MSGuidDecl *CreateDeserialized(ASTContext &C, DeclID ID); // Only ASTContext::getMSGuidDecl and deserialization create these. friend class ASTContext; @@ -4353,7 +4353,7 @@ class UnnamedGlobalConstantDecl : public ValueDecl, static UnnamedGlobalConstantDecl *Create(const ASTContext &C, QualType T, const APValue &APVal); static UnnamedGlobalConstantDecl *CreateDeserialized(ASTContext &C, - unsigned ID); + DeclID ID); // Only ASTContext::getUnnamedGlobalConstantDecl and deserialization create // these. diff --git a/clang/include/clang/AST/DeclFriend.h b/clang/include/clang/AST/DeclFriend.h index 3e6ca5b3219259e1eafb908afc08208ec5bfc251..b56627a5337d63a80af5b4ad2856aad5c1be2998 100644 --- a/clang/include/clang/AST/DeclFriend.h +++ b/clang/include/clang/AST/DeclFriend.h @@ -112,7 +112,7 @@ public: Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_, SourceLocation FriendL, ArrayRef FriendTypeTPLists = std::nullopt); - static FriendDecl *CreateDeserialized(ASTContext &C, unsigned ID, + static FriendDecl *CreateDeserialized(ASTContext &C, DeclID ID, unsigned FriendTypeNumTPLists); /// If this friend declaration names an (untemplated but possibly diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index b8d17dd06d1550082446496c9d02ef5fa9c759a5..7780afa6f1cf5c11b286b39613cc18c21293630b 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -236,7 +236,7 @@ public: ObjCImplementationControl impControl = ObjCImplementationControl::None, bool HasRelatedResultType = false); - static ObjCMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ObjCMethodDecl *CreateDeserialized(ASTContext &C, DeclID ID); ObjCMethodDecl *getCanonicalDecl() override; const ObjCMethodDecl *getCanonicalDecl() const { @@ -614,7 +614,7 @@ public: IdentifierInfo *name, SourceLocation colonLoc, TypeSourceInfo *boundInfo); - static ObjCTypeParamDecl *CreateDeserialized(ASTContext &ctx, unsigned ID); + static ObjCTypeParamDecl *CreateDeserialized(ASTContext &ctx, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -789,7 +789,7 @@ public: TypeSourceInfo *TSI, PropertyControl propControl = None); - static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceLocation getAtLoc() const { return AtLoc; } void setAtLoc(SourceLocation L) { AtLoc = L; } @@ -1279,7 +1279,7 @@ public: ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc = SourceLocation(), bool isInternal = false); - static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, unsigned ID); + static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, DeclID ID); /// Retrieve the type parameters of this class. /// @@ -1969,7 +1969,7 @@ public: TypeSourceInfo *TInfo, AccessControl ac, Expr *BW = nullptr, bool synthesized = false); - static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ObjCIvarDecl *CreateDeserialized(ASTContext &C, DeclID ID); /// Return the class interface that this ivar is logically contained /// in; this is either the interface where the ivar was declared, or the @@ -2039,7 +2039,7 @@ public: SourceLocation IdLoc, IdentifierInfo *Id, QualType T, Expr *BW); - static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, DeclID ID); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2142,7 +2142,7 @@ public: SourceLocation atStartLoc, ObjCProtocolDecl *PrevDecl); - static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, DeclID ID); const ObjCProtocolList &getReferencedProtocols() const { assert(hasDefinition() && "No definition available!"); @@ -2361,7 +2361,7 @@ public: ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc = SourceLocation(), SourceLocation IvarRBraceLoc = SourceLocation()); - static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, DeclID ID); ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } @@ -2558,7 +2558,7 @@ public: Create(ASTContext &C, DeclContext *DC, const IdentifierInfo *Id, ObjCInterfaceDecl *classInterface, SourceLocation nameLoc, SourceLocation atStartLoc, SourceLocation CategoryNameLoc); - static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, DeclID ID); ObjCCategoryDecl *getCategoryDecl() const; @@ -2640,7 +2640,7 @@ public: SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation()); - static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, DeclID ID); /// init_iterator - Iterates through the ivar initializer list. using init_iterator = CXXCtorInitializer **; @@ -2780,7 +2780,7 @@ public: ObjCInterfaceDecl* aliasedClass); static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C, - unsigned ID); + DeclID ID); const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; } ObjCInterfaceDecl *getClassInterface() { return AliasedClass; } @@ -2851,7 +2851,7 @@ public: ObjCIvarDecl *ivarDecl, SourceLocation ivarLoc); - static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; diff --git a/clang/include/clang/AST/DeclOpenMP.h b/clang/include/clang/AST/DeclOpenMP.h index 8fdfddb6c1fd74bf2ddc3b852b0e28679b286926..c7ede7f2157fef7676cb6bf068761c49602479d9 100644 --- a/clang/include/clang/AST/DeclOpenMP.h +++ b/clang/include/clang/AST/DeclOpenMP.h @@ -133,7 +133,7 @@ public: SourceLocation L, ArrayRef VL); static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C, - unsigned ID, unsigned N); + DeclID ID, unsigned N); typedef MutableArrayRef::iterator varlist_iterator; typedef ArrayRef::iterator varlist_const_iterator; @@ -214,7 +214,7 @@ public: QualType T, OMPDeclareReductionDecl *PrevDeclInScope); /// Create deserialized declare reduction node. static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C, - unsigned ID); + DeclID ID); /// Get combiner expression of the declare reduction construct. Expr *getCombiner() { return Combiner; } @@ -318,7 +318,7 @@ public: ArrayRef Clauses, OMPDeclareMapperDecl *PrevDeclInScope); /// Creates deserialized declare mapper node. - static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, unsigned ID, + static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, DeclID ID, unsigned N); using clauselist_iterator = MutableArrayRef::iterator; @@ -397,7 +397,7 @@ public: IdentifierInfo *Id, QualType T, SourceLocation StartLoc); - static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -427,7 +427,7 @@ public: static OMPRequiresDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef CL); /// Create deserialized requires node. - static OMPRequiresDecl *CreateDeserialized(ASTContext &C, unsigned ID, + static OMPRequiresDecl *CreateDeserialized(ASTContext &C, DeclID ID, unsigned N); using clauselist_iterator = MutableArrayRef::iterator; @@ -495,7 +495,7 @@ public: static OMPAllocateDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef VL, ArrayRef CL); - static OMPAllocateDecl *CreateDeserialized(ASTContext &C, unsigned ID, + static OMPAllocateDecl *CreateDeserialized(ASTContext &C, DeclID ID, unsigned NVars, unsigned NClauses); typedef MutableArrayRef::iterator varlist_iterator; diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index f24e71ff229648d80336e76faef5abbe850a0fe9..e2afff8d445016d5dc656fb016c789b56e39add2 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -1087,7 +1087,7 @@ public: NamedDecl *Decl); /// Create an empty function template node. - static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -1204,9 +1204,9 @@ public: bool Typename, bool ParameterPack, bool HasTypeConstraint = false, std::optional NumExpanded = std::nullopt); static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, - unsigned ID); + DeclID ID); static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, - unsigned ID, + DeclID ID, bool HasTypeConstraint); /// Whether this template type parameter was declared with @@ -1414,10 +1414,10 @@ public: ArrayRef ExpandedTInfos); static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, - unsigned ID, + DeclID ID, bool HasTypeConstraint); static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, - unsigned ID, + DeclID ID, unsigned NumExpandedTypes, bool HasTypeConstraint); @@ -1632,9 +1632,9 @@ public: ArrayRef Expansions); static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, - unsigned ID); + DeclID ID); static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, - unsigned ID, + DeclID ID, unsigned NumExpansions); using TemplateParmPosition::getDepth; @@ -1858,7 +1858,7 @@ public: ArrayRef Args, ClassTemplateSpecializationDecl *PrevDecl); static ClassTemplateSpecializationDecl * - CreateDeserialized(ASTContext &C, unsigned ID); + CreateDeserialized(ASTContext &C, DeclID ID); void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override; @@ -2110,7 +2110,7 @@ public: ClassTemplatePartialSpecializationDecl *PrevDecl); static ClassTemplatePartialSpecializationDecl * - CreateDeserialized(ASTContext &C, unsigned ID); + CreateDeserialized(ASTContext &C, DeclID ID); ClassTemplatePartialSpecializationDecl *getMostRecentDecl() { return cast( @@ -2306,7 +2306,7 @@ public: NamedDecl *Decl); /// Create an empty class template node. - static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ClassTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); /// Return the specialization with the provided arguments if it exists, /// otherwise return the insertion point. @@ -2472,7 +2472,7 @@ public: MutableArrayRef Params, FriendUnion Friend, SourceLocation FriendLoc); - static FriendTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static FriendTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); /// If this friend declaration names a templated type (or /// a dependent member type of a templated type), return that @@ -2573,7 +2573,7 @@ public: NamedDecl *Decl); /// Create an empty alias template node. - static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2670,7 +2670,7 @@ public: TypeSourceInfo *TInfo, StorageClass S, ArrayRef Args); static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C, - unsigned ID); + DeclID ID); void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override; @@ -2901,7 +2901,7 @@ public: const TemplateArgumentListInfo &ArgInfos); static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C, - unsigned ID); + DeclID ID); VarTemplatePartialSpecializationDecl *getMostRecentDecl() { return cast( @@ -3078,7 +3078,7 @@ public: VarDecl *Decl); /// Create an empty variable template node. - static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static VarTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); /// Return the specialization with the provided arguments if it exists, /// otherwise return the insertion point. @@ -3183,7 +3183,7 @@ public: SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr); - static ConceptDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ConceptDecl *CreateDeserialized(ASTContext &C, DeclID ID); Expr *getConstraintExpr() const { return ConstraintExpr; @@ -3232,7 +3232,7 @@ public: Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef ConvertedArgs); static ImplicitConceptSpecializationDecl * - CreateDeserialized(const ASTContext &C, unsigned ID, + CreateDeserialized(const ASTContext &C, DeclID ID, unsigned NumTemplateArgs); ArrayRef getTemplateArguments() const { @@ -3275,7 +3275,7 @@ private: static TemplateParamObjectDecl *Create(const ASTContext &C, QualType T, const APValue &V); static TemplateParamObjectDecl *CreateDeserialized(ASTContext &C, - unsigned ID); + DeclID ID); /// Only ASTContext::getTemplateParamObjectDecl and deserialization /// create these. diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index d28e5c3a78ee4bbb9c76ddb2d229a9d99372ab19..a915745d2d7322c7bf34321d0f69b6b40fb6c4ce 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -3198,7 +3198,6 @@ class UnresolvedLookupExpr final NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, - bool Overloaded, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool KnownDependent); @@ -3218,8 +3217,9 @@ public: static UnresolvedLookupExpr * Create(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, - const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, - UnresolvedSetIterator Begin, UnresolvedSetIterator End); + const DeclarationNameInfo &NameInfo, bool RequiresADL, + UnresolvedSetIterator Begin, UnresolvedSetIterator End, + bool KnownDependent); // After canonicalization, there may be dependent template arguments in // CanonicalConverted But none of Args is dependent. When any of @@ -3240,9 +3240,6 @@ public: /// argument-dependent lookup. bool requiresADL() const { return UnresolvedLookupExprBits.RequiresADL; } - /// True if this lookup is overloaded. - bool isOverloaded() const { return UnresolvedLookupExprBits.Overloaded; } - /// Gets the 'naming class' (in the sense of C++0x /// [class.access.base]p5) of the lookup. This is the scope /// that was looked in to find these results. diff --git a/clang/include/clang/AST/OpenACCClause.h b/clang/include/clang/AST/OpenACCClause.h index 8b6d3221aa066bcc73b9a2781d614c26707e2f54..277a351c49fcb89335c19845262643986a9de157 100644 --- a/clang/include/clang/AST/OpenACCClause.h +++ b/clang/include/clang/AST/OpenACCClause.h @@ -156,33 +156,88 @@ public: Expr *ConditionExpr, SourceLocation EndLoc); }; -/// Represents oen of a handful of classes that have a single integer +/// Represents a clause that has one or more IntExprs. It does not own the +/// IntExprs, but provides 'children' and other accessors. +class OpenACCClauseWithIntExprs : public OpenACCClauseWithParams { + MutableArrayRef IntExprs; + +protected: + OpenACCClauseWithIntExprs(OpenACCClauseKind K, SourceLocation BeginLoc, + SourceLocation LParenLoc, SourceLocation EndLoc) + : OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc) {} + + /// Used only for initialization, the leaf class can initialize this to + /// trailing storage. + void setIntExprs(MutableArrayRef NewIntExprs) { + assert(IntExprs.empty() && "Cannot change IntExprs list"); + IntExprs = NewIntExprs; + } + + /// Gets the entire list of integer expressions, but leave it to the + /// individual clauses to expose this how they'd like. + llvm::ArrayRef getIntExprs() const { return IntExprs; } + +public: + child_range children() { + return child_range(reinterpret_cast(IntExprs.begin()), + reinterpret_cast(IntExprs.end())); + } + + const_child_range children() const { + child_range Children = + const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } +}; + +class OpenACCNumGangsClause final + : public OpenACCClauseWithIntExprs, + public llvm::TrailingObjects { + + OpenACCNumGangsClause(SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef IntExprs, SourceLocation EndLoc) + : OpenACCClauseWithIntExprs(OpenACCClauseKind::NumGangs, BeginLoc, + LParenLoc, EndLoc) { + std::uninitialized_copy(IntExprs.begin(), IntExprs.end(), + getTrailingObjects()); + setIntExprs(MutableArrayRef(getTrailingObjects(), IntExprs.size())); + } + +public: + static OpenACCNumGangsClause * + Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef IntExprs, SourceLocation EndLoc); + + llvm::ArrayRef getIntExprs() { + return OpenACCClauseWithIntExprs::getIntExprs(); + } + + llvm::ArrayRef getIntExprs() const { + return OpenACCClauseWithIntExprs::getIntExprs(); + } +}; + +/// Represents one of a handful of clauses that have a single integer /// expression. -class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithParams { +class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithIntExprs { Expr *IntExpr; protected: OpenACCClauseWithSingleIntExpr(OpenACCClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc) - : OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc), - IntExpr(IntExpr) {} + : OpenACCClauseWithIntExprs(K, BeginLoc, LParenLoc, EndLoc), + IntExpr(IntExpr) { + setIntExprs(MutableArrayRef{&this->IntExpr, 1}); + } public: - bool hasIntExpr() const { return IntExpr; } - const Expr *getIntExpr() const { return IntExpr; } - - Expr *getIntExpr() { return IntExpr; }; - - child_range children() { - return child_range(reinterpret_cast(&IntExpr), - reinterpret_cast(&IntExpr + 1)); + bool hasIntExpr() const { return !getIntExprs().empty(); } + const Expr *getIntExpr() const { + return hasIntExpr() ? getIntExprs()[0] : nullptr; } - const_child_range children() const { - return const_child_range(reinterpret_cast(&IntExpr), - reinterpret_cast(&IntExpr + 1)); - } + Expr *getIntExpr() { return hasIntExpr() ? getIntExprs()[0] : nullptr; }; }; class OpenACCNumWorkersClause : public OpenACCClauseWithSingleIntExpr { diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 1b9c9231047717bd32f2c19d77f18264eed512bf..9cd7a364cd3f1dcd8f8c2dfddfec2017d402e57d 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -1067,11 +1067,6 @@ protected: /// argument-dependent lookup if this is the operand of a function call. LLVM_PREFERRED_TYPE(bool) unsigned RequiresADL : 1; - - /// True if these lookup results are overloaded. This is pretty trivially - /// rederivable if we urgently need to kill this field. - LLVM_PREFERRED_TYPE(bool) - unsigned Overloaded : 1; }; static_assert(sizeof(UnresolvedLookupExprBitfields) <= 4, "UnresolvedLookupExprBitfields must be <= than 4 bytes to" diff --git a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h index 27ad32c1694f776de99691c204abea4bc6a1b0a3..05748f300a932f6e6c66c8821dba70d055664dc4 100644 --- a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h +++ b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h @@ -56,6 +56,7 @@ class RecordInitListHelper { public: // `InitList` must have record type. RecordInitListHelper(const InitListExpr *InitList); + RecordInitListHelper(const CXXParenListInitExpr *ParenInitList); // Base classes with their associated initializer expressions. ArrayRef> base_inits() const { @@ -68,6 +69,9 @@ public: } private: + RecordInitListHelper(QualType Ty, std::vector Fields, + ArrayRef Inits); + SmallVector> BaseInits; SmallVector> FieldInits; @@ -92,6 +96,9 @@ struct ReferencedDecls { /// Returns declarations that are declared in or referenced from `FD`. ReferencedDecls getReferencedDecls(const FunctionDecl &FD); +/// Returns declarations that are declared in or referenced from `S`. +ReferencedDecls getReferencedDecls(const Stmt &S); + } // namespace dataflow } // namespace clang diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h index 4277792219c0af2fbbb4563a8cf83fedb396fd54..d50dba35f8264c924d2c21ec3ac69485881fdb3a 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h @@ -84,7 +84,7 @@ public: virtual ComparisonResult compare(QualType Type, const Value &Val1, const Environment &Env1, const Value &Val2, const Environment &Env2) { - // FIXME: Consider adding QualType to RecordValue and removing the Type + // FIXME: Consider adding `QualType` to `Value` and removing the `Type` // argument here. return ComparisonResult::Unknown; } @@ -407,20 +407,15 @@ public: /// storage locations and values for indirections until it finds a /// non-pointer/non-reference type. /// - /// If `Type` is a class, struct, or union type, creates values for all - /// modeled fields (including synthetic fields) and calls `setValue()` to - /// associate the `RecordValue` with its storage location - /// (`RecordValue::getLoc()`). - /// /// If `Type` is one of the following types, this function will always return /// a non-null pointer: /// - `bool` /// - Any integer type - /// - Any class, struct, or union type /// /// Requirements: /// - /// `Type` must not be null. + /// - `Type` must not be null. + /// - `Type` must not be a reference type or record type. Value *createValue(QualType Type); /// Creates an object (i.e. a storage location with an associated value) of @@ -452,6 +447,7 @@ public: /// Initializes the fields (including synthetic fields) of `Loc` with values, /// unless values of the field type are not supported or we hit one of the /// limits at which we stop producing values. + /// If a field already has a value, that value is preserved. /// If `Type` is provided, initializes only those fields that are modeled for /// `Type`; this is intended for use in cases where `Loc` is a derived type /// and we only want to initialize the fields of a base type. @@ -461,6 +457,10 @@ public: } /// Assigns `Val` as the value of `Loc` in the environment. + /// + /// Requirements: + /// + /// `Loc` must not be a `RecordStorageLocation`. void setValue(const StorageLocation &Loc, Value &Val); /// Clears any association between `Loc` and a value in the environment. @@ -470,20 +470,24 @@ public: /// /// Requirements: /// - /// - `E` must be a prvalue - /// - If `Val` is a `RecordValue`, its `RecordStorageLocation` must be - /// `getResultObjectLocation(E)`. An exception to this is if `E` is an - /// expression that originally creates a `RecordValue` (such as a - /// `CXXConstructExpr` or `CallExpr`), as these establish the location of - /// the result object in the first place. + /// - `E` must be a prvalue. + /// - `E` must not have record type. void setValue(const Expr &E, Value &Val); /// Returns the value assigned to `Loc` in the environment or null if `Loc` /// isn't assigned a value in the environment. + /// + /// Requirements: + /// + /// `Loc` must not be a `RecordStorageLocation`. Value *getValue(const StorageLocation &Loc) const; /// Equivalent to `getValue(getStorageLocation(D))` if `D` is assigned a /// storage location in the environment, otherwise returns null. + /// + /// Requirements: + /// + /// `D` must not have record type. Value *getValue(const ValueDecl &D) const; /// Equivalent to `getValue(getStorageLocation(E, SP))` if `E` is assigned a @@ -775,12 +779,6 @@ RecordStorageLocation *getImplicitObjectLocation(const CXXMemberCallExpr &MCE, RecordStorageLocation *getBaseObjectLocation(const MemberExpr &ME, const Environment &Env); -/// Associates a new `RecordValue` with `Loc` and returns the new value. -RecordValue &refreshRecordValue(RecordStorageLocation &Loc, Environment &Env); - -/// Associates a new `RecordValue` with `Expr` and returns the new value. -RecordValue &refreshRecordValue(const Expr &Expr, Environment &Env); - } // namespace dataflow } // namespace clang diff --git a/clang/include/clang/Analysis/FlowSensitive/Value.h b/clang/include/clang/Analysis/FlowSensitive/Value.h index be1bf9324c87b40583b693ff6044d0f8d2211df6..97efa3a93ce6d9d9c58d435bd65aba255ebbc477 100644 --- a/clang/include/clang/Analysis/FlowSensitive/Value.h +++ b/clang/include/clang/Analysis/FlowSensitive/Value.h @@ -35,7 +35,6 @@ public: enum class Kind { Integer, Pointer, - Record, // TODO: Top values should not be need to be type-specific. TopBool, @@ -67,7 +66,6 @@ public: /// Properties may not be set on `RecordValue`s; use synthetic fields instead /// (for details, see documentation for `RecordStorageLocation`). void setProperty(llvm::StringRef Name, Value &Val) { - assert(getKind() != Kind::Record); Properties.insert_or_assign(Name, &Val); } @@ -184,45 +182,6 @@ private: StorageLocation &PointeeLoc; }; -/// Models a value of `struct` or `class` type. -/// In C++, prvalues of class type serve only a limited purpose: They can only -/// be used to initialize a result object. It is not possible to access member -/// variables or call member functions on a prvalue of class type. -/// Correspondingly, `RecordValue` also serves only a limited purpose: It -/// conveys a prvalue of class type from the place where the object is -/// constructed to the result object that it initializes. -/// -/// When creating a prvalue of class type, we already need a storage location -/// for `this`, even though prvalues are otherwise not associated with storage -/// locations. `RecordValue` is therefore essentially a wrapper for a storage -/// location, which is then used to set the storage location for the result -/// object when we process the AST node for that result object. -/// -/// For example: -/// MyStruct S = MyStruct(3); -/// -/// In this example, `MyStruct(3) is a prvalue, which is modeled as a -/// `RecordValue` that wraps a `RecordStorageLocation`. This -/// `RecordStorageLocation` is then used as the storage location for `S`. -/// -/// Over time, we may eliminate `RecordValue` entirely. See also the discussion -/// here: https://reviews.llvm.org/D155204#inline-1503204 -class RecordValue final : public Value { -public: - explicit RecordValue(RecordStorageLocation &Loc) - : Value(Kind::Record), Loc(Loc) {} - - static bool classof(const Value *Val) { - return Val->getKind() == Kind::Record; - } - - /// Returns the storage location that this `RecordValue` is associated with. - RecordStorageLocation &getLoc() const { return Loc; } - -private: - RecordStorageLocation &Loc; -}; - raw_ostream &operator<<(raw_ostream &OS, const Value &Val); } // namespace dataflow diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index a52bf62e24202caf2746cc7c56332032c84eb214..0738f43ca555c8ecccbbf47bde2dba11afed4062 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -234,6 +234,9 @@ def err_cxx23_size_t_suffix: Error< def err_size_t_literal_too_large: Error< "%select{signed |}0'size_t' literal is out of range of possible " "%select{signed |}0'size_t' values">; +def ext_cxx_bitint_suffix : Extension< + "'_BitInt' suffix for literals is a Clang extension">, + InGroup; def ext_c23_bitint_suffix : ExtWarn< "'_BitInt' suffix for literals is a C23 extension">, InGroup; diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 5251774ff4efd6d7f607431511991ca633d22252..60f87da2a7387c25fff72fefb54d5852e627e299 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -1412,6 +1412,9 @@ def MultiGPU: DiagGroup<"multi-gpu">; // libc and the CRT to be skipped. def AVRRtlibLinkingQuirks : DiagGroup<"avr-rtlib-linking-quirks">; +// A warning group related to AArch64 SME function attribues. +def AArch64SMEAttributes : DiagGroup<"aarch64-sme-attributes">; + // A warning group for things that will change semantics in the future. def FutureCompat : DiagGroup<"future-compat">; @@ -1517,5 +1520,8 @@ def UnsafeBufferUsage : DiagGroup<"unsafe-buffer-usage", [UnsafeBufferUsageInCon // Warnings and notes InstallAPI verification. def InstallAPIViolation : DiagGroup<"installapi-violation">; +// Warnings related to _BitInt extension +def BitIntExtension : DiagGroup<"bit-int-extension">; + // Warnings about misuse of ExtractAPI options. def ExtractAPIMisuse : DiagGroup<"extractapi-misuse">; diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 66405095d51de84ce145cb4bbb86dbca3cb16b5a..38174cf3549f14ecad83883acff62b47f15b92c0 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1654,7 +1654,7 @@ def warn_ext_int_deprecated : Warning< "'_ExtInt' is deprecated; use '_BitInt' instead">, InGroup; def ext_bit_int : Extension< "'_BitInt' in %select{C17 and earlier|C++}0 is a Clang extension">, - InGroup>; + InGroup; } // end of Parse Issue category. let CategoryName = "Modules Issue" in { diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 1a2d8bf4e4eb1513aee713118201b4257c4bd6b6..63e951daec7477679802ad24842eb33f2652c4f4 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -87,9 +87,9 @@ def err_expr_not_cce : Error< "call to 'size()'|call to 'data()'}0 is not a constant expression">; def ext_cce_narrowing : ExtWarn< "%select{case value|enumerator value|non-type template argument|" - "array size|explicit specifier argument|noexcept specifier argument}0 " - "%select{cannot be narrowed from type %2 to %3|" - "evaluates to %2, which cannot be narrowed to type %3}1">, + "array size|explicit specifier argument|noexcept specifier argument|" + "call to 'size()'|call to 'data()'}0 %select{cannot be narrowed from " + "type %2 to %3|evaluates to %2, which cannot be narrowed to type %3}1">, InGroup, DefaultError, SFINAEFailure; def err_ice_not_integral : Error< "%select{integer|integral}1 constant expression must have " @@ -3754,6 +3754,16 @@ def err_sme_definition_using_za_in_non_sme_target : Error< "function using ZA state requires 'sme'">; def err_sme_definition_using_zt0_in_non_sme2_target : Error< "function using ZT0 state requires 'sme2'">; +def warn_sme_streaming_pass_return_vl_to_non_streaming : Warning< + "passing a VL-dependent argument to/from a function that has a different" + " streaming-mode. The streaming and non-streaming vector lengths may be" + " different">, + InGroup, DefaultIgnore; +def warn_sme_locally_streaming_has_vl_args_returns : Warning< + "passing/returning a VL-dependent argument to/from a __arm_locally_streaming" + " function. The streaming and non-streaming vector" + " lengths may be different">, + InGroup, DefaultIgnore; def err_conflicting_attributes_arm_state : Error< "conflicting attributes for state '%0'">; def err_sme_streaming_cannot_be_multiversioned : Error< @@ -12283,4 +12293,9 @@ def note_acc_int_expr_conversion : Note<"conversion to %select{integral|enumeration}0 type %1">; def err_acc_int_expr_multiple_conversions : Error<"multiple conversions from expression type %0 to an integral type">; +def err_acc_num_gangs_num_args + : Error<"%select{no|too many}0 integer expression arguments provided to " + "OpenACC 'num_gangs' " + "%select{|clause: '%1' directive expects maximum of %2, %3 were " + "provided}0">; } // end of sema component. diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 24b109e32cdd3e95a0000411779374228a1e8477..75562284ec7de07e5bb390102a5c75a5343f47e3 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -224,6 +224,11 @@ public: /// - the parameter list of a template template parameter Ver17, + /// Attempt to be ABI-compatible with code generated by Clang 18.0.x. + /// This causes clang to revert some fixes to the mangling of lambdas + /// in the initializers of members of local classes. + Ver18, + /// Conform to the underlying platform's C and C++ ABIs as closely /// as we can. Latest diff --git a/clang/include/clang/Basic/OpenACCClauses.def b/clang/include/clang/Basic/OpenACCClauses.def index 520e068f4ffd403cb523445fa8cb866dd24c9832..dd5792e7ca8c39c33492a8cc64c4cbd5d041970f 100644 --- a/clang/include/clang/Basic/OpenACCClauses.def +++ b/clang/include/clang/Basic/OpenACCClauses.def @@ -18,6 +18,7 @@ VISIT_CLAUSE(Default) VISIT_CLAUSE(If) VISIT_CLAUSE(Self) +VISIT_CLAUSE(NumGangs) VISIT_CLAUSE(NumWorkers) VISIT_CLAUSE(VectorLength) diff --git a/clang/include/clang/Basic/riscv_vector.td b/clang/include/clang/Basic/riscv_vector.td index 87a18e8474ef5031a00f1dcf5dfc0fee55c23d12..76ed544f3b2bb1f2e0176932098b732613ec1b7a 100644 --- a/clang/include/clang/Basic/riscv_vector.td +++ b/clang/include/clang/Basic/riscv_vector.td @@ -357,13 +357,13 @@ multiclass RVVNonTupleVCreateBuiltin src_lmul_list> { defvar src_s = FixedVString.S; def vcreate # src_v # dst_v : RVVBuiltin; + "csilxfd">; defvar src_uv = FixedVString.V; defvar src_us = FixedVString.S; def vcreate_u # src_uv # dst_uv : RVVBuiltin; + "csil">; } } diff --git a/clang/include/clang/Driver/OffloadBundler.h b/clang/include/clang/Driver/OffloadBundler.h index 65d33bfbd2825f907c580b70684a36d41d1abd4e..57ecbdcb7d040e238eaf0b6d11009ec7ac0a605f 100644 --- a/clang/include/clang/Driver/OffloadBundler.h +++ b/clang/include/clang/Driver/OffloadBundler.h @@ -100,6 +100,7 @@ struct OffloadTargetInfo { // - Version (2 bytes) // - Compression Method (2 bytes) - Uses the values from // llvm::compression::Format. +// - Total file size (4 bytes). Available in version 2 and above. // - Uncompressed Size (4 bytes). // - Truncated MD5 Hash (8 bytes). // - Compressed Data (variable length). @@ -109,13 +110,17 @@ private: static inline const size_t MagicSize = 4; static inline const size_t VersionFieldSize = sizeof(uint16_t); static inline const size_t MethodFieldSize = sizeof(uint16_t); - static inline const size_t SizeFieldSize = sizeof(uint32_t); - static inline const size_t HashFieldSize = 8; - static inline const size_t HeaderSize = MagicSize + VersionFieldSize + - MethodFieldSize + SizeFieldSize + - HashFieldSize; + static inline const size_t FileSizeFieldSize = sizeof(uint32_t); + static inline const size_t UncompressedSizeFieldSize = sizeof(uint32_t); + static inline const size_t HashFieldSize = sizeof(uint64_t); + static inline const size_t V1HeaderSize = + MagicSize + VersionFieldSize + MethodFieldSize + + UncompressedSizeFieldSize + HashFieldSize; + static inline const size_t V2HeaderSize = + MagicSize + VersionFieldSize + FileSizeFieldSize + MethodFieldSize + + UncompressedSizeFieldSize + HashFieldSize; static inline const llvm::StringRef MagicNumber = "CCOB"; - static inline const uint16_t Version = 1; + static inline const uint16_t Version = 2; public: static llvm::Expected> diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d682a24ab3da554e6c8486ca31bb882a1a4a7900..9f86808145d9ab4a435bd1656e5ce9575896fab1 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -807,8 +807,12 @@ def gcc_install_dir_EQ : Joined<["--"], "gcc-install-dir=">, "Note: executables (e.g. ld) used by the compiler are not overridden by the selected GCC installation">; def gcc_toolchain : Joined<["--"], "gcc-toolchain=">, Flags<[NoXarchOption]>, Visibility<[ClangOption, FlangOption]>, - HelpText<"Specify a directory where Clang can find 'include' and 'lib{,32,64}/gcc{,-cross}/$triple/$version'. " - "Clang will use the GCC installation with the largest version">; + HelpText< + "Specify a directory where Clang can find 'include' and 'lib{,32,64}/gcc{,-cross}/$triple/$version'. " + "Clang will use the GCC installation with the largest version">, + HelpTextForVariants<[FlangOption], + "Specify a directory where Flang can find 'lib{,32,64}/gcc{,-cross}/$triple/$version'. " + "Flang will use the GCC installation with the largest version">; def gcc_triple_EQ : Joined<["--"], "gcc-triple=">, HelpText<"Search for the GCC installation with the specified triple.">; def CC : Flag<["-"], "CC">, Visibility<[ClangOption, CC1Option]>, @@ -3100,6 +3104,11 @@ defm modules_skip_header_search_paths : BoolFOption<"modules-skip-header-search- HeaderSearchOpts<"ModulesSkipHeaderSearchPaths">, DefaultFalse, PosFlag, NegFlag, BothFlags<[], [CC1Option]>>; +def fno_modules_prune_non_affecting_module_map_files : + Flag<["-"], "fno-modules-prune-non-affecting-module-map-files">, + Group, Flags<[]>, Visibility<[CC1Option]>, + MarshallingInfoNegativeFlag>, + HelpText<"Do not prune non-affecting module map files when writing module files">; def fincremental_extensions : Flag<["-"], "fincremental-extensions">, @@ -4747,9 +4756,9 @@ def munaligned_symbols : Flag<["-"], "munaligned-symbols">, Group, HelpText<"Expect external char-aligned symbols to be without ABI alignment (SystemZ only)">; def mno_unaligned_symbols : Flag<["-"], "mno-unaligned-symbols">, Group, HelpText<"Expect external char-aligned symbols to be without ABI alignment (SystemZ only)">; -def mstrict_align : Flag<["-"], "mstrict-align">, +def mstrict_align : Flag<["-"], "mstrict-align">, Group, HelpText<"Force all memory accesses to be aligned (AArch64/LoongArch/RISC-V only)">; -def mno_strict_align : Flag<["-"], "mno-strict-align">, +def mno_strict_align : Flag<["-"], "mno-strict-align">, Group, HelpText<"Allow memory accesses to be unaligned (AArch64/LoongArch/RISC-V only)">; def mno_thumb : Flag<["-"], "mno-thumb">, Group; def mrestrict_it: Flag<["-"], "mrestrict-it">, Group, @@ -8346,14 +8355,15 @@ def _SLASH_FI : CLJoinedOrSeparate<"FI">, def _SLASH_Fe : CLJoined<"Fe">, HelpText<"Set output executable file name">, MetaVarName<"">; -def _SLASH_Fe_COLON : CLJoined<"Fe:">, Alias<_SLASH_Fe>; +def _SLASH_Fe_COLON : CLJoinedOrSeparate<"Fe:">, Alias<_SLASH_Fe>; def _SLASH_Fi : CLCompileJoined<"Fi">, HelpText<"Set preprocess output file name (with /P)">, MetaVarName<"">; +def _SLASH_Fi_COLON : CLJoinedOrSeparate<"Fi:">, Alias<_SLASH_Fi>; def _SLASH_Fo : CLCompileJoined<"Fo">, HelpText<"Set output object file (with /c)">, MetaVarName<"">; -def _SLASH_Fo_COLON : CLCompileJoined<"Fo:">, Alias<_SLASH_Fo>; +def _SLASH_Fo_COLON : CLCompileJoinedOrSeparate<"Fo:">, Alias<_SLASH_Fo>; def _SLASH_guard : CLJoined<"guard:">, HelpText<"Enable Control Flow Guard with /guard:cf, or only the table with /guard:cf,nochecks. " "Enable EH Continuation Guard with /guard:ehcont">; @@ -8448,6 +8458,7 @@ def _SLASH_Zc_dllexportInlines_ : CLFlag<"Zc:dllexportInlines-">, HelpText<"Do not dllexport/dllimport inline member functions of dllexport/import classes">; def _SLASH_Fp : CLJoined<"Fp">, HelpText<"Set pch file name (with /Yc and /Yu)">, MetaVarName<"">; +def _SLASH_Fp_COLON : CLJoinedOrSeparate<"Fp:">, Alias<_SLASH_Fp>; def _SLASH_Gd : CLFlag<"Gd">, HelpText<"Set __cdecl as a default calling convention">; diff --git a/clang/include/clang/Lex/HeaderSearchOptions.h b/clang/include/clang/Lex/HeaderSearchOptions.h index 637dc77e5d957ec70beecc0aa5edb53dfd978548..e4437ac0e35263db2a413a2f7cf11326976a6b21 100644 --- a/clang/include/clang/Lex/HeaderSearchOptions.h +++ b/clang/include/clang/Lex/HeaderSearchOptions.h @@ -252,6 +252,10 @@ public: LLVM_PREFERRED_TYPE(bool) unsigned ModulesSkipPragmaDiagnosticMappings : 1; + /// Whether to prune non-affecting module map files from PCM files. + LLVM_PREFERRED_TYPE(bool) + unsigned ModulesPruneNonAffectingModuleMaps : 1; + LLVM_PREFERRED_TYPE(bool) unsigned ModulesHashContent : 1; @@ -280,7 +284,8 @@ public: ModulesValidateDiagnosticOptions(true), ModulesSkipDiagnosticOptions(false), ModulesSkipHeaderSearchPaths(false), - ModulesSkipPragmaDiagnosticMappings(false), ModulesHashContent(false), + ModulesSkipPragmaDiagnosticMappings(false), + ModulesPruneNonAffectingModuleMaps(true), ModulesHashContent(false), ModulesStrictContextHash(false), ModulesIncludeVFSUsage(false) {} /// AddPath - Add the \p Path path to the specified \p Group list. diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h index 643ddbdad8c87dbe038fbaa311f6497cac694cc8..2ed42d1c5f9aae9aef473d1d85c9cec885c5d1a5 100644 --- a/clang/include/clang/Lex/LiteralSupport.h +++ b/clang/include/clang/Lex/LiteralSupport.h @@ -80,7 +80,8 @@ public: bool isFloat128 : 1; // 1.0q bool isFract : 1; // 1.0hr/r/lr/uhr/ur/ulr bool isAccum : 1; // 1.0hk/k/lk/uhk/uk/ulk - bool isBitInt : 1; // 1wb, 1uwb (C23) + bool isBitInt : 1; // 1wb, 1uwb (C23) or 1__wb, 1__uwb (Clang extension in C++ + // mode) uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64. diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 72b2f958a5e622e90343b733dbd60aab0a26ed97..d3bb04ff7a2c6db05c59f57a2365479ed1040c4e 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -3644,10 +3644,22 @@ private: /// Parses the clause of the 'bind' argument, which can be a string literal or /// an ID expression. ExprResult ParseOpenACCBindClauseArgument(); + + /// A type to represent the state of parsing after an attempt to parse an + /// OpenACC int-expr. This is useful to determine whether an int-expr list can + /// continue parsing after a failed int-expr. + using OpenACCIntExprParseResult = + std::pair; /// Parses the clause kind of 'int-expr', which can be any integral /// expression. - ExprResult ParseOpenACCIntExpr(OpenACCDirectiveKind DK, OpenACCClauseKind CK, - SourceLocation Loc); + OpenACCIntExprParseResult ParseOpenACCIntExpr(OpenACCDirectiveKind DK, + OpenACCClauseKind CK, + SourceLocation Loc); + /// Parses the argument list for 'num_gangs', which allows up to 3 + /// 'int-expr's. + bool ParseOpenACCIntExprList(OpenACCDirectiveKind DK, OpenACCClauseKind CK, + SourceLocation Loc, + llvm::SmallVectorImpl &IntExprs); /// Parses the 'device-type-list', which is a list of identifiers. bool ParseOpenACCDeviceTypeList(); /// Parses the 'async-argument', which is an integral value with two diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 1e89dfc58d92b1758df8f9245025b566655ef076..64607b91acbfc957099776c44cffa4028a0a65f1 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -5445,7 +5445,7 @@ public: ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind); ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val); - bool CheckLoopHintExpr(Expr *E, SourceLocation Loc); + bool CheckLoopHintExpr(Expr *E, SourceLocation Loc, bool AllowZero); ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = nullptr); ExprResult ActOnCharacterConstant(const Token &Tok, @@ -6527,7 +6527,10 @@ public: SourceLocation RParenLoc); //// ActOnCXXThis - Parse 'this' pointer. - ExprResult ActOnCXXThis(SourceLocation loc); + ExprResult ActOnCXXThis(SourceLocation Loc); + + /// Check whether the type of 'this' is valid in the current context. + bool CheckCXXThisType(SourceLocation Loc, QualType Type); /// Build a CXXThisExpr and mark it referenced in the current context. Expr *BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit); @@ -6949,10 +6952,14 @@ private: ///@{ public: + /// Check whether an expression might be an implicit class member access. + bool isPotentialImplicitMemberAccess(const CXXScopeSpec &SS, LookupResult &R, + bool IsAddressOfOperand); + ExprResult BuildPossibleImplicitMemberExpr( const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, - const TemplateArgumentListInfo *TemplateArgs, const Scope *S, - UnresolvedLookupExpr *AsULE = nullptr); + const TemplateArgumentListInfo *TemplateArgs, const Scope *S); + ExprResult BuildImplicitMemberExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, diff --git a/clang/include/clang/Sema/SemaOpenACC.h b/clang/include/clang/Sema/SemaOpenACC.h index 023722049732afe03d3b655af4ab50f5c2a8119a..ea28617f79b81b65df7d5cc63050a55a07003adb 100644 --- a/clang/include/clang/Sema/SemaOpenACC.h +++ b/clang/include/clang/Sema/SemaOpenACC.h @@ -93,14 +93,16 @@ public: } unsigned getNumIntExprs() const { - assert((ClauseKind == OpenACCClauseKind::NumWorkers || + assert((ClauseKind == OpenACCClauseKind::NumGangs || + ClauseKind == OpenACCClauseKind::NumWorkers || ClauseKind == OpenACCClauseKind::VectorLength) && "Parsed clause kind does not have a int exprs"); return std::get(Details).IntExprs.size(); } ArrayRef getIntExprs() { - assert((ClauseKind == OpenACCClauseKind::NumWorkers || + assert((ClauseKind == OpenACCClauseKind::NumGangs || + ClauseKind == OpenACCClauseKind::NumWorkers || ClauseKind == OpenACCClauseKind::VectorLength) && "Parsed clause kind does not have a int exprs"); return std::get(Details).IntExprs; @@ -134,11 +136,19 @@ public: } void setIntExprDetails(ArrayRef IntExprs) { - assert((ClauseKind == OpenACCClauseKind::NumWorkers || + assert((ClauseKind == OpenACCClauseKind::NumGangs || + ClauseKind == OpenACCClauseKind::NumWorkers || ClauseKind == OpenACCClauseKind::VectorLength) && "Parsed clause kind does not have a int exprs"); Details = IntExprDetails{{IntExprs.begin(), IntExprs.end()}}; } + void setIntExprDetails(llvm::SmallVector &&IntExprs) { + assert((ClauseKind == OpenACCClauseKind::NumGangs || + ClauseKind == OpenACCClauseKind::NumWorkers || + ClauseKind == OpenACCClauseKind::VectorLength) && + "Parsed clause kind does not have a int exprs"); + Details = IntExprDetails{IntExprs}; + } }; SemaOpenACC(Sema &S); diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 43ee06c524b3a0b75b9f9d3158890cce4803a736..1cd8b6a357cbf9575db6220956642d4450c81f60 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -501,6 +501,8 @@ private: /// = I + 1 has already been loaded. llvm::PagedVector DeclsLoaded; + static_assert(std::is_same_v); + using GlobalDeclMapType = ContinuousRangeMap; diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index b974fc28283c775ee1a24ae7c9cb67f3bc99c0e6..b36fb5523af5a6b194add7151f074bd42f128b95 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -7241,6 +7241,14 @@ QualType ASTContext::isPromotableBitField(Expr *E) const { // We perform that promotion here to match GCC and C++. // FIXME: C does not permit promotion of an enum bit-field whose rank is // greater than that of 'int'. We perform that promotion to match GCC. + // + // C23 6.3.1.1p2: + // The value from a bit-field of a bit-precise integer type is converted to + // the corresponding bit-precise integer type. (The rest is the same as in + // C11.) + if (QualType QT = Field->getType(); QT->isBitIntType()) + return QT; + if (BitWidth < IntSize) return IntTy; diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 6aaa34c55ce3078510f4210edcc4fa11259c2739..60f213322b346bb8b06a7a569989731aeb8f7de0 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -695,7 +695,7 @@ namespace clang { // Returns true if the given function has a placeholder return type and // that type is declared inside the body of the function. // E.g. auto f() { struct X{}; return X(); } - bool hasAutoReturnTypeDeclaredInside(FunctionDecl *D); + bool hasReturnTypeDeclaredInside(FunctionDecl *D); }; template @@ -3647,15 +3647,28 @@ private: }; } // namespace -/// This function checks if the function has 'auto' return type that contains +/// This function checks if the given function has a return type that contains /// a reference (in any way) to a declaration inside the same function. -bool ASTNodeImporter::hasAutoReturnTypeDeclaredInside(FunctionDecl *D) { +bool ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) { QualType FromTy = D->getType(); const auto *FromFPT = FromTy->getAs(); assert(FromFPT && "Must be called on FunctionProtoType"); + auto IsCXX11LambdaWithouTrailingReturn = [&]() { + if (Importer.FromContext.getLangOpts().CPlusPlus14) // C++14 or later + return false; + + if (FromFPT->hasTrailingReturn()) + return false; + + if (const auto *MD = dyn_cast(D)) + return cast(MD->getDeclContext())->isLambda(); + + return false; + }; + QualType RetT = FromFPT->getReturnType(); - if (isa(RetT.getTypePtr())) { + if (isa(RetT.getTypePtr()) || IsCXX11LambdaWithouTrailingReturn()) { FunctionDecl *Def = D->getDefinition(); IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D); return Visitor.CheckType(RetT); @@ -3811,7 +3824,7 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { // E.g.: auto foo() { struct X{}; return X(); } // To avoid an infinite recursion when importing, create the FunctionDecl // with a simplified return type. - if (hasAutoReturnTypeDeclaredInside(D)) { + if (hasReturnTypeDeclaredInside(D)) { FromReturnTy = Importer.getFromContext().VoidTy; UsedDifferentProtoType = true; } @@ -8561,8 +8574,8 @@ ASTNodeImporter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) { return UnresolvedLookupExpr::Create( Importer.getToContext(), *ToNamingClassOrErr, *ToQualifierLocOrErr, - ToNameInfo, E->requiresADL(), E->isOverloaded(), ToDecls.begin(), - ToDecls.end()); + ToNameInfo, E->requiresADL(), ToDecls.begin(), ToDecls.end(), + /*KnownDependent=*/E->isTypeDependent()); } ExpectedStmt diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 1b99c435aebb2ab73ffb46d73dbad24836947259..474e0ccde5bbf793369028e9fee2a2d6660032f1 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2151,7 +2151,7 @@ VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartL, return new (C, DC) VarDecl(Var, C, DC, StartL, IdL, Id, T, TInfo, S); } -VarDecl *VarDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +VarDecl *VarDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) VarDecl(Var, C, nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, SC_None); @@ -2929,7 +2929,7 @@ QualType ParmVarDecl::getOriginalType() const { return T; } -ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) ParmVarDecl(ParmVar, C, nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, SC_None, nullptr); @@ -4553,7 +4553,7 @@ FieldDecl *FieldDecl::Create(const ASTContext &C, DeclContext *DC, BW, Mutable, InitStyle); } -FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) FieldDecl(Field, nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, nullptr, false, ICIS_NoInit); @@ -4863,7 +4863,7 @@ EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, return Enum; } -EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { EnumDecl *Enum = new (C, ID) EnumDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr, false, false, false); @@ -5025,7 +5025,7 @@ RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC, return R; } -RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) { +RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, Decl::DeclID ID) { RecordDecl *R = new (C, ID) RecordDecl(Record, TagTypeKind::Struct, C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); @@ -5297,7 +5297,7 @@ PragmaCommentDecl *PragmaCommentDecl::Create(const ASTContext &C, } PragmaCommentDecl *PragmaCommentDecl::CreateDeserialized(ASTContext &C, - unsigned ID, + Decl::DeclID ID, unsigned ArgSize) { return new (C, ID, additionalSizeToAlloc(ArgSize + 1)) PragmaCommentDecl(nullptr, SourceLocation(), PCK_Unknown); @@ -5322,7 +5322,7 @@ PragmaDetectMismatchDecl::Create(const ASTContext &C, TranslationUnitDecl *DC, } PragmaDetectMismatchDecl * -PragmaDetectMismatchDecl::CreateDeserialized(ASTContext &C, unsigned ID, +PragmaDetectMismatchDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, unsigned NameValueSize) { return new (C, ID, additionalSizeToAlloc(NameValueSize + 1)) PragmaDetectMismatchDecl(nullptr, SourceLocation(), 0); @@ -5349,7 +5349,7 @@ LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) LabelDecl(DC, IdentL, II, nullptr, GnuLabelL); } -LabelDecl *LabelDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +LabelDecl *LabelDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) LabelDecl(nullptr, SourceLocation(), nullptr, nullptr, SourceLocation()); } @@ -5390,7 +5390,7 @@ ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, QualType Type, } ImplicitParamDecl *ImplicitParamDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) ImplicitParamDecl(C, QualType(), ImplicitParamKind::Other); } @@ -5408,7 +5408,7 @@ FunctionDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, return New; } -FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) FunctionDecl( Function, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, SC_None, false, false, ConstexprSpecKind::Unspecified, nullptr); @@ -5418,7 +5418,7 @@ BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { return new (C, DC) BlockDecl(DC, L); } -BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) BlockDecl(nullptr, SourceLocation()); } @@ -5432,7 +5432,7 @@ CapturedDecl *CapturedDecl::Create(ASTContext &C, DeclContext *DC, CapturedDecl(DC, NumParams); } -CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, unsigned ID, +CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, unsigned NumParams) { return new (C, ID, additionalSizeToAlloc(NumParams)) CapturedDecl(nullptr, NumParams); @@ -5459,7 +5459,7 @@ EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD, } EnumConstantDecl * -EnumConstantDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +EnumConstantDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) EnumConstantDecl(C, nullptr, SourceLocation(), nullptr, QualType(), nullptr, llvm::APSInt()); } @@ -5486,7 +5486,7 @@ IndirectFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, } IndirectFieldDecl *IndirectFieldDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) IndirectFieldDecl(C, nullptr, SourceLocation(), DeclarationName(), QualType(), std::nullopt); @@ -5547,7 +5547,7 @@ bool TypedefNameDecl::isTransparentTagSlow() const { return isTransparent; } -TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) TypedefDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); } @@ -5560,7 +5560,7 @@ TypeAliasDecl *TypeAliasDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) TypeAliasDecl(C, DC, StartLoc, IdLoc, Id, TInfo); } -TypeAliasDecl *TypeAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +TypeAliasDecl *TypeAliasDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) TypeAliasDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); } @@ -5591,7 +5591,7 @@ FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC, } FileScopeAsmDecl *FileScopeAsmDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) FileScopeAsmDecl(nullptr, nullptr, SourceLocation(), SourceLocation()); } @@ -5609,7 +5609,7 @@ TopLevelStmtDecl *TopLevelStmtDecl::Create(ASTContext &C, Stmt *Statement) { } TopLevelStmtDecl *TopLevelStmtDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) TopLevelStmtDecl(/*DC=*/nullptr, SourceLocation(), /*S=*/nullptr); } @@ -5630,7 +5630,7 @@ EmptyDecl *EmptyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { return new (C, DC) EmptyDecl(DC, L); } -EmptyDecl *EmptyDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +EmptyDecl *EmptyDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) EmptyDecl(nullptr, SourceLocation()); } @@ -5663,7 +5663,7 @@ HLSLBufferDecl *HLSLBufferDecl::Create(ASTContext &C, return Result; } -HLSLBufferDecl *HLSLBufferDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +HLSLBufferDecl *HLSLBufferDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) HLSLBufferDecl(nullptr, false, SourceLocation(), nullptr, SourceLocation(), SourceLocation()); } @@ -5719,7 +5719,7 @@ ImportDecl *ImportDecl::CreateImplicit(ASTContext &C, DeclContext *DC, return Import; } -ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, unsigned ID, +ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, unsigned NumLocations) { return new (C, ID, additionalSizeToAlloc(NumLocations)) ImportDecl(EmptyShell()); @@ -5752,6 +5752,6 @@ ExportDecl *ExportDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) ExportDecl(DC, ExportLoc); } -ExportDecl *ExportDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +ExportDecl *ExportDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) ExportDecl(nullptr, SourceLocation()); } diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 434926324c96ca25dea83258a27924d3cd9a3da2..7cb6b31c541fd373662921cc8e46de533d9c16f7 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -71,7 +71,7 @@ void Decl::updateOutOfDate(IdentifierInfo &II) const { #include "clang/AST/DeclNodes.inc" void *Decl::operator new(std::size_t Size, const ASTContext &Context, - unsigned ID, std::size_t Extra) { + Decl::DeclID ID, std::size_t Extra) { // Allocate an extra 8 bytes worth of storage, which ensures that the // resulting pointer will still be 8-byte aligned. static_assert(sizeof(unsigned) * 2 >= alignof(Decl), diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 00cc857f5e73798cb6a798ed0f84b435136929d1..426c5262051094b23d83023eacd2b0ac31abba65 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -57,7 +57,7 @@ using namespace clang; void AccessSpecDecl::anchor() {} -AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) AccessSpecDecl(EmptyShell()); } @@ -161,7 +161,7 @@ CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC, } CXXRecordDecl * -CXXRecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) { +CXXRecordDecl::CreateDeserialized(const ASTContext &C, Decl::DeclID ID) { auto *R = new (C, ID) CXXRecordDecl(CXXRecord, TagTypeKind::Struct, C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); @@ -2163,7 +2163,7 @@ CXXDeductionGuideDecl *CXXDeductionGuideDecl::Create( } CXXDeductionGuideDecl *CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) CXXDeductionGuideDecl( C, nullptr, SourceLocation(), ExplicitSpecifier(), DeclarationNameInfo(), QualType(), nullptr, SourceLocation(), nullptr, @@ -2176,7 +2176,7 @@ RequiresExprBodyDecl *RequiresExprBodyDecl::Create( } RequiresExprBodyDecl *RequiresExprBodyDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) RequiresExprBodyDecl(C, nullptr, SourceLocation()); } @@ -2281,7 +2281,7 @@ CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, isInline, ConstexprKind, EndLocation, TrailingRequiresClause); } -CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) CXXMethodDecl( CXXMethod, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, SC_None, false, false, @@ -2699,7 +2699,7 @@ CXXConstructorDecl::CXXConstructorDecl( void CXXConstructorDecl::anchor() {} CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C, - unsigned ID, + Decl::DeclID ID, uint64_t AllocKind) { bool hasTrailingExplicit = static_cast(AllocKind & TAKHasTailExplicit); bool isInheritingConstructor = @@ -2846,7 +2846,7 @@ bool CXXConstructorDecl::isSpecializationCopyingObject() const { void CXXDestructorDecl::anchor() {} CXXDestructorDecl * -CXXDestructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +CXXDestructorDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) CXXDestructorDecl( C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, false, false, false, ConstexprSpecKind::Unspecified, nullptr); @@ -2878,7 +2878,7 @@ void CXXDestructorDecl::setOperatorDelete(FunctionDecl *OD, Expr *ThisArg) { void CXXConversionDecl::anchor() {} CXXConversionDecl * -CXXConversionDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +CXXConversionDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) CXXConversionDecl( C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, false, false, ExplicitSpecifier(), ConstexprSpecKind::Unspecified, @@ -2924,7 +2924,7 @@ LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, DeclContext *DC, } LinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) LinkageSpecDecl(nullptr, SourceLocation(), SourceLocation(), LinkageSpecLanguageIDs::C, false); @@ -2946,7 +2946,7 @@ UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC, } UsingDirectiveDecl *UsingDirectiveDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) UsingDirectiveDecl(nullptr, SourceLocation(), SourceLocation(), NestedNameSpecifierLoc(), @@ -2985,7 +2985,7 @@ NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC, NamespaceDecl(C, DC, Inline, StartLoc, IdLoc, Id, PrevDecl, Nested); } -NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) NamespaceDecl(C, nullptr, false, SourceLocation(), SourceLocation(), nullptr, nullptr, false); } @@ -3047,7 +3047,7 @@ NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC, } NamespaceAliasDecl * -NamespaceAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +NamespaceAliasDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) NamespaceAliasDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, NestedNameSpecifierLoc(), @@ -3103,7 +3103,7 @@ UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, EmptyShell Empty) redeclarable_base(C) {} UsingShadowDecl * -UsingShadowDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +UsingShadowDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) UsingShadowDecl(UsingShadow, C, EmptyShell()); } @@ -3126,7 +3126,7 @@ ConstructorUsingShadowDecl::Create(ASTContext &C, DeclContext *DC, } ConstructorUsingShadowDecl * -ConstructorUsingShadowDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +ConstructorUsingShadowDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) ConstructorUsingShadowDecl(C, EmptyShell()); } @@ -3174,7 +3174,7 @@ UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation UL, return new (C, DC) UsingDecl(DC, UL, QualifierLoc, NameInfo, HasTypename); } -UsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +UsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) UsingDecl(nullptr, SourceLocation(), NestedNameSpecifierLoc(), DeclarationNameInfo(), false); @@ -3198,7 +3198,7 @@ UsingEnumDecl *UsingEnumDecl::Create(ASTContext &C, DeclContext *DC, UsingEnumDecl(DC, EnumType->getType()->getAsTagDecl()->getDeclName(), UL, EL, NL, EnumType); } -UsingEnumDecl *UsingEnumDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +UsingEnumDecl *UsingEnumDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) UsingEnumDecl(nullptr, DeclarationName(), SourceLocation(), SourceLocation(), SourceLocation(), nullptr); @@ -3217,7 +3217,7 @@ UsingPackDecl *UsingPackDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC, Extra) UsingPackDecl(DC, InstantiatedFrom, UsingDecls); } -UsingPackDecl *UsingPackDecl::CreateDeserialized(ASTContext &C, unsigned ID, +UsingPackDecl *UsingPackDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, unsigned NumExpansions) { size_t Extra = additionalSizeToAlloc(NumExpansions); auto *Result = @@ -3243,7 +3243,7 @@ UnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC, } UnresolvedUsingValueDecl * -UnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +UnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) UnresolvedUsingValueDecl(nullptr, QualType(), SourceLocation(), NestedNameSpecifierLoc(), @@ -3273,7 +3273,7 @@ UnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC, } UnresolvedUsingTypenameDecl * -UnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +UnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) UnresolvedUsingTypenameDecl( nullptr, SourceLocation(), SourceLocation(), NestedNameSpecifierLoc(), SourceLocation(), nullptr, SourceLocation()); @@ -3286,7 +3286,7 @@ UnresolvedUsingIfExistsDecl::Create(ASTContext &Ctx, DeclContext *DC, } UnresolvedUsingIfExistsDecl * -UnresolvedUsingIfExistsDecl::CreateDeserialized(ASTContext &Ctx, unsigned ID) { +UnresolvedUsingIfExistsDecl::CreateDeserialized(ASTContext &Ctx, Decl::DeclID ID) { return new (Ctx, ID) UnresolvedUsingIfExistsDecl(nullptr, SourceLocation(), DeclarationName()); } @@ -3310,7 +3310,7 @@ StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC, } StaticAssertDecl *StaticAssertDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) StaticAssertDecl(nullptr, SourceLocation(), nullptr, nullptr, SourceLocation(), false); } @@ -3332,7 +3332,7 @@ BindingDecl *BindingDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) BindingDecl(DC, IdLoc, Id); } -BindingDecl *BindingDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +BindingDecl *BindingDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) BindingDecl(nullptr, SourceLocation(), nullptr); } @@ -3363,7 +3363,7 @@ DecompositionDecl *DecompositionDecl::Create(ASTContext &C, DeclContext *DC, } DecompositionDecl *DecompositionDecl::CreateDeserialized(ASTContext &C, - unsigned ID, + Decl::DeclID ID, unsigned NumBindings) { size_t Extra = additionalSizeToAlloc(NumBindings); auto *Result = new (C, ID, Extra) @@ -3402,7 +3402,7 @@ MSPropertyDecl *MSPropertyDecl::Create(ASTContext &C, DeclContext *DC, } MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) MSPropertyDecl(nullptr, SourceLocation(), DeclarationName(), QualType(), nullptr, SourceLocation(), nullptr, nullptr); @@ -3419,7 +3419,7 @@ MSGuidDecl *MSGuidDecl::Create(const ASTContext &C, QualType T, Parts P) { return new (C, DC) MSGuidDecl(DC, T, P); } -MSGuidDecl *MSGuidDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +MSGuidDecl *MSGuidDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) MSGuidDecl(nullptr, QualType(), Parts()); } @@ -3529,7 +3529,7 @@ UnnamedGlobalConstantDecl::Create(const ASTContext &C, QualType T, } UnnamedGlobalConstantDecl * -UnnamedGlobalConstantDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +UnnamedGlobalConstantDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) UnnamedGlobalConstantDecl(C, nullptr, QualType(), APValue()); } diff --git a/clang/lib/AST/DeclFriend.cpp b/clang/lib/AST/DeclFriend.cpp index 8ec1dea84df5f19ed29c4e1068de854c87a0a68d..1fabf8aa80c2bdb66fca9e368f4d6f95a147038d 100644 --- a/clang/lib/AST/DeclFriend.cpp +++ b/clang/lib/AST/DeclFriend.cpp @@ -62,7 +62,7 @@ FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC, return FD; } -FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, unsigned ID, +FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, unsigned FriendTypeNumTPLists) { std::size_t Extra = additionalSizeToAlloc(FriendTypeNumTPLists); diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index 32c14938cd5888cd65a8dda612f5b996bf4a7f30..d4275eea058212976f056a3f72874d144e15f11f 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -862,7 +862,7 @@ ObjCMethodDecl *ObjCMethodDecl::Create( isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType); } -ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) ObjCMethodDecl(SourceLocation(), SourceLocation(), Selector(), QualType(), nullptr, nullptr); } @@ -1486,7 +1486,7 @@ ObjCTypeParamDecl *ObjCTypeParamDecl::Create(ASTContext &ctx, DeclContext *dc, } ObjCTypeParamDecl *ObjCTypeParamDecl::CreateDeserialized(ASTContext &ctx, - unsigned ID) { + Decl::DeclID ID) { return new (ctx, ID) ObjCTypeParamDecl(ctx, nullptr, ObjCTypeParamVariance::Invariant, SourceLocation(), 0, SourceLocation(), @@ -1551,7 +1551,7 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::Create( } ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { auto *Result = new (C, ID) ObjCInterfaceDecl(C, nullptr, SourceLocation(), nullptr, nullptr, SourceLocation(), nullptr, false); @@ -1865,7 +1865,7 @@ ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC, synthesized); } -ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, ObjCIvarDecl::None, nullptr, false); @@ -1914,7 +1914,7 @@ ObjCAtDefsFieldDecl } ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) ObjCAtDefsFieldDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr); @@ -1949,7 +1949,7 @@ ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC, } ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { ObjCProtocolDecl *Result = new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(), SourceLocation(), nullptr); @@ -2148,7 +2148,7 @@ ObjCCategoryDecl *ObjCCategoryDecl::Create( } ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(), SourceLocation(), SourceLocation(), nullptr, nullptr, nullptr); @@ -2189,7 +2189,7 @@ ObjCCategoryImplDecl *ObjCCategoryImplDecl::Create( } ObjCCategoryImplDecl *ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) ObjCCategoryImplDecl(nullptr, nullptr, nullptr, SourceLocation(), SourceLocation(), SourceLocation()); @@ -2296,7 +2296,7 @@ ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC, } ObjCImplementationDecl * -ObjCImplementationDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +ObjCImplementationDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) ObjCImplementationDecl(nullptr, nullptr, nullptr, SourceLocation(), SourceLocation()); } @@ -2339,7 +2339,7 @@ ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC, } ObjCCompatibleAliasDecl * -ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) ObjCCompatibleAliasDecl(nullptr, SourceLocation(), nullptr, nullptr); } @@ -2360,7 +2360,7 @@ ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, } ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) ObjCPropertyDecl(nullptr, SourceLocation(), nullptr, SourceLocation(), SourceLocation(), QualType(), nullptr, None); @@ -2393,7 +2393,7 @@ ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C, } ObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) ObjCPropertyImplDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, Dynamic, nullptr, SourceLocation()); diff --git a/clang/lib/AST/DeclOpenMP.cpp b/clang/lib/AST/DeclOpenMP.cpp index ac5780f82dbbb23b68257274af7328dff45b2229..b178a15aab5f282363b48a29bfa252c9c2a1783b 100644 --- a/clang/lib/AST/DeclOpenMP.cpp +++ b/clang/lib/AST/DeclOpenMP.cpp @@ -36,7 +36,7 @@ OMPThreadPrivateDecl *OMPThreadPrivateDecl::Create(ASTContext &C, } OMPThreadPrivateDecl *OMPThreadPrivateDecl::CreateDeserialized(ASTContext &C, - unsigned ID, + Decl::DeclID ID, unsigned N) { return OMPDeclarativeDirective::createEmptyDirective( C, ID, 0, N); @@ -63,7 +63,7 @@ OMPAllocateDecl *OMPAllocateDecl::Create(ASTContext &C, DeclContext *DC, return D; } -OMPAllocateDecl *OMPAllocateDecl::CreateDeserialized(ASTContext &C, unsigned ID, +OMPAllocateDecl *OMPAllocateDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, unsigned NVars, unsigned NClauses) { return OMPDeclarativeDirective::createEmptyDirective( @@ -89,7 +89,7 @@ OMPRequiresDecl *OMPRequiresDecl::Create(ASTContext &C, DeclContext *DC, L); } -OMPRequiresDecl *OMPRequiresDecl::CreateDeserialized(ASTContext &C, unsigned ID, +OMPRequiresDecl *OMPRequiresDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, unsigned N) { return OMPDeclarativeDirective::createEmptyDirective( C, ID, N, 0, SourceLocation()); @@ -117,7 +117,7 @@ OMPDeclareReductionDecl *OMPDeclareReductionDecl::Create( } OMPDeclareReductionDecl * -OMPDeclareReductionDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +OMPDeclareReductionDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) OMPDeclareReductionDecl( OMPDeclareReduction, /*DC=*/nullptr, SourceLocation(), DeclarationName(), QualType(), /*PrevDeclInScope=*/nullptr); @@ -148,7 +148,7 @@ OMPDeclareMapperDecl *OMPDeclareMapperDecl::Create( } OMPDeclareMapperDecl *OMPDeclareMapperDecl::CreateDeserialized(ASTContext &C, - unsigned ID, + Decl::DeclID ID, unsigned N) { return OMPDeclarativeDirective::createEmptyDirective( C, ID, N, 1, SourceLocation(), DeclarationName(), QualType(), @@ -179,7 +179,7 @@ OMPCapturedExprDecl *OMPCapturedExprDecl::Create(ASTContext &C, DeclContext *DC, } OMPCapturedExprDecl *OMPCapturedExprDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) OMPCapturedExprDecl(C, nullptr, nullptr, QualType(), /*TInfo=*/nullptr, SourceLocation()); } diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 5aa2484197372bae11343ba22335c1734023ca1d..0ba271c3e04ee5ddf91cb5138c8e77dfadd4ff54 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -418,7 +418,7 @@ FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, } FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -503,7 +503,7 @@ ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC, } ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -652,14 +652,14 @@ TemplateTypeParmDecl *TemplateTypeParmDecl::Create( } TemplateTypeParmDecl * -TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) { +TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, Decl::DeclID ID) { return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, false, false, std::nullopt); } TemplateTypeParmDecl * -TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID, +TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, Decl::DeclID ID, bool HasTypeConstraint) { return new (C, ID, additionalSizeToAlloc(HasTypeConstraint ? 1 : 0)) @@ -759,7 +759,7 @@ NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create( } NonTypeTemplateParmDecl * -NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, +NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, bool HasTypeConstraint) { return new (C, ID, additionalSizeToAlloc, @@ -770,7 +770,7 @@ NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, } NonTypeTemplateParmDecl * -NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, +NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, unsigned NumExpandedTypes, bool HasTypeConstraint) { auto *NTTP = @@ -836,13 +836,13 @@ TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, } TemplateTemplateParmDecl * -TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, false, nullptr, false, nullptr); } TemplateTemplateParmDecl * -TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, +TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, unsigned NumExpansions) { auto *TTP = new (C, ID, additionalSizeToAlloc(NumExpansions)) @@ -949,7 +949,7 @@ ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, ClassTemplateSpecializationDecl * ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { auto *Result = new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization); Result->setMayHaveOutOfDateDef(false); @@ -1036,7 +1036,7 @@ ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC, } ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); @@ -1070,7 +1070,7 @@ ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create( ImplicitConceptSpecializationDecl * ImplicitConceptSpecializationDecl::CreateDeserialized( - const ASTContext &C, unsigned ID, unsigned NumTemplateArgs) { + const ASTContext &C, Decl::DeclID ID, unsigned NumTemplateArgs) { return new (C, ID, additionalSizeToAlloc(NumTemplateArgs)) ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs); } @@ -1133,7 +1133,7 @@ Create(ASTContext &Context, TagKind TK,DeclContext *DC, ClassTemplatePartialSpecializationDecl * ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C); Result->setMayHaveOutOfDateDef(false); return Result; @@ -1160,7 +1160,7 @@ FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC, } FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) FriendTemplateDecl(EmptyShell()); } @@ -1180,7 +1180,7 @@ TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, } TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -1218,7 +1218,7 @@ VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC, } VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -1340,7 +1340,7 @@ VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create( } VarTemplateSpecializationDecl * -VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { return new (C, ID) VarTemplateSpecializationDecl(VarTemplateSpecialization, C); } @@ -1432,7 +1432,7 @@ VarTemplatePartialSpecializationDecl::Create( VarTemplatePartialSpecializationDecl * VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { + Decl::DeclID ID) { return new (C, ID) VarTemplatePartialSpecializationDecl(C); } @@ -1546,7 +1546,7 @@ TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C, } TemplateParamObjectDecl * -TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, unsigned ID) { +TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue()); C.addDestruction(&TPOD->Value); return TPOD; diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index a581963188433e014cb4a3d74f974cbc2274028c..7e9343271ac3cfd551026ab3c0d54d7bced980e4 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -353,7 +353,7 @@ SourceLocation CXXPseudoDestructorExpr::getEndLoc() const { UnresolvedLookupExpr::UnresolvedLookupExpr( const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, - const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, + const DeclarationNameInfo &NameInfo, bool RequiresADL, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool KnownDependent) : OverloadExpr(UnresolvedLookupExprClass, Context, QualifierLoc, @@ -361,7 +361,6 @@ UnresolvedLookupExpr::UnresolvedLookupExpr( KnownDependent, false, false), NamingClass(NamingClass) { UnresolvedLookupExprBits.RequiresADL = RequiresADL; - UnresolvedLookupExprBits.Overloaded = Overloaded; } UnresolvedLookupExpr::UnresolvedLookupExpr(EmptyShell Empty, @@ -373,15 +372,16 @@ UnresolvedLookupExpr::UnresolvedLookupExpr(EmptyShell Empty, UnresolvedLookupExpr *UnresolvedLookupExpr::Create( const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, - bool RequiresADL, bool Overloaded, UnresolvedSetIterator Begin, - UnresolvedSetIterator End) { + bool RequiresADL, UnresolvedSetIterator Begin, UnresolvedSetIterator End, + bool KnownDependent) { unsigned NumResults = End - Begin; unsigned Size = totalSizeToAlloc(NumResults, 0, 0); void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr)); - return new (Mem) UnresolvedLookupExpr(Context, NamingClass, QualifierLoc, - SourceLocation(), NameInfo, RequiresADL, - Overloaded, nullptr, Begin, End, false); + return new (Mem) UnresolvedLookupExpr( + Context, NamingClass, QualifierLoc, + /*TemplateKWLoc=*/SourceLocation(), NameInfo, RequiresADL, + /*TemplateArgs=*/nullptr, Begin, End, KnownDependent); } UnresolvedLookupExpr *UnresolvedLookupExpr::Create( @@ -390,16 +390,16 @@ UnresolvedLookupExpr *UnresolvedLookupExpr::Create( const DeclarationNameInfo &NameInfo, bool RequiresADL, const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool KnownDependent) { - assert(Args || TemplateKWLoc.isValid()); unsigned NumResults = End - Begin; + bool HasTemplateKWAndArgsInfo = Args || TemplateKWLoc.isValid(); unsigned NumTemplateArgs = Args ? Args->size() : 0; - unsigned Size = - totalSizeToAlloc(NumResults, 1, NumTemplateArgs); + unsigned Size = totalSizeToAlloc( + NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs); void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr)); - return new (Mem) UnresolvedLookupExpr( - Context, NamingClass, QualifierLoc, TemplateKWLoc, NameInfo, RequiresADL, - /*Overloaded=*/true, Args, Begin, End, KnownDependent); + return new (Mem) UnresolvedLookupExpr(Context, NamingClass, QualifierLoc, + TemplateKWLoc, NameInfo, RequiresADL, + Args, Begin, End, KnownDependent); } UnresolvedLookupExpr *UnresolvedLookupExpr::CreateEmpty( diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 73ae8d8efb23a28d372ef170bcb05ce7f4089882..de3c2a63913e94295d0a3007231b70e04c2318aa 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -16853,13 +16853,13 @@ bool Expr::EvaluateCharRangeAsString(std::string &Result, if (!::EvaluateInteger(SizeExpression, SizeValue, Info)) return false; - int64_t Size = SizeValue.getExtValue(); + uint64_t Size = SizeValue.getZExtValue(); if (!::EvaluatePointer(PtrExpression, String, Info)) return false; QualType CharTy = PtrExpression->getType()->getPointeeType(); - for (int64_t I = 0; I < Size; ++I) { + for (uint64_t I = 0; I < Size; ++I) { APValue Char; if (!handleLValueToRValueConversion(Info, PtrExpression, CharTy, String, Char)) diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index f317f506d24f4b9fe8f962d27fbe3f010899c4d4..8cd0c198d9a844d6de48d284b4a4321bffbfd22a 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -194,6 +194,12 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { return false; PrimType T = classifyPrim(CE->getType()); + if (T == PT_IntAP) + return this->emitCastPointerIntegralAP(Ctx.getBitWidth(CE->getType()), + CE); + if (T == PT_IntAPS) + return this->emitCastPointerIntegralAPS(Ctx.getBitWidth(CE->getType()), + CE); return this->emitCastPointerIntegral(T, CE); } @@ -922,9 +928,9 @@ bool ByteCodeExprGen::VisitImplicitValueInitExpr(const ImplicitValueIni return true; } - if (QT->isAnyComplexType()) { + if (const auto *ComplexTy = E->getType()->getAs()) { assert(Initializing); - QualType ElemQT = QT->getAs()->getElementType(); + QualType ElemQT = ComplexTy->getElementType(); PrimType ElemT = classifyPrim(ElemQT); for (unsigned I = 0; I < 2; ++I) { if (!this->visitZeroInitializer(ElemT, ElemQT, E)) @@ -935,6 +941,20 @@ bool ByteCodeExprGen::VisitImplicitValueInitExpr(const ImplicitValueIni return true; } + if (const auto *VecT = E->getType()->getAs()) { + unsigned NumVecElements = VecT->getNumElements(); + QualType ElemQT = VecT->getElementType(); + PrimType ElemT = classifyPrim(ElemQT); + + for (unsigned I = 0; I < NumVecElements; ++I) { + if (!this->visitZeroInitializer(ElemT, ElemQT, E)) + return false; + if (!this->emitInitElem(ElemT, I, E)) + return false; + } + return true; + } + return false; } @@ -1098,13 +1118,13 @@ bool ByteCodeExprGen::VisitInitListExpr(const InitListExpr *E) { return true; } - if (T->isAnyComplexType()) { + if (const auto *ComplexTy = E->getType()->getAs()) { unsigned NumInits = E->getNumInits(); if (NumInits == 1) return this->delegate(E->inits()[0]); - QualType ElemQT = E->getType()->getAs()->getElementType(); + QualType ElemQT = ComplexTy->getElementType(); PrimType ElemT = classifyPrim(ElemQT); if (NumInits == 0) { // Zero-initialize both elements. @@ -1337,6 +1357,8 @@ bool ByteCodeExprGen::VisitMemberExpr(const MemberExpr *E) { if (const auto *FD = dyn_cast(Member)) { const RecordDecl *RD = FD->getParent(); const Record *R = getRecord(RD); + if (!R) + return false; const Record::Field *F = R->getField(FD); // Leave a pointer to the field on the stack. if (F->Decl->getType()->isReferenceType()) diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp index 55a06f37a0c3dec8296174593d35c07579e53f80..36dab6252ece67a4071ed3b338e28f9524a3db3e 100644 --- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp @@ -675,7 +675,30 @@ bool ByteCodeStmtGen::visitDefaultStmt(const DefaultStmt *S) { template bool ByteCodeStmtGen::visitAttributedStmt(const AttributedStmt *S) { - // Ignore all attributes. + + for (const Attr *A : S->getAttrs()) { + auto *AA = dyn_cast(A); + if (!AA) + continue; + + assert(isa(S->getSubStmt())); + + const Expr *Assumption = AA->getAssumption(); + if (Assumption->isValueDependent()) + return false; + + if (Assumption->HasSideEffects(this->Ctx.getASTContext())) + continue; + + // Evaluate assumption. + if (!this->visitBool(Assumption)) + return false; + + if (!this->emitAssume(Assumption)) + return false; + } + + // Ignore other attributes. return this->visitStmt(S->getSubStmt()); } diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h index bab9774288bfa6e127f5ddead8e0fa334dd4c3b5..fb7ee14515715aa6696c7de240715d6542e8c088 100644 --- a/clang/lib/AST/Interp/IntegralAP.h +++ b/clang/lib/AST/Interp/IntegralAP.h @@ -154,7 +154,10 @@ public: } IntegralAP truncate(unsigned BitWidth) const { - return IntegralAP(V.trunc(BitWidth)); + if constexpr (Signed) + return IntegralAP(V.trunc(BitWidth).sextOrTrunc(this->bitWidth())); + else + return IntegralAP(V.trunc(BitWidth).zextOrTrunc(this->bitWidth())); } IntegralAP toUnsigned() const { diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index dd0bacd73acb107f1280eb929cf75d886a617754..9283f697c007098804c8486cc9f0c4d31635f846 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -1548,17 +1548,16 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset, if (!CheckArray(S, OpPC, Ptr)) return false; - // Get a version of the index comparable to the type. - T Index = T::from(Ptr.getIndex(), Offset.bitWidth()); - // Compute the largest index into the array. - T MaxIndex = T::from(Ptr.getNumElems(), Offset.bitWidth()); + uint64_t Index = Ptr.getIndex(); + uint64_t MaxIndex = static_cast(Ptr.getNumElems()); bool Invalid = false; // Helper to report an invalid offset, computed as APSInt. auto DiagInvalidOffset = [&]() -> void { const unsigned Bits = Offset.bitWidth(); - APSInt APOffset(Offset.toAPSInt().extend(Bits + 2), false); - APSInt APIndex(Index.toAPSInt().extend(Bits + 2), false); + APSInt APOffset(Offset.toAPSInt().extend(Bits + 2), /*IsUnsigend=*/false); + APSInt APIndex(APInt(Bits + 2, Index, /*IsSigned=*/true), + /*IsUnsigned=*/false); APSInt NewIndex = (Op == ArithOp::Add) ? (APIndex + APOffset) : (APIndex - APOffset); S.CCEDiag(S.Current->getSource(OpPC), diag::note_constexpr_array_index) @@ -1569,22 +1568,24 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset, }; if (Ptr.isBlockPointer()) { - T MaxOffset = T::from(MaxIndex - Index, Offset.bitWidth()); + uint64_t IOffset = static_cast(Offset); + uint64_t MaxOffset = MaxIndex - Index; + if constexpr (Op == ArithOp::Add) { // If the new offset would be negative, bail out. - if (Offset.isNegative() && (Offset.isMin() || -Offset > Index)) + if (Offset.isNegative() && (Offset.isMin() || -IOffset > Index)) DiagInvalidOffset(); // If the new offset would be out of bounds, bail out. - if (Offset.isPositive() && Offset > MaxOffset) + if (Offset.isPositive() && IOffset > MaxOffset) DiagInvalidOffset(); } else { // If the new offset would be negative, bail out. - if (Offset.isPositive() && Index < Offset) + if (Offset.isPositive() && Index < IOffset) DiagInvalidOffset(); // If the new offset would be out of bounds, bail out. - if (Offset.isNegative() && (Offset.isMin() || -Offset > MaxOffset)) + if (Offset.isNegative() && (Offset.isMin() || -IOffset > MaxOffset)) DiagInvalidOffset(); } } @@ -1601,7 +1602,7 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset, else Result = WideIndex - WideOffset; - S.Stk.push(Ptr.atIndex(static_cast(Result))); + S.Stk.push(Ptr.atIndex(static_cast(Result))); return true; } @@ -1832,6 +1833,32 @@ bool CastPointerIntegral(InterpState &S, CodePtr OpPC) { return true; } +static inline bool CastPointerIntegralAP(InterpState &S, CodePtr OpPC, + uint32_t BitWidth) { + const Pointer &Ptr = S.Stk.pop(); + + const SourceInfo &E = S.Current->getSource(OpPC); + S.CCEDiag(E, diag::note_constexpr_invalid_cast) + << 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC); + + S.Stk.push>( + IntegralAP::from(Ptr.getIntegerRepresentation(), BitWidth)); + return true; +} + +static inline bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC, + uint32_t BitWidth) { + const Pointer &Ptr = S.Stk.pop(); + + const SourceInfo &E = S.Current->getSource(OpPC); + S.CCEDiag(E, diag::note_constexpr_invalid_cast) + << 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC); + + S.Stk.push>( + IntegralAP::from(Ptr.getIntegerRepresentation(), BitWidth)); + return true; +} + //===----------------------------------------------------------------------===// // Zero, Nullptr //===----------------------------------------------------------------------===// @@ -2300,6 +2327,18 @@ inline bool InvalidDeclRef(InterpState &S, CodePtr OpPC, return CheckDeclRef(S, OpPC, DR); } +inline bool Assume(InterpState &S, CodePtr OpPC) { + const auto Val = S.Stk.pop(); + + if (Val) + return true; + + // Else, diagnose. + const SourceLocation &Loc = S.Current->getLocation(OpPC); + S.CCEDiag(Loc, diag::note_constexpr_assumption_failed); + return false; +} + template ::T> inline bool OffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E) { llvm::SmallVector ArrayIndices; diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp index f562f9e1cb19fb7770537d8cfe40df49dfe927d3..565c85bc2e0c218c8135b3cf68c0cc0af04eda7d 100644 --- a/clang/lib/AST/Interp/InterpBuiltin.cpp +++ b/clang/lib/AST/Interp/InterpBuiltin.cpp @@ -9,6 +9,7 @@ #include "Boolean.h" #include "Interp.h" #include "PrimType.h" +#include "clang/AST/OSLog.h" #include "clang/AST/RecordLayout.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/TargetInfo.h" @@ -1088,6 +1089,17 @@ static bool interp__builtin_is_aligned_up_down(InterpState &S, CodePtr OpPC, return false; } +static bool interp__builtin_os_log_format_buffer_size(InterpState &S, + CodePtr OpPC, + const InterpFrame *Frame, + const Function *Func, + const CallExpr *Call) { + analyze_os_log::OSLogBufferLayout Layout; + analyze_os_log::computeOSLogBufferLayout(S.getCtx(), Call, Layout); + pushInteger(S, Layout.size().getQuantity(), Call->getType()); + return true; +} + bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, const CallExpr *Call) { const InterpFrame *Frame = S.Current; @@ -1409,6 +1421,11 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, return false; break; + case Builtin::BI__builtin_os_log_format_buffer_size: + if (!interp__builtin_os_log_format_buffer_size(S, OpPC, Frame, F, Call)) + return false; + break; + default: S.FFDiag(S.Current->getLocation(OpPC), diag::note_invalid_subexpr_in_const_expr) diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td index e17be3afd25729a7f3a1b78fcb425af3d16ae1fa..742785b28eb4d7131cd862b0dbad87a5495e75be 100644 --- a/clang/lib/AST/Interp/Opcodes.td +++ b/clang/lib/AST/Interp/Opcodes.td @@ -664,10 +664,19 @@ def CastFloatingIntegralAPS : Opcode { } def CastPointerIntegral : Opcode { - let Types = [AluTypeClass]; - let Args = []; + let Types = [FixedSizeIntegralTypeClass]; let HasGroup = 1; } +def CastPointerIntegralAP : Opcode { + let Types = []; + let HasGroup = 0; + let Args = [ArgUint32]; +} +def CastPointerIntegralAPS : Opcode { + let Types = []; + let HasGroup = 0; + let Args = [ArgUint32]; +} def DecayPtr : Opcode { let Types = [PtrTypeClass, PtrTypeClass]; @@ -727,6 +736,8 @@ def InvalidDeclRef : Opcode { let Args = [ArgDeclRef]; } +def Assume : Opcode; + def ArrayDecay : Opcode; def CheckNonNullArg : Opcode { diff --git a/clang/lib/AST/Interp/Pointer.cpp b/clang/lib/AST/Interp/Pointer.cpp index e163e658d462b2d2020900e95d27798461c41f4c..5ef31671ae7be51c8d3caae38b9f633600576ede 100644 --- a/clang/lib/AST/Interp/Pointer.cpp +++ b/clang/lib/AST/Interp/Pointer.cpp @@ -23,7 +23,7 @@ Pointer::Pointer(Block *Pointee) : Pointer(Pointee, Pointee->getDescriptor()->getMetadataSize(), Pointee->getDescriptor()->getMetadataSize()) {} -Pointer::Pointer(Block *Pointee, unsigned BaseAndOffset) +Pointer::Pointer(Block *Pointee, uint64_t BaseAndOffset) : Pointer(Pointee, BaseAndOffset, BaseAndOffset) {} Pointer::Pointer(const Pointer &P) @@ -34,7 +34,7 @@ Pointer::Pointer(const Pointer &P) PointeeStorage.BS.Pointee->addPointer(this); } -Pointer::Pointer(Block *Pointee, unsigned Base, unsigned Offset) +Pointer::Pointer(Block *Pointee, unsigned Base, uint64_t Offset) : Offset(Offset), StorageKind(Storage::Block) { assert((Base == RootPtrMark || Base % alignof(void *) == 0) && "wrong base"); diff --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h index b4475577b74625bdb147ee22eb134aab2d7ac2e5..c4d701bc71b7bf58fde85730a47e74e26eecc5dc 100644 --- a/clang/lib/AST/Interp/Pointer.h +++ b/clang/lib/AST/Interp/Pointer.h @@ -89,10 +89,10 @@ public: PointeeStorage.Int.Desc = nullptr; } Pointer(Block *B); - Pointer(Block *B, unsigned BaseAndOffset); + Pointer(Block *B, uint64_t BaseAndOffset); Pointer(const Pointer &P); Pointer(Pointer &&P); - Pointer(uint64_t Address, const Descriptor *Desc, unsigned Offset = 0) + Pointer(uint64_t Address, const Descriptor *Desc, uint64_t Offset = 0) : Offset(Offset), StorageKind(Storage::Int) { PointeeStorage.Int.Value = Address; PointeeStorage.Int.Desc = Desc; @@ -134,14 +134,14 @@ public: std::optional toRValue(const Context &Ctx) const; /// Offsets a pointer inside an array. - [[nodiscard]] Pointer atIndex(unsigned Idx) const { + [[nodiscard]] Pointer atIndex(uint64_t Idx) const { if (isIntegralPointer()) return Pointer(asIntPointer().Value, asIntPointer().Desc, Idx); if (asBlockPointer().Base == RootPtrMark) return Pointer(asBlockPointer().Pointee, RootPtrMark, getDeclDesc()->getSize()); - unsigned Off = Idx * elemSize(); + uint64_t Off = Idx * elemSize(); if (getFieldDesc()->ElemDesc) Off += sizeof(InlineDescriptor); else @@ -630,7 +630,7 @@ private: friend class DeadBlock; friend struct InitMap; - Pointer(Block *Pointee, unsigned Base, unsigned Offset); + Pointer(Block *Pointee, unsigned Base, uint64_t Offset); /// Returns the embedded descriptor preceding a field. InlineDescriptor *getInlineDesc() const { @@ -656,7 +656,7 @@ private: } /// Offset into the storage. - unsigned Offset = 0; + uint64_t Offset = 0; /// Previous link in the pointer chain. Pointer *Prev = nullptr; diff --git a/clang/lib/AST/Interp/Program.cpp b/clang/lib/AST/Interp/Program.cpp index 2c8c6781b3483344f6f271c5b84c00993f44d1ff..3773e0662f784ce3b9f23224ee5150f5c1caaf73 100644 --- a/clang/lib/AST/Interp/Program.cpp +++ b/clang/lib/AST/Interp/Program.cpp @@ -108,27 +108,23 @@ Pointer Program::getPtrGlobal(unsigned Idx) const { } std::optional Program::getGlobal(const ValueDecl *VD) { - auto It = GlobalIndices.find(VD); - if (It != GlobalIndices.end()) + if (auto It = GlobalIndices.find(VD); It != GlobalIndices.end()) return It->second; // Find any previous declarations which were already evaluated. std::optional Index; - for (const Decl *P = VD; P; P = P->getPreviousDecl()) { - auto It = GlobalIndices.find(P); - if (It != GlobalIndices.end()) { + for (const Decl *P = VD->getPreviousDecl(); P; P = P->getPreviousDecl()) { + if (auto It = GlobalIndices.find(P); It != GlobalIndices.end()) { Index = It->second; break; } } // Map the decl to the existing index. - if (Index) { + if (Index) GlobalIndices[VD] = *Index; - return std::nullopt; - } - return Index; + return std::nullopt; } std::optional Program::getOrCreateGlobal(const ValueDecl *VD, @@ -173,7 +169,6 @@ std::optional Program::getOrCreateDummy(const ValueDecl *VD) { std::optional Program::createGlobal(const ValueDecl *VD, const Expr *Init) { - assert(!getGlobal(VD)); bool IsStatic, IsExtern; if (const auto *Var = dyn_cast(VD)) { IsStatic = Context::shouldBeGloballyIndexed(VD); diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index c3b98d2d2149cb589da0286d95f323b0b9e8783b..106c69dd5beed718256fc003af4caee51f475909 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -1062,26 +1062,23 @@ void CXXNameMangler::mangleNameWithAbiTags(GlobalDecl GD, // ::= // const DeclContext *DC = Context.getEffectiveDeclContext(ND); + bool IsLambda = isLambda(ND); // If this is an extern variable declared locally, the relevant DeclContext // is that of the containing namespace, or the translation unit. // FIXME: This is a hack; extern variables declared locally should have // a proper semantic declaration context! - if (isLocalContainerContext(DC) && ND->hasLinkage() && !isLambda(ND)) + if (isLocalContainerContext(DC) && ND->hasLinkage() && !IsLambda) while (!DC->isNamespace() && !DC->isTranslationUnit()) DC = Context.getEffectiveParentContext(DC); - else if (GetLocalClassDecl(ND)) { + else if (GetLocalClassDecl(ND) && + (!IsLambda || isCompatibleWith(LangOptions::ClangABI::Ver18))) { mangleLocalName(GD, AdditionalAbiTags); return; } assert(!isa(DC) && "context cannot be LinkageSpecDecl"); - if (isLocalContainerContext(DC)) { - mangleLocalName(GD, AdditionalAbiTags); - return; - } - // Closures can require a nested-name mangling even if they're semantically // in the global namespace. if (const NamedDecl *PrefixND = getClosurePrefix(ND)) { @@ -1089,6 +1086,11 @@ void CXXNameMangler::mangleNameWithAbiTags(GlobalDecl GD, return; } + if (isLocalContainerContext(DC)) { + mangleLocalName(GD, AdditionalAbiTags); + return; + } + if (DC->isTranslationUnit() || isStdNamespace(DC)) { // Check if we have a template. const TemplateArgumentList *TemplateArgs = nullptr; @@ -2201,8 +2203,6 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) { if (NoFunction && isLocalContainerContext(DC)) return; - assert(!isLocalContainerContext(DC)); - const NamedDecl *ND = cast(DC); if (mangleSubstitution(ND)) return; diff --git a/clang/lib/AST/OpenACCClause.cpp b/clang/lib/AST/OpenACCClause.cpp index 75334223e073c32feb9c65d657a429826c8e8438..6cd5b28802187de369e264ecb50f610fc16d98bc 100644 --- a/clang/lib/AST/OpenACCClause.cpp +++ b/clang/lib/AST/OpenACCClause.cpp @@ -124,6 +124,16 @@ OpenACCVectorLengthClause::Create(const ASTContext &C, SourceLocation BeginLoc, OpenACCVectorLengthClause(BeginLoc, LParenLoc, IntExpr, EndLoc); } +OpenACCNumGangsClause *OpenACCNumGangsClause::Create(const ASTContext &C, + SourceLocation BeginLoc, + SourceLocation LParenLoc, + ArrayRef IntExprs, + SourceLocation EndLoc) { + void *Mem = C.Allocate( + OpenACCNumGangsClause::totalSizeToAlloc(IntExprs.size())); + return new (Mem) OpenACCNumGangsClause(BeginLoc, LParenLoc, IntExprs, EndLoc); +} + //===----------------------------------------------------------------------===// // OpenACC clauses printing methods //===----------------------------------------------------------------------===// @@ -141,6 +151,12 @@ void OpenACCClausePrinter::VisitSelfClause(const OpenACCSelfClause &C) { OS << "(" << CondExpr << ")"; } +void OpenACCClausePrinter::VisitNumGangsClause(const OpenACCNumGangsClause &C) { + OS << "num_gangs("; + llvm::interleaveComma(C.getIntExprs(), OS); + OS << ")"; +} + void OpenACCClausePrinter::VisitNumWorkersClause( const OpenACCNumWorkersClause &C) { OS << "num_workers(" << C.getIntExpr() << ")"; diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 8138ae3a244a8baba6be68dac233308cd36fc46d..c81724f84dd9cee09aed44aa37b6819cd2d2b613 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -2497,6 +2497,12 @@ void OpenACCClauseProfiler::VisitSelfClause(const OpenACCSelfClause &Clause) { Profiler.VisitStmt(Clause.getConditionExpr()); } +void OpenACCClauseProfiler::VisitNumGangsClause( + const OpenACCNumGangsClause &Clause) { + for (auto *E : Clause.getIntExprs()) + Profiler.VisitStmt(E); +} + void OpenACCClauseProfiler::VisitNumWorkersClause( const OpenACCNumWorkersClause &Clause) { assert(Clause.hasIntExpr() && "num_workers clause requires a valid int expr"); diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index e5a8b285715b3096c45dd9cbf5211d7125108fce..8f0a9a9b0ed0bcd0659571935f450e59737b401e 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -399,6 +399,7 @@ void TextNodeDumper::Visit(const OpenACCClause *C) { break; case OpenACCClauseKind::If: case OpenACCClauseKind::Self: + case OpenACCClauseKind::NumGangs: case OpenACCClauseKind::NumWorkers: case OpenACCClauseKind::VectorLength: // The condition expression will be printed as a part of the 'children', diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/clang/lib/ASTMatchers/Dynamic/Marshallers.h index c76ddf17b719d4c1ee62177fba6d4a6eb3f0727d..0e640cbada726868b218e53333f46430c3d9ce1d 100644 --- a/clang/lib/ASTMatchers/Dynamic/Marshallers.h +++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.h @@ -937,7 +937,7 @@ class MapAnyOfMatcherDescriptor : public MatcherDescriptor { public: MapAnyOfMatcherDescriptor(ASTNodeKind CladeNodeKind, std::vector NodeKinds) - : CladeNodeKind(CladeNodeKind), NodeKinds(NodeKinds) {} + : CladeNodeKind(CladeNodeKind), NodeKinds(std::move(NodeKinds)) {} VariantMatcher create(SourceRange NameRange, ArrayRef Args, Diagnostics *Error) const override { @@ -1026,7 +1026,7 @@ public: } return std::make_unique(CladeNodeKind, - NodeKinds); + std::move(NodeKinds)); } bool isVariadic() const override { return true; } diff --git a/clang/lib/Analysis/FlowSensitive/ASTOps.cpp b/clang/lib/Analysis/FlowSensitive/ASTOps.cpp index 1982c6c9f383053dce6f20e69cdd6711e80781bd..619bf772bba5eec46215759e62e197176e2d7718 100644 --- a/clang/lib/Analysis/FlowSensitive/ASTOps.cpp +++ b/clang/lib/Analysis/FlowSensitive/ASTOps.cpp @@ -80,11 +80,12 @@ bool containsSameFields(const FieldSet &Fields, } /// Returns the fields of a `RecordDecl` that are initialized by an -/// `InitListExpr`, in the order in which they appear in -/// `InitListExpr::inits()`. -/// `Init->getType()` must be a record type. +/// `InitListExpr` or `CXXParenListInitExpr`, in the order in which they appear +/// in `InitListExpr::inits()` / `CXXParenListInitExpr::getInitExprs()`. +/// `InitList->getType()` must be a record type. +template static std::vector -getFieldsForInitListExpr(const InitListExpr *InitList) { +getFieldsForInitListExpr(const InitListT *InitList) { const RecordDecl *RD = InitList->getType()->getAsRecordDecl(); assert(RD != nullptr); @@ -105,19 +106,29 @@ getFieldsForInitListExpr(const InitListExpr *InitList) { return Fields; } -RecordInitListHelper::RecordInitListHelper(const InitListExpr *InitList) { - auto *RD = InitList->getType()->getAsCXXRecordDecl(); - assert(RD != nullptr); +RecordInitListHelper::RecordInitListHelper(const InitListExpr *InitList) + : RecordInitListHelper(InitList->getType(), + getFieldsForInitListExpr(InitList), + InitList->inits()) {} + +RecordInitListHelper::RecordInitListHelper( + const CXXParenListInitExpr *ParenInitList) + : RecordInitListHelper(ParenInitList->getType(), + getFieldsForInitListExpr(ParenInitList), + ParenInitList->getInitExprs()) {} - std::vector Fields = getFieldsForInitListExpr(InitList); - ArrayRef Inits = InitList->inits(); +RecordInitListHelper::RecordInitListHelper( + QualType Ty, std::vector Fields, + ArrayRef Inits) { + auto *RD = Ty->getAsCXXRecordDecl(); + assert(RD != nullptr); // Unions initialized with an empty initializer list need special treatment. // For structs/classes initialized with an empty initializer list, Clang // puts `ImplicitValueInitExpr`s in `InitListExpr::inits()`, but for unions, // it doesn't do this -- so we create an `ImplicitValueInitExpr` ourselves. SmallVector InitsForUnion; - if (InitList->getType()->isUnionType() && Inits.empty()) { + if (Ty->isUnionType() && Inits.empty()) { assert(Fields.size() == 1); ImplicitValueInitForUnion.emplace(Fields.front()->getType()); InitsForUnion.push_back(&*ImplicitValueInitForUnion); @@ -217,6 +228,10 @@ static void getReferencedDecls(const Stmt &S, ReferencedDecls &Referenced) { if (InitList->getType()->isRecordType()) for (const auto *FD : getFieldsForInitListExpr(InitList)) Referenced.Fields.insert(FD); + } else if (auto *ParenInitList = dyn_cast(&S)) { + if (ParenInitList->getType()->isRecordType()) + for (const auto *FD : getFieldsForInitListExpr(ParenInitList)) + Referenced.Fields.insert(FD); } } @@ -246,4 +261,10 @@ ReferencedDecls getReferencedDecls(const FunctionDecl &FD) { return Result; } +ReferencedDecls getReferencedDecls(const Stmt &S) { + ReferencedDecls Result; + getReferencedDecls(S, Result); + return Result; +} + } // namespace clang::dataflow diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index 3f1600d9ac5d8724494bc35ce9436160a5269d28..05395e07a7a68cc035a7ca281d21cfe1b05e0e9e 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -24,6 +24,7 @@ #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/Support/ErrorHandling.h" #include #include @@ -80,7 +81,6 @@ static bool equateUnknownValues(Value::Kind K) { switch (K) { case Value::Kind::Integer: case Value::Kind::Pointer: - case Value::Kind::Record: return true; default: return false; @@ -145,25 +145,7 @@ static Value *joinDistinctValues(QualType Type, Value &Val1, return &A.makeBoolValue(JoinedVal); } - Value *JoinedVal = nullptr; - if (auto *RecordVal1 = dyn_cast(&Val1)) { - auto *RecordVal2 = cast(&Val2); - - if (&RecordVal1->getLoc() == &RecordVal2->getLoc()) - // `RecordVal1` and `RecordVal2` may have different properties associated - // with them. Create a new `RecordValue` with the same location but - // without any properties so that we soundly approximate both values. If a - // particular analysis needs to join properties, it should do so in - // `DataflowAnalysis::join()`. - JoinedVal = &JoinedEnv.create(RecordVal1->getLoc()); - else - // If the locations for the two records are different, need to create a - // completely new value. - JoinedVal = JoinedEnv.createValue(Type); - } else { - JoinedVal = JoinedEnv.createValue(Type); - } - + Value *JoinedVal = JoinedEnv.createValue(Type); if (JoinedVal) Model.join(Type, Val1, Env1, Val2, Env2, *JoinedVal, JoinedEnv); @@ -401,6 +383,28 @@ public: return true; } + void + PropagateResultObjectToRecordInitList(const RecordInitListHelper &InitList, + RecordStorageLocation *Loc) { + for (auto [Base, Init] : InitList.base_inits()) { + assert(Base->getType().getCanonicalType() == + Init->getType().getCanonicalType()); + + // Storage location for the base class is the same as that of the + // derived class because we "flatten" the object hierarchy and put all + // fields in `RecordStorageLocation` of the derived class. + PropagateResultObject(Init, Loc); + } + + for (auto [Field, Init] : InitList.field_inits()) { + // Fields of non-record type are handled in + // `TransferVisitor::VisitInitListExpr()`. + if (Field->getType()->isRecordType()) + PropagateResultObject( + Init, cast(Loc->getChild(*Field))); + } + } + // Assigns `Loc` as the result object location of `E`, then propagates the // location to all lower-level prvalues that initialize the same object as // `E` (or one of its base classes or member variables). @@ -440,26 +444,14 @@ public: return; } - RecordInitListHelper InitListHelper(InitList); - - for (auto [Base, Init] : InitListHelper.base_inits()) { - assert(Base->getType().getCanonicalType() == - Init->getType().getCanonicalType()); - - // Storage location for the base class is the same as that of the - // derived class because we "flatten" the object hierarchy and put all - // fields in `RecordStorageLocation` of the derived class. - PropagateResultObject(Init, Loc); - } + PropagateResultObjectToRecordInitList(RecordInitListHelper(InitList), + Loc); + return; + } - for (auto [Field, Init] : InitListHelper.field_inits()) { - // Fields of non-record type are handled in - // `TransferVisitor::VisitInitListExpr()`. - if (!Field->getType()->isRecordType()) - continue; - PropagateResultObject( - Init, cast(Loc->getChild(*Field))); - } + if (auto *ParenInitList = dyn_cast(E)) { + PropagateResultObjectToRecordInitList(RecordInitListHelper(ParenInitList), + Loc); return; } @@ -555,7 +547,6 @@ void Environment::initialize() { auto &ThisLoc = cast(createStorageLocation(ThisPointeeType)); setThisPointeeStorageLocation(ThisLoc); - refreshRecordValue(ThisLoc, *this); // Initialize fields of `*this` with values, but only if we're not // analyzing a constructor; after all, it's the constructor's job to do // this (and we want to be able to test that). @@ -619,8 +610,8 @@ Environment Environment::pushCall(const CallExpr *Call) const { if (const auto *MethodCall = dyn_cast(Call)) { if (const Expr *Arg = MethodCall->getImplicitObjectArgument()) { if (!isa(Arg)) - Env.ThisPointeeLoc = - cast(getStorageLocation(*Arg)); + Env.ThisPointeeLoc = + cast(getStorageLocation(*Arg)); // Otherwise (when the argument is `this`), retain the current // environment's `ThisPointeeLoc`. } @@ -699,10 +690,6 @@ void Environment::popCall(const CXXConstructExpr *Call, // See also comment in `popCall(const CallExpr *, const Environment &)` above. this->LocToVal = std::move(CalleeEnv.LocToVal); this->FlowConditionToken = std::move(CalleeEnv.FlowConditionToken); - - if (Value *Val = CalleeEnv.getValue(*CalleeEnv.ThisPointeeLoc)) { - setValue(*Call, *Val); - } } bool Environment::equivalentTo(const Environment &Other, @@ -926,24 +913,23 @@ void Environment::initializeFieldsWithValues(RecordStorageLocation &Loc, } void Environment::setValue(const StorageLocation &Loc, Value &Val) { - assert(!isa(&Val) || &cast(&Val)->getLoc() == &Loc); - + // Records should not be associated with values. + assert(!isa(Loc)); LocToVal[&Loc] = &Val; } void Environment::setValue(const Expr &E, Value &Val) { const Expr &CanonE = ignoreCFGOmittedNodes(E); - if (auto *RecordVal = dyn_cast(&Val)) { - assert(&RecordVal->getLoc() == &getResultObjectLocation(CanonE)); - (void)RecordVal; - } - assert(CanonE.isPRValue()); + // Records should not be associated with values. + assert(!CanonE.getType()->isRecordType()); ExprToVal[&CanonE] = &Val; } Value *Environment::getValue(const StorageLocation &Loc) const { + // Records should not be associated with values. + assert(!isa(Loc)); return LocToVal.lookup(&Loc); } @@ -955,6 +941,9 @@ Value *Environment::getValue(const ValueDecl &D) const { } Value *Environment::getValue(const Expr &E) const { + // Records should not be associated with values. + assert(!E.getType()->isRecordType()); + if (E.isPRValue()) { auto It = ExprToVal.find(&ignoreCFGOmittedNodes(E)); return It == ExprToVal.end() ? nullptr : It->second; @@ -983,6 +972,7 @@ Value *Environment::createValueUnlessSelfReferential( int &CreatedValuesCount) { assert(!Type.isNull()); assert(!Type->isReferenceType()); + assert(!Type->isRecordType()); // Allow unlimited fields at depth 1; only cap at deeper nesting levels. if ((Depth > 1 && CreatedValuesCount > MaxCompositeValueSize) || @@ -1011,15 +1001,6 @@ Value *Environment::createValueUnlessSelfReferential( return &arena().create(PointeeLoc); } - if (Type->isRecordType()) { - CreatedValuesCount++; - auto &Loc = cast(createStorageLocation(Type)); - initializeFieldsWithValues(Loc, Loc.getType(), Visited, Depth, - CreatedValuesCount); - - return &refreshRecordValue(Loc, *this); - } - return nullptr; } @@ -1029,20 +1010,23 @@ Environment::createLocAndMaybeValue(QualType Ty, int Depth, int &CreatedValuesCount) { if (!Visited.insert(Ty.getCanonicalType()).second) return createStorageLocation(Ty.getNonReferenceType()); - Value *Val = createValueUnlessSelfReferential( - Ty.getNonReferenceType(), Visited, Depth, CreatedValuesCount); - Visited.erase(Ty.getCanonicalType()); + auto EraseVisited = llvm::make_scope_exit( + [&Visited, Ty] { Visited.erase(Ty.getCanonicalType()); }); Ty = Ty.getNonReferenceType(); - if (Val == nullptr) - return createStorageLocation(Ty); - - if (Ty->isRecordType()) - return cast(Val)->getLoc(); + if (Ty->isRecordType()) { + auto &Loc = cast(createStorageLocation(Ty)); + initializeFieldsWithValues(Loc, Ty, Visited, Depth, CreatedValuesCount); + return Loc; + } StorageLocation &Loc = createStorageLocation(Ty); - setValue(Loc, *Val); + + if (Value *Val = createValueUnlessSelfReferential(Ty, Visited, Depth, + CreatedValuesCount)) + setValue(Loc, *Val); + return Loc; } @@ -1054,10 +1038,11 @@ void Environment::initializeFieldsWithValues(RecordStorageLocation &Loc, auto initField = [&](QualType FieldType, StorageLocation &FieldLoc) { if (FieldType->isRecordType()) { auto &FieldRecordLoc = cast(FieldLoc); - setValue(FieldRecordLoc, create(FieldRecordLoc)); initializeFieldsWithValues(FieldRecordLoc, FieldRecordLoc.getType(), Visited, Depth + 1, CreatedValuesCount); } else { + if (getValue(FieldLoc) != nullptr) + return; if (!Visited.insert(FieldType.getCanonicalType()).second) return; if (Value *Val = createValueUnlessSelfReferential( @@ -1098,7 +1083,7 @@ StorageLocation &Environment::createObjectInternal(const ValueDecl *D, // be null. if (InitExpr) { if (auto *InitExprLoc = getStorageLocation(*InitExpr)) - return *InitExprLoc; + return *InitExprLoc; } // Even though we have an initializer, we might not get an @@ -1115,7 +1100,6 @@ StorageLocation &Environment::createObjectInternal(const ValueDecl *D, auto &RecordLoc = cast(Loc); if (!InitExpr) initializeFieldsWithValues(RecordLoc); - refreshRecordValue(RecordLoc, *this); } else { Value *Val = nullptr; if (InitExpr) @@ -1207,9 +1191,7 @@ void Environment::dump(raw_ostream &OS) const { DACtx->dumpFlowCondition(FlowConditionToken, OS); } -void Environment::dump() const { - dump(llvm::dbgs()); -} +void Environment::dump() const { dump(llvm::dbgs()); } Environment::PrValueToResultObject Environment::buildResultObjectMap( DataflowAnalysisContext *DACtx, const FunctionDecl *FuncDecl, @@ -1254,25 +1236,5 @@ RecordStorageLocation *getBaseObjectLocation(const MemberExpr &ME, return Env.get(*Base); } -RecordValue &refreshRecordValue(RecordStorageLocation &Loc, Environment &Env) { - auto &NewVal = Env.create(Loc); - Env.setValue(Loc, NewVal); - return NewVal; -} - -RecordValue &refreshRecordValue(const Expr &Expr, Environment &Env) { - assert(Expr.getType()->isRecordType()); - - if (Expr.isPRValue()) - refreshRecordValue(Env.getResultObjectLocation(Expr), Env); - - if (auto *Loc = Env.get(Expr)) - refreshRecordValue(*Loc, Env); - - auto &NewVal = *cast(Env.createValue(Expr.getType())); - Env.setStorageLocation(Expr, NewVal.getLoc()); - return NewVal; -} - } // namespace dataflow } // namespace clang diff --git a/clang/lib/Analysis/FlowSensitive/DebugSupport.cpp b/clang/lib/Analysis/FlowSensitive/DebugSupport.cpp index 573c4b1d474bf474a0fe699222927de0bdf57eb9..d40aab7a7f10359e3bed23793d7298294f1ca00c 100644 --- a/clang/lib/Analysis/FlowSensitive/DebugSupport.cpp +++ b/clang/lib/Analysis/FlowSensitive/DebugSupport.cpp @@ -28,8 +28,6 @@ llvm::StringRef debugString(Value::Kind Kind) { return "Integer"; case Value::Kind::Pointer: return "Pointer"; - case Value::Kind::Record: - return "Record"; case Value::Kind::AtomicBool: return "AtomicBool"; case Value::Kind::TopBool: diff --git a/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp b/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp index 397a8d87e114d7a90214f4bad99fb307ee605d3b..a36cb41a63dfb152527e01f163e47b2f662ba7c6 100644 --- a/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp +++ b/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp @@ -95,7 +95,6 @@ public: switch (V.getKind()) { case Value::Kind::Integer: - case Value::Kind::Record: case Value::Kind::TopBool: case Value::Kind::AtomicBool: case Value::Kind::FormulaBool: @@ -126,8 +125,9 @@ public: return; JOS.attribute("type", L.getType().getAsString()); - if (auto *V = Env.getValue(L)) - dump(*V); + if (!L.getType()->isRecordType()) + if (auto *V = Env.getValue(L)) + dump(*V); if (auto *RLoc = dyn_cast(&L)) { for (const auto &Child : RLoc->children()) @@ -281,9 +281,10 @@ public: Iters.back().Block->Elements[ElementIndex - 1].getAs(); if (const Expr *E = S ? llvm::dyn_cast(S->getStmt()) : nullptr) { if (E->isPRValue()) { - if (auto *V = State.Env.getValue(*E)) - JOS.attributeObject( - "value", [&] { ModelDumper(JOS, State.Env).dump(*V); }); + if (!E->getType()->isRecordType()) + if (auto *V = State.Env.getValue(*E)) + JOS.attributeObject( + "value", [&] { ModelDumper(JOS, State.Env).dump(*V); }); } else { if (auto *Loc = State.Env.getStorageLocation(*E)) JOS.attributeObject( diff --git a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp index cadb1ceb2d850733829a9d18e1a0ddef67e80946..0707aa662e4cc2756135742cb17e4a2509ff3173 100644 --- a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp +++ b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp @@ -339,17 +339,6 @@ void setHasValue(RecordStorageLocation &OptionalLoc, BoolValue &HasValueVal, Env.setValue(locForHasValue(OptionalLoc), HasValueVal); } -/// Creates a symbolic value for an `optional` value at an existing storage -/// location. Uses `HasValueVal` as the symbolic value of the "has_value" -/// property. -RecordValue &createOptionalValue(RecordStorageLocation &Loc, - BoolValue &HasValueVal, Environment &Env) { - auto &OptionalVal = Env.create(Loc); - Env.setValue(Loc, OptionalVal); - setHasValue(Loc, HasValueVal, Env); - return OptionalVal; -} - /// Returns the symbolic value that represents the "has_value" property of the /// optional at `OptionalLoc`. Returns null if `OptionalLoc` is null. BoolValue *getHasValue(Environment &Env, RecordStorageLocation *OptionalLoc) { @@ -413,9 +402,8 @@ void transferArrowOpCall(const Expr *UnwrapExpr, const Expr *ObjectExpr, void transferMakeOptionalCall(const CallExpr *E, const MatchFinder::MatchResult &, LatticeTransferState &State) { - State.Env.setValue( - *E, createOptionalValue(State.Env.getResultObjectLocation(*E), - State.Env.getBoolLiteralValue(true), State.Env)); + setHasValue(State.Env.getResultObjectLocation(*E), + State.Env.getBoolLiteralValue(true), State.Env); } void transferOptionalHasValueCall(const CXXMemberCallExpr *CallExpr, @@ -483,9 +471,6 @@ void transferValueOrNotEqX(const Expr *ComparisonExpr, void transferCallReturningOptional(const CallExpr *E, const MatchFinder::MatchResult &Result, LatticeTransferState &State) { - if (State.Env.getValue(*E) != nullptr) - return; - RecordStorageLocation *Loc = nullptr; if (E->isPRValue()) { Loc = &State.Env.getResultObjectLocation(*E); @@ -497,16 +482,16 @@ void transferCallReturningOptional(const CallExpr *E, } } - RecordValue &Val = - createOptionalValue(*Loc, State.Env.makeAtomicBoolValue(), State.Env); - if (E->isPRValue()) - State.Env.setValue(*E, Val); + if (State.Env.getValue(locForHasValue(*Loc)) != nullptr) + return; + + setHasValue(*Loc, State.Env.makeAtomicBoolValue(), State.Env); } void constructOptionalValue(const Expr &E, Environment &Env, BoolValue &HasValueVal) { RecordStorageLocation &Loc = Env.getResultObjectLocation(E); - Env.setValue(E, createOptionalValue(Loc, HasValueVal, Env)); + setHasValue(Loc, HasValueVal, Env); } /// Returns a symbolic value for the "has_value" property of an `optional` @@ -555,7 +540,7 @@ void transferAssignment(const CXXOperatorCallExpr *E, BoolValue &HasValueVal, assert(E->getNumArgs() > 0); if (auto *Loc = State.Env.get(*E->getArg(0))) { - createOptionalValue(*Loc, HasValueVal, State.Env); + setHasValue(*Loc, HasValueVal, State.Env); // Assign a storage location for the whole expression. State.Env.setStorageLocation(*E, *Loc); @@ -587,11 +572,11 @@ void transferSwap(RecordStorageLocation *Loc1, RecordStorageLocation *Loc2, if (Loc1 == nullptr) { if (Loc2 != nullptr) - createOptionalValue(*Loc2, Env.makeAtomicBoolValue(), Env); + setHasValue(*Loc2, Env.makeAtomicBoolValue(), Env); return; } if (Loc2 == nullptr) { - createOptionalValue(*Loc1, Env.makeAtomicBoolValue(), Env); + setHasValue(*Loc1, Env.makeAtomicBoolValue(), Env); return; } @@ -609,8 +594,8 @@ void transferSwap(RecordStorageLocation *Loc1, RecordStorageLocation *Loc2, if (BoolVal2 == nullptr) BoolVal2 = &Env.makeAtomicBoolValue(); - createOptionalValue(*Loc1, *BoolVal2, Env); - createOptionalValue(*Loc2, *BoolVal1, Env); + setHasValue(*Loc1, *BoolVal2, Env); + setHasValue(*Loc2, *BoolVal1, Env); } void transferSwapCall(const CXXMemberCallExpr *E, @@ -806,8 +791,7 @@ auto buildTransferMatchSwitch() { LatticeTransferState &State) { if (RecordStorageLocation *Loc = getImplicitObjectLocation(*E, State.Env)) { - createOptionalValue(*Loc, State.Env.getBoolLiteralValue(true), - State.Env); + setHasValue(*Loc, State.Env.getBoolLiteralValue(true), State.Env); } }) @@ -818,8 +802,8 @@ auto buildTransferMatchSwitch() { LatticeTransferState &State) { if (RecordStorageLocation *Loc = getImplicitObjectLocation(*E, State.Env)) { - createOptionalValue(*Loc, State.Env.getBoolLiteralValue(false), - State.Env); + setHasValue(*Loc, State.Env.getBoolLiteralValue(false), + State.Env); } }) diff --git a/clang/lib/Analysis/FlowSensitive/RecordOps.cpp b/clang/lib/Analysis/FlowSensitive/RecordOps.cpp index 2f0b0e5c5640c342710762b5794e186ae72d8f12..b8401230a83d4370b2ee47e42e2f64913bd7673d 100644 --- a/clang/lib/Analysis/FlowSensitive/RecordOps.cpp +++ b/clang/lib/Analysis/FlowSensitive/RecordOps.cpp @@ -83,9 +83,6 @@ void copyRecord(RecordStorageLocation &Src, RecordStorageLocation &Dst, copySyntheticField(SrcFieldLoc->getType(), *SrcFieldLoc, Dst.getSyntheticField(Name), Env); } - - RecordValue *DstVal = &Env.create(Dst); - Env.setValue(Dst, *DstVal); } bool recordsEqual(const RecordStorageLocation &Loc1, const Environment &Env1, diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp index 1e034771014eaaa760a1ca516f5fa56ad6fecf1d..2771c8b2e37ebb7e114f60de6b2ea47370504828 100644 --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -96,6 +96,8 @@ static Value *maybeUnpackLValueExpr(const Expr &E, Environment &Env) { } static void propagateValue(const Expr &From, const Expr &To, Environment &Env) { + if (From.getType()->isRecordType()) + return; if (auto *Val = Env.getValue(From)) Env.setValue(To, *Val); } @@ -403,6 +405,9 @@ public: return; if (Ret->isPRValue()) { + if (Ret->getType()->isRecordType()) + return; + auto *Val = Env.getValue(*Ret); if (Val == nullptr) return; @@ -457,15 +462,9 @@ public: assert(ArgExpr != nullptr); propagateValueOrStorageLocation(*ArgExpr, *S, Env); - // If this is a prvalue of record type, we consider it to be an "original - // record constructor", which we always require to have a `RecordValue`. - // So make sure we have a value if we didn't propagate one above. if (S->isPRValue() && S->getType()->isRecordType()) { - if (Env.getValue(*S) == nullptr) { - auto &Loc = Env.getResultObjectLocation(*S); - Env.initializeFieldsWithValues(Loc); - refreshRecordValue(Loc, Env); - } + auto &Loc = Env.getResultObjectLocation(*S); + Env.initializeFieldsWithValues(Loc); } } @@ -495,7 +494,6 @@ public: } RecordStorageLocation &Loc = Env.getResultObjectLocation(*S); - Env.setValue(*S, refreshRecordValue(Loc, Env)); if (ConstructorDecl->isCopyOrMoveConstructor()) { // It is permissible for a copy/move constructor to have additional @@ -542,8 +540,7 @@ public: RecordStorageLocation *LocSrc = nullptr; if (Arg1->isPRValue()) { - if (auto *Val = Env.get(*Arg1)) - LocSrc = &Val->getLoc(); + LocSrc = &Env.getResultObjectLocation(*Arg1); } else { LocSrc = Env.get(*Arg1); } @@ -575,15 +572,6 @@ public: propagateValue(*RBO->getSemanticForm(), *RBO, Env); } - void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *S) { - if (S->getCastKind() == CK_ConstructorConversion) { - const Expr *SubExpr = S->getSubExpr(); - assert(SubExpr != nullptr); - - propagateValue(*SubExpr, *S, Env); - } - } - void VisitCallExpr(const CallExpr *S) { // Of clang's builtins, only `__builtin_expect` is handled explicitly, since // others (like trap, debugtrap, and unreachable) are handled by CFG @@ -613,12 +601,10 @@ public: // If this call produces a prvalue of record type, initialize its fields // with values. - if (S->getType()->isRecordType() && S->isPRValue()) - if (Env.getValue(*S) == nullptr) { - RecordStorageLocation &Loc = Env.getResultObjectLocation(*S); - Env.initializeFieldsWithValues(Loc); - Env.setValue(*S, refreshRecordValue(Loc, Env)); - } + if (S->getType()->isRecordType() && S->isPRValue()) { + RecordStorageLocation &Loc = Env.getResultObjectLocation(*S); + Env.initializeFieldsWithValues(Loc); + } } } @@ -626,18 +612,16 @@ public: const Expr *SubExpr = S->getSubExpr(); assert(SubExpr != nullptr); - Value *SubExprVal = Env.getValue(*SubExpr); - if (SubExprVal == nullptr) - return; + StorageLocation &Loc = Env.createStorageLocation(*S); + Env.setStorageLocation(*S, Loc); - if (RecordValue *RecordVal = dyn_cast(SubExprVal)) { - Env.setStorageLocation(*S, RecordVal->getLoc()); + if (SubExpr->getType()->isRecordType()) + // Nothing else left to do -- we initialized the record when transferring + // `SubExpr`. return; - } - StorageLocation &Loc = Env.createStorageLocation(*S); - Env.setValue(Loc, *SubExprVal); - Env.setStorageLocation(*S, Loc); + if (Value *SubExprVal = Env.getValue(*SubExpr)) + Env.setValue(Loc, *SubExprVal); } void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *S) { @@ -683,15 +667,11 @@ public: return; } - // In case the initializer list is transparent, we just need to propagate - // the value that it contains. - if (S->isSemanticForm() && S->isTransparent()) { - propagateValue(*S->getInit(0), *S, Env); + // If the initializer list is transparent, there's nothing to do. + if (S->isSemanticForm() && S->isTransparent()) return; - } RecordStorageLocation &Loc = Env.getResultObjectLocation(*S); - Env.setValue(*S, refreshRecordValue(Loc, Env)); // Initialization of base classes and fields of record type happens when we // visit the nested `CXXConstructExpr` or `InitListExpr` for that base class diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp index 1b73c5d6830161070d66fa4c76614e4ab90d82a1..71d5c1a6c4f4a36fc818474c57bb568108b354d4 100644 --- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp +++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp @@ -367,11 +367,11 @@ builtinTransferInitializer(const CFGInitializer &Elt, return; ParentLoc->setChild(*Member, InitExprLoc); - } else if (auto *InitExprVal = Env.getValue(*InitExpr)) { - assert(MemberLoc != nullptr); // Record-type initializers construct themselves directly into the result // object, so there is no need to handle them here. - if (!Member->getType()->isRecordType()) + } else if (!Member->getType()->isRecordType()) { + assert(MemberLoc != nullptr); + if (auto *InitExprVal = Env.getValue(*InitExpr)) Env.setValue(*MemberLoc, *InitExprVal); } } diff --git a/clang/lib/Analysis/FlowSensitive/Value.cpp b/clang/lib/Analysis/FlowSensitive/Value.cpp index 7fad6deb0e918fa4a5b1e5a5fed5b4dec9bed3ad..d70e5a82ea2327e8d6f02bcf352a703426647509 100644 --- a/clang/lib/Analysis/FlowSensitive/Value.cpp +++ b/clang/lib/Analysis/FlowSensitive/Value.cpp @@ -46,8 +46,6 @@ raw_ostream &operator<<(raw_ostream &OS, const Value &Val) { return OS << "Integer(@" << &Val << ")"; case Value::Kind::Pointer: return OS << "Pointer(" << &cast(Val).getPointeeLoc() << ")"; - case Value::Kind::Record: - return OS << "Record(" << &cast(Val).getLoc() << ")"; case Value::Kind::TopBool: return OS << "TopBool(" << cast(Val).getAtom() << ")"; case Value::Kind::AtomicBool: diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp index 1e4d48e13c025f467a62bdc92281c65830347c15..eb627a3c043bc567e6dd82501182e0c573bbfa10 100644 --- a/clang/lib/CodeGen/ABIInfoImpl.cpp +++ b/clang/lib/CodeGen/ABIInfoImpl.cpp @@ -157,7 +157,7 @@ llvm::Value *CodeGen::emitRoundPointerUpToAlignment(CodeGenFunction &CGF, llvm::Value *RoundUp = CGF.Builder.CreateConstInBoundsGEP1_32( CGF.Builder.getInt8Ty(), Ptr, Align.getQuantity() - 1); return CGF.Builder.CreateIntrinsic( - llvm::Intrinsic::ptrmask, {CGF.AllocaInt8PtrTy, CGF.IntPtrTy}, + llvm::Intrinsic::ptrmask, {Ptr->getType(), CGF.IntPtrTy}, {RoundUp, llvm::ConstantInt::get(CGF.IntPtrTy, -Align.getQuantity())}, nullptr, Ptr->getName() + ".aligned"); } diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 6cc00b85664f411f860d40d10d049ce99a37a8cb..22c3f8642ad8ebc28a8f4dc5a119d131478f7bd2 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -104,6 +104,21 @@ static cl::opt ClSanitizeOnOptimizerEarlyEP( "sanitizer-early-opt-ep", cl::Optional, cl::desc("Insert sanitizers on OptimizerEarlyEP.")); +// Experiment to mark cold functions as optsize/minsize/optnone. +// TODO: remove once this is exposed as a proper driver flag. +static cl::opt ClPGOColdFuncAttr( + "pgo-cold-func-opt", cl::init(PGOOptions::ColdFuncOpt::Default), cl::Hidden, + cl::desc( + "Function attribute to apply to cold functions as determined by PGO"), + cl::values(clEnumValN(PGOOptions::ColdFuncOpt::Default, "default", + "Default (no attribute)"), + clEnumValN(PGOOptions::ColdFuncOpt::OptSize, "optsize", + "Mark cold functions with optsize."), + clEnumValN(PGOOptions::ColdFuncOpt::MinSize, "minsize", + "Mark cold functions with minsize."), + clEnumValN(PGOOptions::ColdFuncOpt::OptNone, "optnone", + "Mark cold functions with optnone."))); + extern cl::opt ProfileCorrelate; // Re-link builtin bitcodes after optimization @@ -768,42 +783,41 @@ void EmitAssemblyHelper::RunOptimizationPipeline( CodeGenOpts.InstrProfileOutput.empty() ? getDefaultProfileGenName() : CodeGenOpts.InstrProfileOutput, "", "", CodeGenOpts.MemoryProfileUsePath, nullptr, PGOOptions::IRInstr, - PGOOptions::NoCSAction, PGOOptions::ColdFuncOpt::Default, + PGOOptions::NoCSAction, ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling, /*PseudoProbeForProfiling=*/false, CodeGenOpts.AtomicProfileUpdate); else if (CodeGenOpts.hasProfileIRUse()) { // -fprofile-use. auto CSAction = CodeGenOpts.hasProfileCSIRUse() ? PGOOptions::CSIRUse : PGOOptions::NoCSAction; - PGOOpt = PGOOptions( - CodeGenOpts.ProfileInstrumentUsePath, "", - CodeGenOpts.ProfileRemappingFile, CodeGenOpts.MemoryProfileUsePath, VFS, - PGOOptions::IRUse, CSAction, PGOOptions::ColdFuncOpt::Default, - CodeGenOpts.DebugInfoForProfiling); + PGOOpt = PGOOptions(CodeGenOpts.ProfileInstrumentUsePath, "", + CodeGenOpts.ProfileRemappingFile, + CodeGenOpts.MemoryProfileUsePath, VFS, + PGOOptions::IRUse, CSAction, ClPGOColdFuncAttr, + CodeGenOpts.DebugInfoForProfiling); } else if (!CodeGenOpts.SampleProfileFile.empty()) // -fprofile-sample-use PGOOpt = PGOOptions( CodeGenOpts.SampleProfileFile, "", CodeGenOpts.ProfileRemappingFile, CodeGenOpts.MemoryProfileUsePath, VFS, PGOOptions::SampleUse, - PGOOptions::NoCSAction, PGOOptions::ColdFuncOpt::Default, + PGOOptions::NoCSAction, ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling, CodeGenOpts.PseudoProbeForProfiling); else if (!CodeGenOpts.MemoryProfileUsePath.empty()) // -fmemory-profile-use (without any of the above options) PGOOpt = PGOOptions("", "", "", CodeGenOpts.MemoryProfileUsePath, VFS, PGOOptions::NoAction, PGOOptions::NoCSAction, - PGOOptions::ColdFuncOpt::Default, - CodeGenOpts.DebugInfoForProfiling); + ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling); else if (CodeGenOpts.PseudoProbeForProfiling) // -fpseudo-probe-for-profiling - PGOOpt = PGOOptions("", "", "", /*MemoryProfile=*/"", nullptr, - PGOOptions::NoAction, PGOOptions::NoCSAction, - PGOOptions::ColdFuncOpt::Default, - CodeGenOpts.DebugInfoForProfiling, true); + PGOOpt = + PGOOptions("", "", "", /*MemoryProfile=*/"", nullptr, + PGOOptions::NoAction, PGOOptions::NoCSAction, + ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling, true); else if (CodeGenOpts.DebugInfoForProfiling) // -fdebug-info-for-profiling PGOOpt = PGOOptions("", "", "", /*MemoryProfile=*/"", nullptr, PGOOptions::NoAction, PGOOptions::NoCSAction, - PGOOptions::ColdFuncOpt::Default, true); + ClPGOColdFuncAttr, true); // Check to see if we want to generate a CS profile. if (CodeGenOpts.hasProfileCSIRInstr()) { @@ -820,14 +834,13 @@ void EmitAssemblyHelper::RunOptimizationPipeline( : CodeGenOpts.InstrProfileOutput; PGOOpt->CSAction = PGOOptions::CSIRInstr; } else - PGOOpt = - PGOOptions("", - CodeGenOpts.InstrProfileOutput.empty() - ? getDefaultProfileGenName() - : CodeGenOpts.InstrProfileOutput, - "", /*MemoryProfile=*/"", nullptr, PGOOptions::NoAction, - PGOOptions::CSIRInstr, PGOOptions::ColdFuncOpt::Default, - CodeGenOpts.DebugInfoForProfiling); + PGOOpt = PGOOptions("", + CodeGenOpts.InstrProfileOutput.empty() + ? getDefaultProfileGenName() + : CodeGenOpts.InstrProfileOutput, + "", /*MemoryProfile=*/"", nullptr, + PGOOptions::NoAction, PGOOptions::CSIRInstr, + ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling); } if (TM) TM->setPGOOption(PGOOpt); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index a05874e63c73c202c87cea797b311dac72b7b24a..7e5f2edfc732cce0c7d0cc309f94b69b71a61a76 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -826,29 +826,32 @@ const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberField( ASTContext &Ctx, const RecordDecl *RD, StringRef Name, uint64_t &Offset) { const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel = getLangOpts().getStrictFlexArraysLevel(); - unsigned FieldNo = 0; - bool IsUnion = RD->isUnion(); + uint32_t FieldNo = 0; - for (const Decl *D : RD->decls()) { - if (const auto *Field = dyn_cast(D); - Field && (Name.empty() || Field->getNameAsString() == Name) && + if (RD->isImplicit()) + return nullptr; + + for (const FieldDecl *FD : RD->fields()) { + if ((Name.empty() || FD->getNameAsString() == Name) && Decl::isFlexibleArrayMemberLike( - Ctx, Field, Field->getType(), StrictFlexArraysLevel, + Ctx, FD, FD->getType(), StrictFlexArraysLevel, /*IgnoreTemplateOrMacroSubstitution=*/true)) { const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); Offset += Layout.getFieldOffset(FieldNo); - return Field; + return FD; } - if (const auto *Record = dyn_cast(D)) - if (const FieldDecl *Field = - FindFlexibleArrayMemberField(Ctx, Record, Name, Offset)) { + QualType Ty = FD->getType(); + if (Ty->isRecordType()) { + if (const FieldDecl *Field = FindFlexibleArrayMemberField( + Ctx, Ty->getAsRecordDecl(), Name, Offset)) { const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); Offset += Layout.getFieldOffset(FieldNo); return Field; } + } - if (!IsUnion && isa(D)) + if (!RD->isUnion()) ++FieldNo; } @@ -858,14 +861,13 @@ const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberField( static unsigned CountCountedByAttrs(const RecordDecl *RD) { unsigned Num = 0; - for (const Decl *D : RD->decls()) { - if (const auto *FD = dyn_cast(D); - FD && FD->getType()->isCountAttributedType()) { + for (const FieldDecl *FD : RD->fields()) { + if (FD->getType()->isCountAttributedType()) return ++Num; - } - if (const auto *Rec = dyn_cast(D)) - Num += CountCountedByAttrs(Rec); + QualType Ty = FD->getType(); + if (Ty->isRecordType()) + Num += CountCountedByAttrs(Ty->getAsRecordDecl()); } return Num; @@ -18265,8 +18267,8 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, if (!E->getArg(0)->getType()->hasFloatingRepresentation()) llvm_unreachable("lerp operand must have a float representation"); return Builder.CreateIntrinsic( - /*ReturnType=*/X->getType(), Intrinsic::dx_lerp, - ArrayRef{X, Y, S}, nullptr, "dx.lerp"); + /*ReturnType=*/X->getType(), CGM.getHLSLRuntime().getLerpIntrinsic(), + ArrayRef{X, Y, S}, nullptr, "hlsl.lerp"); } case Builtin::BI__builtin_hlsl_elementwise_frac: { Value *Op0 = EmitScalarExpr(E->getArg(0)); @@ -18294,20 +18296,28 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *M = EmitScalarExpr(E->getArg(0)); Value *A = EmitScalarExpr(E->getArg(1)); Value *B = EmitScalarExpr(E->getArg(2)); - if (E->getArg(0)->getType()->hasFloatingRepresentation()) { + if (E->getArg(0)->getType()->hasFloatingRepresentation()) return Builder.CreateIntrinsic( /*ReturnType*/ M->getType(), Intrinsic::fmuladd, - ArrayRef{M, A, B}, nullptr, "dx.fmad"); - } + ArrayRef{M, A, B}, nullptr, "hlsl.fmad"); + if (E->getArg(0)->getType()->hasSignedIntegerRepresentation()) { - return Builder.CreateIntrinsic( - /*ReturnType*/ M->getType(), Intrinsic::dx_imad, - ArrayRef{M, A, B}, nullptr, "dx.imad"); + if (CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil) + return Builder.CreateIntrinsic( + /*ReturnType*/ M->getType(), Intrinsic::dx_imad, + ArrayRef{M, A, B}, nullptr, "dx.imad"); + + Value *Mul = Builder.CreateNSWMul(M, A); + return Builder.CreateNSWAdd(Mul, B); } assert(E->getArg(0)->getType()->hasUnsignedIntegerRepresentation()); - return Builder.CreateIntrinsic( - /*ReturnType=*/M->getType(), Intrinsic::dx_umad, - ArrayRef{M, A, B}, nullptr, "dx.umad"); + if (CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil) + return Builder.CreateIntrinsic( + /*ReturnType=*/M->getType(), Intrinsic::dx_umad, + ArrayRef{M, A, B}, nullptr, "dx.umad"); + + Value *Mul = Builder.CreateNUWMul(M, A); + return Builder.CreateNUWAdd(Mul, B); } case Builtin::BI__builtin_hlsl_elementwise_rcp: { Value *Op0 = EmitScalarExpr(E->getArg(0)); diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 1f18e0d5ba409a88b3e51b098219685d7a5fc8cb..40a5cd20c3d715a343f1e44866000641be07d5c4 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -147,6 +147,15 @@ struct BinOpInfo { return UnOp->getSubExpr()->getType()->isFixedPointType(); return false; } + + /// Check if the RHS has a signed integer representation. + bool rhsHasSignedIntegerRepresentation() const { + if (const auto *BinOp = dyn_cast(E)) { + QualType RHSType = BinOp->getRHS()->getType(); + return RHSType->hasSignedIntegerRepresentation(); + } + return false; + } }; static bool MustVisitNullValue(const Expr *E) { @@ -782,7 +791,7 @@ public: void EmitUndefinedBehaviorIntegerDivAndRemCheck(const BinOpInfo &Ops, llvm::Value *Zero,bool isDiv); // Common helper for getting how wide LHS of shift is. - static Value *GetMaximumShiftAmount(Value *LHS, Value *RHS); + static Value *GetMaximumShiftAmount(Value *LHS, Value *RHS, bool RHSIsSigned); // Used for shifting constraints for OpenCL, do mask for powers of 2, URem for // non powers of two. @@ -1531,7 +1540,7 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType, if (auto DstPT = dyn_cast(DstTy)) { // The source value may be an integer, or a pointer. if (isa(SrcTy)) - return Builder.CreateBitCast(Src, DstTy, "conv"); + return Src; assert(SrcType->isIntegerType() && "Not ptr->ptr or int->ptr conversion?"); // First, convert to the correct width so that we control the kind of @@ -4344,7 +4353,8 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) { return Builder.CreateExactSDiv(diffInChars, divisor, "sub.ptr.div"); } -Value *ScalarExprEmitter::GetMaximumShiftAmount(Value *LHS, Value *RHS) { +Value *ScalarExprEmitter::GetMaximumShiftAmount(Value *LHS, Value *RHS, + bool RHSIsSigned) { llvm::IntegerType *Ty; if (llvm::VectorType *VT = dyn_cast(LHS->getType())) Ty = cast(VT->getElementType()); @@ -4355,7 +4365,9 @@ Value *ScalarExprEmitter::GetMaximumShiftAmount(Value *LHS, Value *RHS) { // this in ConstantInt::get, this results in the value getting truncated. // Constrain the return value to be max(RHS) in this case. llvm::Type *RHSTy = RHS->getType(); - llvm::APInt RHSMax = llvm::APInt::getMaxValue(RHSTy->getScalarSizeInBits()); + llvm::APInt RHSMax = + RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits()) + : llvm::APInt::getMaxValue(RHSTy->getScalarSizeInBits()); if (RHSMax.ult(Ty->getBitWidth())) return llvm::ConstantInt::get(RHSTy, RHSMax); return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1); @@ -4370,7 +4382,7 @@ Value *ScalarExprEmitter::ConstrainShiftValue(Value *LHS, Value *RHS, Ty = cast(LHS->getType()); if (llvm::isPowerOf2_64(Ty->getBitWidth())) - return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS), Name); + return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS, false), Name); return Builder.CreateURem( RHS, llvm::ConstantInt::get(RHS->getType(), Ty->getBitWidth()), Name); @@ -4403,7 +4415,9 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) { isa(Ops.LHS->getType())) { CodeGenFunction::SanitizerScope SanScope(&CGF); SmallVector, 2> Checks; - llvm::Value *WidthMinusOne = GetMaximumShiftAmount(Ops.LHS, Ops.RHS); + bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation(); + llvm::Value *WidthMinusOne = + GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned); llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne); if (SanitizeExponent) { @@ -4421,7 +4435,7 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) { Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont); llvm::Value *PromotedWidthMinusOne = (RHS == Ops.RHS) ? WidthMinusOne - : GetMaximumShiftAmount(Ops.LHS, RHS); + : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned); CGF.EmitBlock(CheckShiftBase); llvm::Value *BitsShiftedOff = Builder.CreateLShr( Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS, "shl.zeros", @@ -4471,8 +4485,9 @@ Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) { else if (CGF.SanOpts.has(SanitizerKind::ShiftExponent) && isa(Ops.LHS->getType())) { CodeGenFunction::SanitizerScope SanScope(&CGF); - llvm::Value *Valid = - Builder.CreateICmpULE(Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS)); + bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation(); + llvm::Value *Valid = Builder.CreateICmpULE( + Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned)); EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops); } diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index 506b364f5b2ec7110399dee74a54c195930cc9cc..0abe39dedcb96f81a5f5b3d62ca5aaf103936727 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -74,6 +74,7 @@ public: GENERATE_HLSL_INTRINSIC_FUNCTION(All, all) GENERATE_HLSL_INTRINSIC_FUNCTION(Any, any) + GENERATE_HLSL_INTRINSIC_FUNCTION(Lerp, lerp) GENERATE_HLSL_INTRINSIC_FUNCTION(ThreadId, thread_id) //===----------------------------------------------------------------------===// diff --git a/clang/lib/CodeGen/CGLoopInfo.cpp b/clang/lib/CodeGen/CGLoopInfo.cpp index 0d4800b90a2f26c67ba51fff219673fb5290a8e4..72d1471021ac02971f8d4da33e0ef149df12a501 100644 --- a/clang/lib/CodeGen/CGLoopInfo.cpp +++ b/clang/lib/CodeGen/CGLoopInfo.cpp @@ -673,6 +673,8 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx, setPipelineDisabled(true); break; case LoopHintAttr::UnrollCount: + setUnrollState(LoopAttributes::Disable); + break; case LoopHintAttr::UnrollAndJamCount: case LoopHintAttr::VectorizeWidth: case LoopHintAttr::InterleaveCount: diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 71215da362d3d01a3c1fc622db29a4103fb44cff..733686d4946b3c1e529d80d11e5e9e743c6ed6b7 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -1208,6 +1208,12 @@ struct CounterCoverageMappingBuilder /// Find a valid gap range between \p AfterLoc and \p BeforeLoc. std::optional findGapAreaBetween(SourceLocation AfterLoc, SourceLocation BeforeLoc) { + // Some statements (like AttributedStmt and ImplicitValueInitExpr) don't + // have valid source locations. Do not emit a gap region if this is the case + // in either AfterLoc end or BeforeLoc end. + if (AfterLoc.isInvalid() || BeforeLoc.isInvalid()) + return std::nullopt; + // If AfterLoc is in function-like macro, use the right parenthesis // location. if (AfterLoc.isMacroID()) { @@ -1368,9 +1374,8 @@ struct CounterCoverageMappingBuilder for (const Stmt *Child : S->children()) if (Child) { // If last statement contains terminate statements, add a gap area - // between the two statements. Skipping attributed statements, because - // they don't have valid start location. - if (LastStmt && HasTerminateStmt && !isa(Child)) { + // between the two statements. + if (LastStmt && HasTerminateStmt) { auto Gap = findGapAreaBetween(getEnd(LastStmt), getStart(Child)); if (Gap) fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), @@ -2011,11 +2016,13 @@ struct CounterCoverageMappingBuilder Counter TrueCount = llvm::EnableSingleByteCoverage ? getRegionCounter(E->getTrueExpr()) : getRegionCounter(E); - - propagateCounts(ParentCount, E->getCond()); Counter OutCount; - if (!isa(E)) { + if (const auto *BCO = dyn_cast(E)) { + propagateCounts(ParentCount, BCO->getCommon()); + OutCount = TrueCount; + } else { + propagateCounts(ParentCount, E->getCond()); // The 'then' count applies to the area immediately after the condition. auto Gap = findGapAreaBetween(E->getQuestionLoc(), getStart(E->getTrueExpr())); @@ -2024,8 +2031,6 @@ struct CounterCoverageMappingBuilder extendRegion(E->getTrueExpr()); OutCount = propagateCounts(TrueCount, E->getTrueExpr()); - } else { - OutCount = TrueCount; } extendRegion(E->getFalseExpr()); diff --git a/clang/lib/Driver/OffloadBundler.cpp b/clang/lib/Driver/OffloadBundler.cpp index 77c89356bc76bb38a4b0771b739b281a92bb709f..8cc82a0ee7168729ccd39eedff8de7df5b32cd3c 100644 --- a/clang/lib/Driver/OffloadBundler.cpp +++ b/clang/lib/Driver/OffloadBundler.cpp @@ -1010,6 +1010,10 @@ CompressedOffloadBundle::compress(llvm::compression::Params P, uint16_t CompressionMethod = static_cast(P.format); uint32_t UncompressedSize = Input.getBuffer().size(); + uint32_t TotalFileSize = MagicNumber.size() + sizeof(TotalFileSize) + + sizeof(Version) + sizeof(CompressionMethod) + + sizeof(UncompressedSize) + sizeof(TruncatedHash) + + CompressedBuffer.size(); SmallVector FinalBuffer; llvm::raw_svector_ostream OS(FinalBuffer); @@ -1017,6 +1021,8 @@ CompressedOffloadBundle::compress(llvm::compression::Params P, OS.write(reinterpret_cast(&Version), sizeof(Version)); OS.write(reinterpret_cast(&CompressionMethod), sizeof(CompressionMethod)); + OS.write(reinterpret_cast(&TotalFileSize), + sizeof(TotalFileSize)); OS.write(reinterpret_cast(&UncompressedSize), sizeof(UncompressedSize)); OS.write(reinterpret_cast(&TruncatedHash), @@ -1034,6 +1040,8 @@ CompressedOffloadBundle::compress(llvm::compression::Params P, (UncompressedSize / (1024.0 * 1024.0)) / CompressionTimeSeconds; llvm::errs() << "Compressed bundle format version: " << Version << "\n" + << "Total file size (including headers): " + << formatWithCommas(TotalFileSize) << " bytes\n" << "Compression method used: " << MethodUsed << "\n" << "Compression level: " << P.level << "\n" << "Binary size before compression: " @@ -1059,9 +1067,9 @@ CompressedOffloadBundle::decompress(const llvm::MemoryBuffer &Input, StringRef Blob = Input.getBuffer(); - if (Blob.size() < HeaderSize) { + if (Blob.size() < V1HeaderSize) return llvm::MemoryBuffer::getMemBufferCopy(Blob); - } + if (llvm::identify_magic(Blob) != llvm::file_magic::offload_bundle_compressed) { if (Verbose) @@ -1069,21 +1077,32 @@ CompressedOffloadBundle::decompress(const llvm::MemoryBuffer &Input, return llvm::MemoryBuffer::getMemBufferCopy(Blob); } + size_t CurrentOffset = MagicSize; + uint16_t ThisVersion; + memcpy(&ThisVersion, Blob.data() + CurrentOffset, sizeof(uint16_t)); + CurrentOffset += VersionFieldSize; + uint16_t CompressionMethod; + memcpy(&CompressionMethod, Blob.data() + CurrentOffset, sizeof(uint16_t)); + CurrentOffset += MethodFieldSize; + + uint32_t TotalFileSize; + if (ThisVersion >= 2) { + if (Blob.size() < V2HeaderSize) + return createStringError(inconvertibleErrorCode(), + "Compressed bundle header size too small"); + memcpy(&TotalFileSize, Blob.data() + CurrentOffset, sizeof(uint32_t)); + CurrentOffset += FileSizeFieldSize; + } + uint32_t UncompressedSize; + memcpy(&UncompressedSize, Blob.data() + CurrentOffset, sizeof(uint32_t)); + CurrentOffset += UncompressedSizeFieldSize; + uint64_t StoredHash; - memcpy(&ThisVersion, Input.getBuffer().data() + MagicNumber.size(), - sizeof(uint16_t)); - memcpy(&CompressionMethod, Blob.data() + MagicSize + VersionFieldSize, - sizeof(uint16_t)); - memcpy(&UncompressedSize, - Blob.data() + MagicSize + VersionFieldSize + MethodFieldSize, - sizeof(uint32_t)); - memcpy(&StoredHash, - Blob.data() + MagicSize + VersionFieldSize + MethodFieldSize + - SizeFieldSize, - sizeof(uint64_t)); + memcpy(&StoredHash, Blob.data() + CurrentOffset, sizeof(uint64_t)); + CurrentOffset += HashFieldSize; llvm::compression::Format CompressionFormat; if (CompressionMethod == @@ -1102,7 +1121,7 @@ CompressedOffloadBundle::decompress(const llvm::MemoryBuffer &Input, DecompressTimer.startTimer(); SmallVector DecompressedData; - StringRef CompressedData = Blob.substr(HeaderSize); + StringRef CompressedData = Blob.substr(CurrentOffset); if (llvm::Error DecompressionError = llvm::compression::decompress( CompressionFormat, llvm::arrayRefFromStringRef(CompressedData), DecompressedData, UncompressedSize)) @@ -1135,8 +1154,11 @@ CompressedOffloadBundle::decompress(const llvm::MemoryBuffer &Input, double DecompressionSpeedMBs = (UncompressedSize / (1024.0 * 1024.0)) / DecompressionTimeSeconds; - llvm::errs() << "Compressed bundle format version: " << ThisVersion << "\n" - << "Decompression method: " + llvm::errs() << "Compressed bundle format version: " << ThisVersion << "\n"; + if (ThisVersion >= 2) + llvm::errs() << "Total file size (from header): " + << formatWithCommas(TotalFileSize) << " bytes\n"; + llvm::errs() << "Decompression method: " << (CompressionFormat == llvm::compression::Format::Zlib ? "zlib" : "zstd") diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 456ea74caadb009b01e87583aec0272e125d8195..5894a48e0e378bc89ab0feb3b0235959c66b9ae3 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -847,6 +847,16 @@ static bool UseRelaxAll(Compilation &C, const ArgList &Args) { if (Arg *A = Args.getLastArg(options::OPT_O_Group)) RelaxDefault = A->getOption().matches(options::OPT_O0); + // RISC-V requires an indirect jump for offsets larger than 1MiB. This cannot + // be done by assembler branch relaxation as it needs a free temporary + // register. Because of this, branch relaxation is handled by a MachineIR + // pass before the assembler. Forcing assembler branch relaxation for -O0 + // makes the MachineIR branch relaxation inaccurate and it will miss cases + // where an indirect branch is necessary. To avoid this issue we are + // sacrificing the compile time improvement of using -mrelax-all for -O0. + if (C.getDefaultToolChain().getTriple().isRISCV()) + RelaxDefault = false; + if (RelaxDefault) { RelaxDefault = false; for (const auto &Act : C.getActions()) { @@ -4634,7 +4644,7 @@ renderDebugOptions(const ToolChain &TC, const Driver &D, const llvm::Triple &T, // Emit DW_TAG_template_alias for template aliases? True by default for SCE. bool UseDebugTemplateAlias = - DebuggerTuning == llvm::DebuggerKind::SCE && RequestedDWARFVersion >= 5; + DebuggerTuning == llvm::DebuggerKind::SCE && RequestedDWARFVersion >= 4; if (const auto *DebugTemplateAlias = Args.getLastArg( options::OPT_gtemplate_alias, options::OPT_gno_template_alias)) { // DW_TAG_template_alias is only supported from DWARFv5 but if a user @@ -4733,7 +4743,7 @@ renderDebugOptions(const ToolChain &TC, const Driver &D, const llvm::Triple &T, Output.getFilename()); } -static void ProcessVSRuntimeLibrary(const ArgList &Args, +static void ProcessVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { unsigned RTOptionID = options::OPT__SLASH_MT; @@ -4796,6 +4806,12 @@ static void ProcessVSRuntimeLibrary(const ArgList &Args, // implemented in clang. CmdArgs.push_back("--dependent-lib=oldnames"); } + + // All Arm64EC object files implicitly add softintrin.lib. This is necessary + // even if the file doesn't actually refer to any of the routines because + // the CRT itself has incomplete dependency markings. + if (TC.getTriple().isWindowsArm64EC()) + CmdArgs.push_back("--dependent-lib=softintrin"); } void Clang::ConstructJob(Compilation &C, const JobAction &JA, @@ -7051,7 +7067,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Triple.isWindowsMSVCEnvironment() && !D.IsCLMode() && Args.hasArg(options::OPT_fms_runtime_lib_EQ)) - ProcessVSRuntimeLibrary(Args, CmdArgs); + ProcessVSRuntimeLibrary(getToolChain(), Args, CmdArgs); // Handle -fgcc-version, if present. VersionTuple GNUCVer; @@ -8178,7 +8194,7 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType, ArgStringList &CmdArgs) const { bool isNVPTX = getToolChain().getTriple().isNVPTX(); - ProcessVSRuntimeLibrary(Args, CmdArgs); + ProcessVSRuntimeLibrary(getToolChain(), Args, CmdArgs); if (Arg *ShowIncludes = Args.getLastArg(options::OPT__SLASH_showIncludes, diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index f10aa4dfaa9ddd9a9dde4679e8990240d63a1d44..b65b96db16bd79583dc6dd4857f27c111ee0fb88 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -2116,8 +2116,12 @@ unsigned tools::getDwarfVersion(const ToolChain &TC, const llvm::opt::ArgList &Args) { unsigned DwarfVersion = ParseDebugDefaultVersion(TC, Args); if (const Arg *GDwarfN = getDwarfNArg(Args)) - if (int N = DwarfVersionNum(GDwarfN->getSpelling())) + if (int N = DwarfVersionNum(GDwarfN->getSpelling())) { DwarfVersion = N; + if (DwarfVersion == 5 && TC.getTriple().isOSAIX()) + TC.getDriver().Diag(diag::err_drv_unsupported_opt_for_target) + << GDwarfN->getSpelling() << TC.getTriple().str(); + } if (DwarfVersion == 0) { DwarfVersion = TC.GetDefaultDwarfVersion(); assert(DwarfVersion && "toolchain default DWARF version must be nonzero"); diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index b46bac24503ce1c64cfa0fa0c51a07164a986600..abe0b931676005c00de472e432051db124f6785d 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -118,7 +118,7 @@ void Flang::addOtherOptions(const ArgList &Args, ArgStringList &CmdArgs) const { Arg *gNArg = Args.getLastArg(options::OPT_gN_Group); DebugInfoKind = debugLevelToInfoKind(*gNArg); } else if (Args.hasArg(options::OPT_g_Flag)) { - DebugInfoKind = llvm::codegenoptions::DebugLineTablesOnly; + DebugInfoKind = llvm::codegenoptions::FullDebugInfo; } else { DebugInfoKind = llvm::codegenoptions::NoDebugInfo; } diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index a679683077ac949e38ce55dc388fe9256977535b..cdfb4256e41d93ddf36de11fb047aeb4fdc37eb0 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1543,6 +1543,7 @@ private: return false; if (Line.MustBeDeclaration && Contexts.size() == 1 && !Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) && + !Line.startsWith(tok::l_paren) && !Tok->isOneOf(TT_TypeDeclarationParen, TT_RequiresExpressionLParen)) { if (const auto *Previous = Tok->Previous; !Previous || @@ -2726,8 +2727,10 @@ private: } } - if (Tok.Next->isOneOf(tok::question, tok::ampamp)) + if (Tok.Next->is(tok::question) || + (Tok.Next->is(tok::ampamp) && !Tok.Previous->isTypeName(IsCpp))) { return false; + } // `foreach((A a, B b) in someList)` should not be seen as a cast. if (Tok.Next->is(Keywords.kw_in) && Style.isCSharp()) diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 5531e938e0f4f4f9fa2e48f39caedfd21d1052b6..8236051e30c4a5daa74b8ae09ce7e77d286cfad9 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3660,6 +3660,9 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts, case LangOptions::ClangABI::Ver17: GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "17.0"); break; + case LangOptions::ClangABI::Ver18: + GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "18.0"); + break; case LangOptions::ClangABI::Latest: break; } @@ -4167,6 +4170,8 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, Opts.setClangABICompat(LangOptions::ClangABI::Ver15); else if (Major <= 17) Opts.setClangABICompat(LangOptions::ClangABI::Ver17); + else if (Major <= 18) + Opts.setClangABICompat(LangOptions::ClangABI::Ver18); } else if (Ver != "latest") { Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); diff --git a/clang/lib/Headers/avxintrin.h b/clang/lib/Headers/avxintrin.h index be7a0b247e03d45d7e7429de4dce85546b87206b..4983f3311370014f773499e784560fbd19eb2b46 100644 --- a/clang/lib/Headers/avxintrin.h +++ b/clang/lib/Headers/avxintrin.h @@ -840,6 +840,7 @@ _mm256_permutevar_pd(__m256d __a, __m256i __c) /// Copies the values stored in a 128-bit vector of [4 x float] as /// specified by the 128-bit integer vector operand. +/// /// \headerfile /// /// This intrinsic corresponds to the VPERMILPS instruction. diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp index 5eec2a2fd6d1a69c76a3464997394b681cb133a6..ef90fe9e6f5451701d6b2fd01639c70cad9839bc 100644 --- a/clang/lib/Interpreter/IncrementalParser.cpp +++ b/clang/lib/Interpreter/IncrementalParser.cpp @@ -209,6 +209,10 @@ IncrementalParser::IncrementalParser(Interpreter &Interp, if (Err) return; CI->ExecuteAction(*Act); + + if (getCodeGen()) + CachedInCodeGenModule = GenModule(); + std::unique_ptr IncrConsumer = std::make_unique(Interp, CI->takeASTConsumer()); CI->setASTConsumer(std::move(IncrConsumer)); @@ -224,11 +228,8 @@ IncrementalParser::IncrementalParser(Interpreter &Interp, return; // PTU.takeError(); } - if (CodeGenerator *CG = getCodeGen()) { - std::unique_ptr M(CG->ReleaseModule()); - CG->StartModule("incr_module_" + std::to_string(PTUs.size()), - M->getContext()); - PTU->TheModule = std::move(M); + if (getCodeGen()) { + PTU->TheModule = GenModule(); assert(PTU->TheModule && "Failed to create initial PTU"); } } @@ -364,6 +365,19 @@ IncrementalParser::Parse(llvm::StringRef input) { std::unique_ptr IncrementalParser::GenModule() { static unsigned ID = 0; if (CodeGenerator *CG = getCodeGen()) { + // Clang's CodeGen is designed to work with a single llvm::Module. In many + // cases for convenience various CodeGen parts have a reference to the + // llvm::Module (TheModule or Module) which does not change when a new + // module is pushed. However, the execution engine wants to take ownership + // of the module which does not map well to CodeGen's design. To work this + // around we created an empty module to make CodeGen happy. We should make + // sure it always stays empty. + assert((!CachedInCodeGenModule || + (CachedInCodeGenModule->empty() && + CachedInCodeGenModule->global_empty() && + CachedInCodeGenModule->alias_empty() && + CachedInCodeGenModule->ifunc_empty())) && + "CodeGen wrote to a readonly module"); std::unique_ptr M(CG->ReleaseModule()); CG->StartModule("incr_module_" + std::to_string(ID++), M->getContext()); return M; diff --git a/clang/lib/Interpreter/IncrementalParser.h b/clang/lib/Interpreter/IncrementalParser.h index e13b74c7f6594890ac6481e4be41a2270086bac7..f63bce50acd3b90b1964963add99fa5c23861744 100644 --- a/clang/lib/Interpreter/IncrementalParser.h +++ b/clang/lib/Interpreter/IncrementalParser.h @@ -24,6 +24,7 @@ #include namespace llvm { class LLVMContext; +class Module; } // namespace llvm namespace clang { @@ -57,6 +58,10 @@ protected: /// of code. std::list PTUs; + /// When CodeGen is created the first llvm::Module gets cached in many places + /// and we must keep it alive. + std::unique_ptr CachedInCodeGenModule; + IncrementalParser(); public: diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 438c6d772e6e04d41412dfbb018f651f9c9a2e7a..9c0cbea5052cb23dcb781c8d3ac72653506f1daf 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -974,6 +974,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, bool isFixedPointConstant = isFixedPointLiteral(); bool isFPConstant = isFloatingLiteral(); bool HasSize = false; + bool DoubleUnderscore = false; // Loop over all of the characters of the suffix. If we see something bad, // we break out of the loop. @@ -1117,6 +1118,31 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, if (isImaginary) break; // Cannot be repeated. isImaginary = true; continue; // Success. + case '_': + if (isFPConstant) + break; // Invalid for floats + if (HasSize) + break; + if (DoubleUnderscore) + break; // Cannot be repeated. + if (LangOpts.CPlusPlus && s + 2 < ThisTokEnd && + s[1] == '_') { // s + 2 < ThisTokEnd to ensure some character exists + // after __ + DoubleUnderscore = true; + s += 2; // Skip both '_' + if (s + 1 < ThisTokEnd && + (*s == 'u' || *s == 'U')) { // Ensure some character after 'u'/'U' + isUnsigned = true; + ++s; + } + if (s + 1 < ThisTokEnd && + ((*s == 'w' && *(++s) == 'b') || (*s == 'W' && *(++s) == 'B'))) { + isBitInt = true; + HasSize = true; + continue; + } + } + break; case 'w': case 'W': if (isFPConstant) @@ -1127,9 +1153,9 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, // wb and WB are allowed, but a mixture of cases like Wb or wB is not. We // explicitly do not support the suffix in C++ as an extension because a // library-based UDL that resolves to a library type may be more - // appropriate there. - if (!LangOpts.CPlusPlus && ((s[0] == 'w' && s[1] == 'b') || - (s[0] == 'W' && s[1] == 'B'))) { + // appropriate there. The same rules apply for __wb/__WB. + if ((!LangOpts.CPlusPlus || DoubleUnderscore) && s + 1 < ThisTokEnd && + ((s[0] == 'w' && s[1] == 'b') || (s[0] == 'W' && s[1] == 'B'))) { isBitInt = true; HasSize = true; ++s; // Skip both characters (2nd char skipped on continue). @@ -1241,7 +1267,9 @@ bool NumericLiteralParser::isValidUDSuffix(const LangOptions &LangOpts, return false; // By C++11 [lex.ext]p10, ud-suffixes starting with an '_' are always valid. - if (Suffix[0] == '_') + // Suffixes starting with '__' (double underscore) are for use by + // the implementation. + if (Suffix.starts_with("_") && !Suffix.starts_with("__")) return true; // In C++11, there are no library suffixes. diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp index 8f25c67ec9dfbe40d1e73c9ac2efff1fb2b5d846..f267efabd617fd9cfaad99c1d998adc593588be8 100644 --- a/clang/lib/Lex/PPExpressions.cpp +++ b/clang/lib/Lex/PPExpressions.cpp @@ -333,11 +333,11 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, : diag::ext_cxx23_size_t_suffix : diag::err_cxx23_size_t_suffix); - // 'wb/uwb' literals are a C23 feature. We explicitly do not support the - // suffix in C++ as an extension because a library-based UDL that resolves - // to a library type may be more appropriate there. + // 'wb/uwb' literals are a C23 feature. + // '__wb/__uwb' are a C++ extension. if (Literal.isBitInt) - PP.Diag(PeekTok, PP.getLangOpts().C23 + PP.Diag(PeekTok, PP.getLangOpts().CPlusPlus ? diag::ext_cxx_bitint_suffix + : PP.getLangOpts().C23 ? diag::warn_c23_compat_bitint_suffix : diag::ext_c23_bitint_suffix); diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp index 757417f75c9636e53444875dbc38c1f677ef1fc6..8a18fca8064ee119ae2d429844eb41021b93cc72 100644 --- a/clang/lib/Parse/ParseOpenACC.cpp +++ b/clang/lib/Parse/ParseOpenACC.cpp @@ -632,16 +632,54 @@ Parser::ParseOpenACCClauseList(OpenACCDirectiveKind DirKind) { return Clauses; } -ExprResult Parser::ParseOpenACCIntExpr(OpenACCDirectiveKind DK, - OpenACCClauseKind CK, - SourceLocation Loc) { - ExprResult ER = - getActions().CorrectDelayedTyposInExpr(ParseAssignmentExpression()); +Parser::OpenACCIntExprParseResult +Parser::ParseOpenACCIntExpr(OpenACCDirectiveKind DK, OpenACCClauseKind CK, + SourceLocation Loc) { + ExprResult ER = ParseAssignmentExpression(); + // If the actual parsing failed, we don't know the state of the parse, so + // don't try to continue. if (!ER.isUsable()) - return ER; + return {ER, OpenACCParseCanContinue::Cannot}; + + // Parsing can continue after the initial assignment expression parsing, so + // even if there was a typo, we can continue. + ER = getActions().CorrectDelayedTyposInExpr(ER); + if (!ER.isUsable()) + return {ER, OpenACCParseCanContinue::Can}; + + return {getActions().OpenACC().ActOnIntExpr(DK, CK, Loc, ER.get()), + OpenACCParseCanContinue::Can}; +} + +bool Parser::ParseOpenACCIntExprList(OpenACCDirectiveKind DK, + OpenACCClauseKind CK, SourceLocation Loc, + llvm::SmallVectorImpl &IntExprs) { + OpenACCIntExprParseResult CurResult = ParseOpenACCIntExpr(DK, CK, Loc); + + if (!CurResult.first.isUsable() && + CurResult.second == OpenACCParseCanContinue::Cannot) { + SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end, + Parser::StopBeforeMatch); + return true; + } + + IntExprs.push_back(CurResult.first.get()); + + while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) { + ExpectAndConsume(tok::comma); + + CurResult = ParseOpenACCIntExpr(DK, CK, Loc); - return getActions().OpenACC().ActOnIntExpr(DK, CK, Loc, ER.get()); + if (!CurResult.first.isUsable() && + CurResult.second == OpenACCParseCanContinue::Cannot) { + SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end, + Parser::StopBeforeMatch); + return true; + } + IntExprs.push_back(CurResult.first.get()); + } + return false; } bool Parser::ParseOpenACCClauseVarList(OpenACCClauseKind Kind) { @@ -761,7 +799,7 @@ bool Parser::ParseOpenACCGangArg(SourceLocation GangLoc) { ConsumeToken(); return ParseOpenACCIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang, GangLoc) - .isInvalid(); + .first.isInvalid(); } if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Num, getCurToken()) && @@ -773,7 +811,7 @@ bool Parser::ParseOpenACCGangArg(SourceLocation GangLoc) { // This is just the 'num' case where 'num' is optional. return ParseOpenACCIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang, GangLoc) - .isInvalid(); + .first.isInvalid(); } bool Parser::ParseOpenACCGangArgList(SourceLocation GangLoc) { @@ -946,13 +984,25 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams( } break; } - case OpenACCClauseKind::NumGangs: + case OpenACCClauseKind::NumGangs: { + llvm::SmallVector IntExprs; + + if (ParseOpenACCIntExprList(OpenACCDirectiveKind::Invalid, + OpenACCClauseKind::NumGangs, ClauseLoc, + IntExprs)) { + Parens.skipToEnd(); + return OpenACCCanContinue(); + } + ParsedClause.setIntExprDetails(std::move(IntExprs)); + break; + } case OpenACCClauseKind::NumWorkers: case OpenACCClauseKind::DeviceNum: case OpenACCClauseKind::DefaultAsync: case OpenACCClauseKind::VectorLength: { ExprResult IntExpr = ParseOpenACCIntExpr(OpenACCDirectiveKind::Invalid, - ClauseKind, ClauseLoc); + ClauseKind, ClauseLoc) + .first; if (IntExpr.isInvalid()) { Parens.skipToEnd(); return OpenACCCanContinue(); @@ -1017,7 +1067,8 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams( : OpenACCSpecialTokenKind::Num, ClauseKind); ExprResult IntExpr = ParseOpenACCIntExpr(OpenACCDirectiveKind::Invalid, - ClauseKind, ClauseLoc); + ClauseKind, ClauseLoc) + .first; if (IntExpr.isInvalid()) { Parens.skipToEnd(); return OpenACCCanContinue(); @@ -1081,11 +1132,13 @@ bool Parser::ParseOpenACCWaitArgument(SourceLocation Loc, bool IsDirective) { // Consume colon. ConsumeToken(); - ExprResult IntExpr = ParseOpenACCIntExpr( - IsDirective ? OpenACCDirectiveKind::Wait - : OpenACCDirectiveKind::Invalid, - IsDirective ? OpenACCClauseKind::Invalid : OpenACCClauseKind::Wait, - Loc); + ExprResult IntExpr = + ParseOpenACCIntExpr(IsDirective ? OpenACCDirectiveKind::Wait + : OpenACCDirectiveKind::Invalid, + IsDirective ? OpenACCClauseKind::Invalid + : OpenACCClauseKind::Wait, + Loc) + .first; if (IntExpr.isInvalid()) return true; diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index 3979f75b6020dbba3d91ae2e747aac6bbcdf996a..cd0fab5fe31d3fc66928ccd079d380441cbd7ee6 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -1569,7 +1569,8 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) { ConsumeToken(); // Consume the constant expression eof terminator. if (Arg2Error || R.isInvalid() || - Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation())) + Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation(), + /*AllowZero=*/false)) return false; // Argument is a constant expression with an integer type. @@ -1594,7 +1595,8 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) { ConsumeToken(); // Consume the constant expression eof terminator. if (R.isInvalid() || - Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation())) + Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation(), + /*AllowZero=*/true)) return false; // Argument is a constant expression with an integer type. diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 6778bc6607f75e10700b44fc0e0114669adb598b..51757f4cf727d6433144bf664637a3b9900f0da9 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -3507,11 +3507,15 @@ bool Sema::ParseSVEImmChecks( static ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD) { if (FD->hasAttr()) return ArmStreaming; - if (const auto *T = FD->getType()->getAs()) { - if (T->getAArch64SMEAttributes() & FunctionType::SME_PStateSMEnabledMask) - return ArmStreaming; - if (T->getAArch64SMEAttributes() & FunctionType::SME_PStateSMCompatibleMask) - return ArmStreamingCompatible; + if (const Type *Ty = FD->getType().getTypePtrOrNull()) { + if (const auto *FPT = Ty->getAs()) { + if (FPT->getAArch64SMEAttributes() & + FunctionType::SME_PStateSMEnabledMask) + return ArmStreaming; + if (FPT->getAArch64SMEAttributes() & + FunctionType::SME_PStateSMCompatibleMask) + return ArmStreamingCompatible; + } } return ArmNonStreaming; } @@ -7949,6 +7953,7 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, // For variadic functions, we may have more args than parameters. // For some K&R functions, we may have less args than parameters. const auto N = std::min(Proto->getNumParams(), Args.size()); + bool AnyScalableArgsOrRet = Proto->getReturnType()->isSizelessVectorType(); for (unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) { // Args[ArgIdx] can be null in malformed code. if (const Expr *Arg = Args[ArgIdx]) { @@ -7962,6 +7967,8 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, checkAIXMemberAlignment((Arg->getExprLoc()), Arg); QualType ParamTy = Proto->getParamType(ArgIdx); + if (ParamTy->isSizelessVectorType()) + AnyScalableArgsOrRet = true; QualType ArgTy = Arg->getType(); CheckArgAlignment(Arg->getExprLoc(), FDecl, std::to_string(ArgIdx + 1), ArgTy, ParamTy); @@ -7982,6 +7989,23 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, } } + // If the call requires a streaming-mode change and has scalable vector + // arguments or return values, then warn the user that the streaming and + // non-streaming vector lengths may be different. + const auto *CallerFD = dyn_cast(CurContext); + if (CallerFD && (!FD || !FD->getBuiltinID()) && AnyScalableArgsOrRet) { + bool IsCalleeStreaming = + ExtInfo.AArch64SMEAttributes & FunctionType::SME_PStateSMEnabledMask; + bool IsCalleeStreamingCompatible = + ExtInfo.AArch64SMEAttributes & + FunctionType::SME_PStateSMCompatibleMask; + ArmStreamingType CallerFnType = getArmStreamingFnType(CallerFD); + if (!IsCalleeStreamingCompatible && + (CallerFnType == ArmStreamingCompatible || + ((CallerFnType == ArmStreaming) ^ IsCalleeStreaming))) + Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming); + } + FunctionType::ArmStateValue CalleeArmZAState = FunctionType::getArmZAState(ExtInfo.AArch64SMEAttributes); FunctionType::ArmStateValue CalleeArmZT0State = @@ -7990,7 +8014,7 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, CalleeArmZT0State != FunctionType::ARM_None) { bool CallerHasZAState = false; bool CallerHasZT0State = false; - if (const auto *CallerFD = dyn_cast(CurContext)) { + if (CallerFD) { auto *Attr = CallerFD->getAttr(); if (Attr && Attr->isNewZA()) CallerHasZAState = true; @@ -12755,10 +12779,15 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, // In this case, the expression could be printed using a different // specifier, but we've decided that the specifier is probably correct // and we should cast instead. Just use the normal warning message. + + unsigned Diag = + IsScopedEnum + ? diag::warn_format_conversion_argument_type_mismatch_pedantic + : diag::warn_format_conversion_argument_type_mismatch; + EmitFormatDiagnostic( - S.PDiag(diag::warn_format_conversion_argument_type_mismatch) - << AT.getRepresentativeTypeName(S.Context) << ExprTy << IsEnum - << E->getSourceRange(), + S.PDiag(Diag) << AT.getRepresentativeTypeName(S.Context) << ExprTy + << IsEnum << E->getSourceRange(), E->getBeginLoc(), /*IsStringLocation*/ false, SpecRange, Hints); } } diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp index 736632857efc36997d039c0037e7ffdbe1e88b98..81334c817b2af2edf716413938db94e059ca67e8 100644 --- a/clang/lib/Sema/SemaCoroutine.cpp +++ b/clang/lib/Sema/SemaCoroutine.cpp @@ -817,13 +817,10 @@ ExprResult Sema::BuildOperatorCoawaitLookupExpr(Scope *S, SourceLocation Loc) { assert(!Operators.isAmbiguous() && "Operator lookup cannot be ambiguous"); const auto &Functions = Operators.asUnresolvedSet(); - bool IsOverloaded = - Functions.size() > 1 || - (Functions.size() == 1 && isa(*Functions.begin())); Expr *CoawaitOp = UnresolvedLookupExpr::Create( Context, /*NamingClass*/ nullptr, NestedNameSpecifierLoc(), - DeclarationNameInfo(OpName, Loc), /*RequiresADL*/ true, IsOverloaded, - Functions.begin(), Functions.end()); + DeclarationNameInfo(OpName, Loc), /*RequiresADL*/ true, Functions.begin(), + Functions.end(), /*KnownDependent=*/false); assert(CoawaitOp); return CoawaitOp; } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index af6b3f21f15a65878de26a9b376bd073beca5682..35eac93e324dec7780f9fb0215743b061f8b3e52 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1240,8 +1240,8 @@ Corrected: Result.suppressDiagnostics(); return NameClassification::OverloadSet(UnresolvedLookupExpr::Create( Context, Result.getNamingClass(), SS.getWithLocInContext(Context), - Result.getLookupNameInfo(), ADL, Result.isOverloadedResult(), - Result.begin(), Result.end())); + Result.getLookupNameInfo(), ADL, Result.begin(), Result.end(), + /*KnownDependent=*/false)); } ExprResult @@ -12408,12 +12408,22 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, } // Check if the function definition uses any AArch64 SME features without - // having the '+sme' feature enabled. + // having the '+sme' feature enabled and warn user if sme locally streaming + // function returns or uses arguments with VL-based types. if (DeclIsDefn) { const auto *Attr = NewFD->getAttr(); bool UsesSM = NewFD->hasAttr(); bool UsesZA = Attr && Attr->isNewZA(); bool UsesZT0 = Attr && Attr->isNewZT0(); + + if (NewFD->hasAttr()) { + if (NewFD->getReturnType()->isSizelessVectorType() || + llvm::any_of(NewFD->parameters(), [](ParmVarDecl *P) { + return P->getOriginalType()->isSizelessVectorType(); + })) + Diag(NewFD->getLocation(), + diag::warn_sme_locally_streaming_has_vl_args_returns); + } if (const auto *FPT = NewFD->getType()->getAs()) { FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); UsesSM |= diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 2ef8a15d5238fa1610d1246383f724aab594474f..abdbc9d8830c03f6c70121e73f9f2427450cc577 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1302,7 +1302,7 @@ static bool checkTupleLikeDecomposition(Sema &S, // in the associated namespaces. Expr *Get = UnresolvedLookupExpr::Create( S.Context, nullptr, NestedNameSpecifierLoc(), SourceLocation(), - DeclarationNameInfo(GetDN, Loc), /*RequiresADL*/ true, &Args, + DeclarationNameInfo(GetDN, Loc), /*RequiresADL=*/true, &Args, UnresolvedSetIterator(), UnresolvedSetIterator(), /*KnownDependent=*/false); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c7e1d1daafea995980d5afb94827edeebdd77961..5c861467bc1023dc85dba17e56d5fdafc2fa6fc3 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2918,26 +2918,9 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, // to get this right here so that we don't end up making a // spuriously dependent expression if we're inside a dependent // instance method. - if (getLangOpts().CPlusPlus && !R.empty() && - (*R.begin())->isCXXClassMember()) { - bool MightBeImplicitMember; - if (!IsAddressOfOperand) - MightBeImplicitMember = true; - else if (!SS.isEmpty()) - MightBeImplicitMember = false; - else if (R.isOverloadedResult()) - MightBeImplicitMember = false; - else if (R.isUnresolvableResult()) - MightBeImplicitMember = true; - else - MightBeImplicitMember = isa(R.getFoundDecl()) || - isa(R.getFoundDecl()) || - isa(R.getFoundDecl()); - - if (MightBeImplicitMember) - return BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, - R, TemplateArgs, S); - } + if (isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand)) + return BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, + S); if (TemplateArgs || TemplateKWLoc.isValid()) { @@ -3471,12 +3454,10 @@ ExprResult Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, // we've picked a target. R.suppressDiagnostics(); - UnresolvedLookupExpr *ULE - = UnresolvedLookupExpr::Create(Context, R.getNamingClass(), - SS.getWithLocInContext(Context), - R.getLookupNameInfo(), - NeedsADL, R.isOverloadedResult(), - R.begin(), R.end()); + UnresolvedLookupExpr *ULE = UnresolvedLookupExpr::Create( + Context, R.getNamingClass(), SS.getWithLocInContext(Context), + R.getLookupNameInfo(), NeedsADL, R.begin(), R.end(), + /*KnownDependent=*/false); return ULE; } @@ -3902,7 +3883,7 @@ static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal, return FloatingLiteral::Create(S.Context, Val, isExact, Ty, Loc); } -bool Sema::CheckLoopHintExpr(Expr *E, SourceLocation Loc) { +bool Sema::CheckLoopHintExpr(Expr *E, SourceLocation Loc, bool AllowZero) { assert(E && "Invalid expression"); if (E->isValueDependent()) @@ -3920,7 +3901,13 @@ bool Sema::CheckLoopHintExpr(Expr *E, SourceLocation Loc) { if (R.isInvalid()) return true; - bool ValueIsPositive = ValueAPS.isStrictlyPositive(); + // GCC allows the value of unroll count to be 0. + // https://gcc.gnu.org/onlinedocs/gcc/Loop-Specific-Pragmas.html says + // "The values of 0 and 1 block any unrolling of the loop." + // The values doesn't have to be strictly positive in '#pragma GCC unroll' and + // '#pragma unroll' cases. + bool ValueIsPositive = + AllowZero ? ValueAPS.isNonNegative() : ValueAPS.isStrictlyPositive(); if (!ValueIsPositive || ValueAPS.getActiveBits() > 31) { Diag(E->getExprLoc(), diag::err_pragma_loop_invalid_argument_value) << toString(ValueAPS, 10) << ValueIsPositive; @@ -4150,11 +4137,13 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { // 'wb/uwb' literals are a C23 feature. We support _BitInt as a type in C++, // but we do not currently support the suffix in C++ mode because it's not // entirely clear whether WG21 will prefer this suffix to return a library - // type such as std::bit_int instead of returning a _BitInt. - if (Literal.isBitInt && !getLangOpts().CPlusPlus) - PP.Diag(Tok.getLocation(), getLangOpts().C23 - ? diag::warn_c23_compat_bitint_suffix - : diag::ext_c23_bitint_suffix); + // type such as std::bit_int instead of returning a _BitInt. '__wb/__uwb' + // literals are a C++ extension. + if (Literal.isBitInt) + PP.Diag(Tok.getLocation(), + getLangOpts().CPlusPlus ? diag::ext_cxx_bitint_suffix + : getLangOpts().C23 ? diag::warn_c23_compat_bitint_suffix + : diag::ext_c23_bitint_suffix); // Get the value in the widest-possible width. What is "widest" depends on // whether the literal is a bit-precise integer or not. For a bit-precise diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 7582cbd75fec052abc66f28b322a869f37aa5b23..779a41620033dc6a6cef9d3f7b694a654f6a061a 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1416,26 +1416,42 @@ bool Sema::CheckCXXThisCapture(SourceLocation Loc, const bool Explicit, } ExprResult Sema::ActOnCXXThis(SourceLocation Loc) { - /// C++ 9.3.2: In the body of a non-static member function, the keyword this - /// is a non-lvalue expression whose value is the address of the object for - /// which the function is called. + // C++20 [expr.prim.this]p1: + // The keyword this names a pointer to the object for which an + // implicit object member function is invoked or a non-static + // data member's initializer is evaluated. QualType ThisTy = getCurrentThisType(); - if (ThisTy.isNull()) { - DeclContext *DC = getFunctionLevelDeclContext(); + if (CheckCXXThisType(Loc, ThisTy)) + return ExprError(); - if (const auto *Method = dyn_cast(DC); - Method && Method->isExplicitObjectMemberFunction()) { - return Diag(Loc, diag::err_invalid_this_use) << 1; - } + return BuildCXXThisExpr(Loc, ThisTy, /*IsImplicit=*/false); +} - if (isLambdaCallWithExplicitObjectParameter(CurContext)) - return Diag(Loc, diag::err_invalid_this_use) << 1; +bool Sema::CheckCXXThisType(SourceLocation Loc, QualType Type) { + if (!Type.isNull()) + return false; - return Diag(Loc, diag::err_invalid_this_use) << 0; + // C++20 [expr.prim.this]p3: + // If a declaration declares a member function or member function template + // of a class X, the expression this is a prvalue of type + // "pointer to cv-qualifier-seq X" wherever X is the current class between + // the optional cv-qualifier-seq and the end of the function-definition, + // member-declarator, or declarator. It shall not appear within the + // declaration of either a static member function or an explicit object + // member function of the current class (although its type and value + // category are defined within such member functions as they are within + // an implicit object member function). + DeclContext *DC = getFunctionLevelDeclContext(); + if (const auto *Method = dyn_cast(DC); + Method && Method->isExplicitObjectMemberFunction()) { + Diag(Loc, diag::err_invalid_this_use) << 1; + } else if (isLambdaCallWithExplicitObjectParameter(CurContext)) { + Diag(Loc, diag::err_invalid_this_use) << 1; + } else { + Diag(Loc, diag::err_invalid_this_use) << 0; } - - return BuildCXXThisExpr(Loc, ThisTy, /*IsImplicit=*/false); + return true; } Expr *Sema::BuildCXXThisExpr(SourceLocation Loc, QualType Type, @@ -8644,21 +8660,8 @@ static ExprResult attemptRecovery(Sema &SemaRef, // Detect and handle the case where the decl might be an implicit // member. - bool MightBeImplicitMember; - if (!Consumer.isAddressOfOperand()) - MightBeImplicitMember = true; - else if (!NewSS.isEmpty()) - MightBeImplicitMember = false; - else if (R.isOverloadedResult()) - MightBeImplicitMember = false; - else if (R.isUnresolvableResult()) - MightBeImplicitMember = true; - else - MightBeImplicitMember = isa(ND) || - isa(ND) || - isa(ND); - - if (MightBeImplicitMember) + if (SemaRef.isPotentialImplicitMemberAccess( + NewSS, R, Consumer.isAddressOfOperand())) return SemaRef.BuildPossibleImplicitMemberExpr( NewSS, /*TemplateKWLoc*/ SourceLocation(), R, /*TemplateArgs*/ nullptr, /*S*/ nullptr); diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp index c79128bc8f39e7e97b5273511d6b05f67224aaa2..6e30716b9ae436b3eacec19f76a974734d116a9a 100644 --- a/clang/lib/Sema/SemaExprMember.cpp +++ b/clang/lib/Sema/SemaExprMember.cpp @@ -62,6 +62,10 @@ enum IMAKind { /// The reference is a contextually-permitted abstract member reference. IMA_Abstract, + /// Whether the context is static is dependent on the enclosing template (i.e. + /// in a dependent class scope explicit specialization). + IMA_Dependent, + /// The reference may be to an unresolved using declaration and the /// context is not an instance method. IMA_Unresolved_StaticOrExplicitContext, @@ -92,14 +96,25 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, DeclContext *DC = SemaRef.getFunctionLevelDeclContext(); - bool isStaticOrExplicitContext = - SemaRef.CXXThisTypeOverride.isNull() && - (!isa(DC) || cast(DC)->isStatic() || - cast(DC)->isExplicitObjectMemberFunction()); + bool couldInstantiateToStatic = false; + bool isStaticOrExplicitContext = SemaRef.CXXThisTypeOverride.isNull(); - if (R.isUnresolvableResult()) + if (auto *MD = dyn_cast(DC)) { + if (MD->isImplicitObjectMemberFunction()) { + isStaticOrExplicitContext = false; + // A dependent class scope function template explicit specialization + // that is neither declared 'static' nor with an explicit object + // parameter could instantiate to a static or non-static member function. + couldInstantiateToStatic = MD->getDependentSpecializationInfo(); + } + } + + if (R.isUnresolvableResult()) { + if (couldInstantiateToStatic) + return IMA_Dependent; return isStaticOrExplicitContext ? IMA_Unresolved_StaticOrExplicitContext : IMA_Unresolved; + } // Collect all the declaring classes of instance members we find. bool hasNonInstance = false; @@ -124,6 +139,9 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, if (Classes.empty()) return IMA_Static; + if (couldInstantiateToStatic) + return IMA_Dependent; + // C++11 [expr.prim.general]p12: // An id-expression that denotes a non-static data member or non-static // member function of a class can only be used: @@ -264,21 +282,37 @@ static void diagnoseInstanceReference(Sema &SemaRef, } } +bool Sema::isPotentialImplicitMemberAccess(const CXXScopeSpec &SS, + LookupResult &R, + bool IsAddressOfOperand) { + if (!getLangOpts().CPlusPlus) + return false; + else if (R.empty() || !R.begin()->isCXXClassMember()) + return false; + else if (!IsAddressOfOperand) + return true; + else if (!SS.isEmpty()) + return false; + else if (R.isOverloadedResult()) + return false; + else if (R.isUnresolvableResult()) + return true; + else + return isa(R.getFoundDecl()); +} + /// Builds an expression which might be an implicit member expression. ExprResult Sema::BuildPossibleImplicitMemberExpr( const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, - const TemplateArgumentListInfo *TemplateArgs, const Scope *S, - UnresolvedLookupExpr *AsULE) { - switch (ClassifyImplicitMemberAccess(*this, R)) { + const TemplateArgumentListInfo *TemplateArgs, const Scope *S) { + switch (IMAKind Classification = ClassifyImplicitMemberAccess(*this, R)) { case IMA_Instance: - return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, true, S); - case IMA_Mixed: case IMA_Mixed_Unrelated: case IMA_Unresolved: - return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, false, - S); - + return BuildImplicitMemberExpr( + SS, TemplateKWLoc, R, TemplateArgs, + /*IsKnownInstance=*/Classification == IMA_Instance, S); case IMA_Field_Uneval_Context: Diag(R.getNameLoc(), diag::warn_cxx98_compat_non_static_member_use) << R.getLookupNameInfo().getName(); @@ -288,8 +322,16 @@ ExprResult Sema::BuildPossibleImplicitMemberExpr( case IMA_Mixed_StaticOrExplicitContext: case IMA_Unresolved_StaticOrExplicitContext: if (TemplateArgs || TemplateKWLoc.isValid()) - return BuildTemplateIdExpr(SS, TemplateKWLoc, R, false, TemplateArgs); - return AsULE ? AsULE : BuildDeclarationNameExpr(SS, R, false); + return BuildTemplateIdExpr(SS, TemplateKWLoc, R, /*RequiresADL=*/false, + TemplateArgs); + return BuildDeclarationNameExpr(SS, R, /*NeedsADL=*/false, + /*AcceptInvalidDecl=*/false); + case IMA_Dependent: + R.suppressDiagnostics(); + return UnresolvedLookupExpr::Create( + Context, R.getNamingClass(), SS.getWithLocInContext(Context), + TemplateKWLoc, R.getLookupNameInfo(), /*RequiresADL=*/false, + TemplateArgs, R.begin(), R.end(), /*KnownDependent=*/true); case IMA_Error_StaticOrExplicitContext: case IMA_Error_Unrelated: diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp index 67658c93ed3baff3ff8f19b1982d7251d24e6bf8..ad118ac90e4aa6a23db950cc77e9179f85ea9aa0 100644 --- a/clang/lib/Sema/SemaModule.cpp +++ b/clang/lib/Sema/SemaModule.cpp @@ -1003,6 +1003,10 @@ Decl *Sema::ActOnFinishExportDecl(Scope *S, Decl *D, SourceLocation RBraceLoc) { } } + // Anything exported from a module should never be considered unused. + for (auto *Exported : ED->decls()) + Exported->markUsed(getASTContext()); + return D; } diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp index 190739fa02e9327ad43d16ac3ecbd4e366e719c7..ba69e71e30a181f855f3015c870a201675b37768 100644 --- a/clang/lib/Sema/SemaOpenACC.cpp +++ b/clang/lib/Sema/SemaOpenACC.cpp @@ -91,6 +91,7 @@ bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind, default: return false; } + case OpenACCClauseKind::NumGangs: case OpenACCClauseKind::NumWorkers: case OpenACCClauseKind::VectorLength: switch (DirectiveKind) { @@ -230,6 +231,40 @@ SemaOpenACC::ActOnClause(ArrayRef ExistingClauses, getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getConditionExpr(), Clause.getEndLoc()); } + case OpenACCClauseKind::NumGangs: { + // Restrictions only properly implemented on 'compute' constructs, and + // 'compute' constructs are the only construct that can do anything with + // this yet, so skip/treat as unimplemented in this case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) + break; + + // There is no prose in the standard that says duplicates aren't allowed, + // but this diagnostic is present in other compilers, as well as makes + // sense. + if (checkAlreadyHasClauseOfKind(*this, ExistingClauses, Clause)) + return nullptr; + + if (Clause.getIntExprs().empty()) + Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args) + << /*NoArgs=*/0; + + unsigned MaxArgs = + (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel || + Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) + ? 3 + : 1; + if (Clause.getIntExprs().size() > MaxArgs) + Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args) + << /*NoArgs=*/1 << Clause.getDirectiveKind() << MaxArgs + << Clause.getIntExprs().size(); + + // Create the AST node for the clause even if the number of expressions is + // incorrect. + return OpenACCNumGangsClause::Create( + getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(), + Clause.getIntExprs(), Clause.getEndLoc()); + break; + } case OpenACCClauseKind::NumWorkers: { // Restrictions only properly implemented on 'compute' constructs, and // 'compute' constructs are the only construct that can do anything with diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 3e9f6cba25076d1ccd7b35c000a539e5460642ed..5ba09926acf2b9e92c9eb3bcfc29b004d1fdebd3 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -19354,7 +19354,7 @@ buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, return UnresolvedLookupExpr::Create( SemaRef.Context, /*NamingClass=*/nullptr, ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, - /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); + /*ADL=*/true, ResSet.begin(), ResSet.end(), /*KnownDependent=*/false); } // Lookup inside the classes. // C++ [over.match.oper]p3: @@ -22220,7 +22220,7 @@ static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, return UnresolvedLookupExpr::Create( SemaRef.Context, /*NamingClass=*/nullptr, MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, - /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); + /*ADL=*/false, URS.begin(), URS.end(), /*KnownDependent=*/false); } SourceLocation Loc = MapperId.getLoc(); // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 48d6264029e9bfe900c7c62f2eac399cc1d0661c..04cd9e78739d209b176d8cc5aba80fe87a440762 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -14261,20 +14261,14 @@ ExprResult Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, OverloadResult, AllowTypoCorrection); } -static bool IsOverloaded(const UnresolvedSetImpl &Functions) { - return Functions.size() > 1 || - (Functions.size() == 1 && - isa((*Functions.begin())->getUnderlyingDecl())); -} - ExprResult Sema::CreateUnresolvedLookupExpr(CXXRecordDecl *NamingClass, NestedNameSpecifierLoc NNSLoc, DeclarationNameInfo DNI, const UnresolvedSetImpl &Fns, bool PerformADL) { return UnresolvedLookupExpr::Create(Context, NamingClass, NNSLoc, DNI, - PerformADL, IsOverloaded(Fns), - Fns.begin(), Fns.end()); + PerformADL, Fns.begin(), Fns.end(), + /*KnownDependent=*/false); } ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl, diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index a0339273a0ba35ec6826ae58ab2e9f1e683cf2a0..9d44c22c8ddcc3a234c46af72b16d19e96829d4f 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -109,9 +109,18 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const ParsedAttr &A, SetHints(LoopHintAttr::Unroll, LoopHintAttr::Disable); } else if (PragmaName == "unroll") { // #pragma unroll N - if (ValueExpr) - SetHints(LoopHintAttr::UnrollCount, LoopHintAttr::Numeric); - else + if (ValueExpr && !ValueExpr->isValueDependent()) { + llvm::APSInt ValueAPS; + ExprResult R = S.VerifyIntegerConstantExpression(ValueExpr, &ValueAPS); + assert(!R.isInvalid() && "unroll count value must be a valid value, it's " + "should be checked in Sema::CheckLoopHintExpr"); + (void)R; + // The values of 0 and 1 block any unrolling of the loop. + if (ValueAPS.isZero() || ValueAPS.isOne()) + SetHints(LoopHintAttr::UnrollCount, LoopHintAttr::Disable); + else + SetHints(LoopHintAttr::UnrollCount, LoopHintAttr::Numeric); + } else SetHints(LoopHintAttr::Unroll, LoopHintAttr::Enable); } else if (PragmaName == "nounroll_and_jam") { SetHints(LoopHintAttr::UnrollAndJam, LoopHintAttr::Disable); @@ -142,7 +151,8 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const ParsedAttr &A, if (Option == LoopHintAttr::VectorizeWidth) { assert((ValueExpr || (StateLoc && StateLoc->Ident)) && "Attribute must have a valid value expression or argument."); - if (ValueExpr && S.CheckLoopHintExpr(ValueExpr, St->getBeginLoc())) + if (ValueExpr && S.CheckLoopHintExpr(ValueExpr, St->getBeginLoc(), + /*AllowZero=*/false)) return nullptr; if (StateLoc && StateLoc->Ident && StateLoc->Ident->isStr("scalable")) State = LoopHintAttr::ScalableWidth; @@ -152,7 +162,8 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const ParsedAttr &A, Option == LoopHintAttr::UnrollCount || Option == LoopHintAttr::PipelineInitiationInterval) { assert(ValueExpr && "Attribute must have a valid value expression."); - if (S.CheckLoopHintExpr(ValueExpr, St->getBeginLoc())) + if (S.CheckLoopHintExpr(ValueExpr, St->getBeginLoc(), + /*AllowZero=*/false)) return nullptr; State = LoopHintAttr::Numeric; } else if (Option == LoopHintAttr::Vectorize || diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index d4976f9d0d11d81e8b06f7321034bef56403243b..4bda31ba67c02d03e1d9323fdef4d3e763ca871c 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -2962,19 +2962,6 @@ void DeclareImplicitDeductionGuidesForTypeAlias( Context.getCanonicalTemplateArgument( Context.getInjectedTemplateArg(NewParam)); } - // Substitute new template parameters into requires-clause if present. - Expr *RequiresClause = - transformRequireClause(SemaRef, F, TemplateArgsForBuildingFPrime); - // FIXME: implement the is_deducible constraint per C++ - // [over.match.class.deduct]p3.3: - // ... and a constraint that is satisfied if and only if the arguments - // of A are deducible (see below) from the return type. - auto *FPrimeTemplateParamList = TemplateParameterList::Create( - Context, AliasTemplate->getTemplateParameters()->getTemplateLoc(), - AliasTemplate->getTemplateParameters()->getLAngleLoc(), - FPrimeTemplateParams, - AliasTemplate->getTemplateParameters()->getRAngleLoc(), - /*RequiresClause=*/RequiresClause); // To form a deduction guide f' from f, we leverage clang's instantiation // mechanism, we construct a template argument list where the template @@ -3020,6 +3007,20 @@ void DeclareImplicitDeductionGuidesForTypeAlias( F, TemplateArgListForBuildingFPrime, AliasTemplate->getLocation(), Sema::CodeSynthesisContext::BuildingDeductionGuides)) { auto *GG = cast(FPrime); + // Substitute new template parameters into requires-clause if present. + Expr *RequiresClause = + transformRequireClause(SemaRef, F, TemplateArgsForBuildingFPrime); + // FIXME: implement the is_deducible constraint per C++ + // [over.match.class.deduct]p3.3: + // ... and a constraint that is satisfied if and only if the arguments + // of A are deducible (see below) from the return type. + auto *FPrimeTemplateParamList = TemplateParameterList::Create( + Context, AliasTemplate->getTemplateParameters()->getTemplateLoc(), + AliasTemplate->getTemplateParameters()->getLAngleLoc(), + FPrimeTemplateParams, + AliasTemplate->getTemplateParameters()->getRAngleLoc(), + /*RequiresClause=*/RequiresClause); + buildDeductionGuide(SemaRef, AliasTemplate, FPrimeTemplateParamList, GG->getCorrespondingConstructor(), GG->getExplicitSpecifier(), GG->getTypeSourceInfo(), diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 7cd428de0bb32d2a29d36e1bf60b638b0bd6b315..98d5c7cb3a8a808d203ccd97e07614c5bad7e60d 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2150,7 +2150,8 @@ TemplateInstantiator::TransformLoopHintAttr(const LoopHintAttr *LH) { return LH; // Generate error if there is a problem with the value. - if (getSema().CheckLoopHintExpr(TransformedExpr, LH->getLocation())) + if (getSema().CheckLoopHintExpr(TransformedExpr, LH->getLocation(), + LH->getOption() == LoopHintAttr::UnrollCount)) return LH; // Create new LoopHintValueAttr with integral expression in place of the @@ -2501,10 +2502,7 @@ TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB, assert(Arg.getKind() == TemplateArgument::Type && "unexpected nontype template argument kind in template rewrite"); QualType NewT = Arg.getAsType(); - assert(isa(NewT) && - "type parm not rewritten to type parm"); - auto NewTL = TLB.push(NewT); - NewTL.setNameLoc(TL.getNameLoc()); + TLB.pushTrivial(SemaRef.Context, NewT, TL.getNameLoc()); return NewT; } diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index caa07abb61fe349b91ec5aeb101dde2da5725328..787a485e0b2f8c36f9526e3d3f2b5728e68329a6 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -5101,6 +5101,14 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, EnterExpressionEvaluationContext EvalContext( *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated); + Qualifiers ThisTypeQuals; + CXXRecordDecl *ThisContext = nullptr; + if (CXXMethodDecl *Method = dyn_cast(Function)) { + ThisContext = Method->getParent(); + ThisTypeQuals = Method->getMethodQualifiers(); + } + CXXThisScopeRAII ThisScope(*this, ThisContext, ThisTypeQuals); + // Introduce a new scope where local variable instantiations will be // recorded, unless we're actually a member function within a local // class, in which case we need to merge our results with the parent diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index 4909414c0c78d44851e609bbdee99e4ccc213d5e..a4b681ae4f008ec81c6f967fe8935f4080109a9c 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -1085,9 +1085,11 @@ ExprResult Sema::ActOnPackIndexingExpr(Scope *S, Expr *PackExpression, SourceLocation RSquareLoc) { bool isParameterPack = ::isParameterPack(PackExpression); if (!isParameterPack) { - CorrectDelayedTyposInExpr(IndexExpr); - Diag(PackExpression->getBeginLoc(), diag::err_expected_name_of_pack) - << PackExpression; + if (!PackExpression->containsErrors()) { + CorrectDelayedTyposInExpr(IndexExpr); + Diag(PackExpression->getBeginLoc(), diag::err_expected_name_of_pack) + << PackExpression; + } return ExprError(); } ExprResult Res = diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index ade33ec65038fdb3abc6b10708aec3f7a898163b..9404be5a46f3f73d503fe298e94ca7a0aaae384b 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -796,6 +796,9 @@ public: ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI); + ExprResult TransformUnresolvedLookupExpr(UnresolvedLookupExpr *E, + bool IsAddressOfOperand); + StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S); // FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous @@ -3320,12 +3323,13 @@ public: /// Build a new C++ "this" expression. /// - /// By default, builds a new "this" expression without performing any - /// semantic analysis. Subclasses may override this routine to provide - /// different behavior. + /// By default, performs semantic analysis to build a new "this" expression. + /// Subclasses may override this routine to provide different behavior. ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc, QualType ThisType, bool isImplicit) { + if (getSema().CheckCXXThisType(ThisLoc, ThisType)) + return ExprError(); return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit); } @@ -4759,8 +4763,6 @@ public: const TemplateArgumentLoc *operator->() const { return &Arg; } }; - TemplateArgumentLocInventIterator() { } - explicit TemplateArgumentLocInventIterator(TreeTransform &Self, InputIterator Iter) : Self(Self), Iter(Iter) { } @@ -10429,12 +10431,11 @@ TreeTransform::TransformOMPReductionClause(OMPReductionClause *C) { cast(getDerived().TransformDecl(E->getExprLoc(), D)); Decls.addDecl(InstD, InstD->getAccess()); } - UnresolvedReductions.push_back( - UnresolvedLookupExpr::Create( + UnresolvedReductions.push_back(UnresolvedLookupExpr::Create( SemaRef.Context, /*NamingClass=*/nullptr, - ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), - NameInfo, /*ADL=*/true, ULE->isOverloaded(), - Decls.begin(), Decls.end())); + ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo, + /*ADL=*/true, Decls.begin(), Decls.end(), + /*KnownDependent=*/false)); } else UnresolvedReductions.push_back(nullptr); } @@ -10480,7 +10481,8 @@ OMPClause *TreeTransform::TransformOMPTaskReductionClause( UnresolvedReductions.push_back(UnresolvedLookupExpr::Create( SemaRef.Context, /*NamingClass=*/nullptr, ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo, - /*ADL=*/true, ULE->isOverloaded(), Decls.begin(), Decls.end())); + /*ADL=*/true, Decls.begin(), Decls.end(), + /*KnownDependent=*/false)); } else UnresolvedReductions.push_back(nullptr); } @@ -10525,7 +10527,8 @@ TreeTransform::TransformOMPInReductionClause(OMPInReductionClause *C) { UnresolvedReductions.push_back(UnresolvedLookupExpr::Create( SemaRef.Context, /*NamingClass=*/nullptr, ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo, - /*ADL=*/true, ULE->isOverloaded(), Decls.begin(), Decls.end())); + /*ADL=*/true, Decls.begin(), Decls.end(), + /*KnownDependent=*/false)); } else UnresolvedReductions.push_back(nullptr); } @@ -10706,8 +10709,8 @@ bool transformOMPMappableExprListClause( UnresolvedMappers.push_back(UnresolvedLookupExpr::Create( TT.getSema().Context, /*NamingClass=*/nullptr, MapperIdScopeSpec.getWithLocInContext(TT.getSema().Context), - MapperIdInfo, /*ADL=*/true, ULE->isOverloaded(), Decls.begin(), - Decls.end())); + MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(), + /*KnownDependent=*/false)); } else { UnresolvedMappers.push_back(nullptr); } @@ -11159,6 +11162,32 @@ void OpenACCClauseTransform::VisitSelfClause( ParsedClause.getEndLoc()); } +template +void OpenACCClauseTransform::VisitNumGangsClause( + const OpenACCNumGangsClause &C) { + llvm::SmallVector InstantiatedIntExprs; + + for (Expr *CurIntExpr : C.getIntExprs()) { + ExprResult Res = Self.TransformExpr(CurIntExpr); + + if (!Res.isUsable()) + return; + + Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid, + C.getClauseKind(), + C.getBeginLoc(), Res.get()); + if (!Res.isUsable()) + return; + + InstantiatedIntExprs.push_back(Res.get()); + } + + ParsedClause.setIntExprDetails(InstantiatedIntExprs); + NewClause = OpenACCNumGangsClause::Create( + Self.getSema().getASTContext(), ParsedClause.getBeginLoc(), + ParsedClause.getLParenLoc(), ParsedClause.getIntExprs(), + ParsedClause.getEndLoc()); +} template void OpenACCClauseTransform::VisitNumWorkersClause( const OpenACCNumWorkersClause &C) { @@ -11467,7 +11496,11 @@ template ExprResult TreeTransform::TransformAddressOfOperand(Expr *E) { if (DependentScopeDeclRefExpr *DRE = dyn_cast(E)) - return getDerived().TransformDependentScopeDeclRefExpr(DRE, true, nullptr); + return getDerived().TransformDependentScopeDeclRefExpr( + DRE, /*IsAddressOfOperand=*/true, nullptr); + else if (UnresolvedLookupExpr *ULE = dyn_cast(E)) + return getDerived().TransformUnresolvedLookupExpr( + ULE, /*IsAddressOfOperand=*/true); else return getDerived().TransformExpr(E); } @@ -13174,10 +13207,16 @@ bool TreeTransform::TransformOverloadExprDecls(OverloadExpr *Old, return false; } -template +template +ExprResult TreeTransform::TransformUnresolvedLookupExpr( + UnresolvedLookupExpr *Old) { + return TransformUnresolvedLookupExpr(Old, /*IsAddressOfOperand=*/false); +} + +template ExprResult -TreeTransform::TransformUnresolvedLookupExpr( - UnresolvedLookupExpr *Old) { +TreeTransform::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old, + bool IsAddressOfOperand) { LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(), Sema::LookupOrdinaryName); @@ -13209,26 +13248,8 @@ TreeTransform::TransformUnresolvedLookupExpr( R.setNamingClass(NamingClass); } + // Rebuild the template arguments, if any. SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc(); - - // If we have neither explicit template arguments, nor the template keyword, - // it's a normal declaration name or member reference. - if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid()) { - NamedDecl *D = R.getAsSingle(); - // In a C++11 unevaluated context, an UnresolvedLookupExpr might refer to an - // instance member. In other contexts, BuildPossibleImplicitMemberExpr will - // give a good diagnostic. - if (D && D->isCXXInstanceMember()) { - return SemaRef.BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, R, - /*TemplateArgs=*/nullptr, - /*Scope=*/nullptr); - } - - return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL()); - } - - // If we have template arguments, rebuild them, then rebuild the - // templateid expression. TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc()); if (Old->hasExplicitTemplateArgs() && getDerived().TransformTemplateArguments(Old->getTemplateArgs(), @@ -13238,6 +13259,23 @@ TreeTransform::TransformUnresolvedLookupExpr( return ExprError(); } + // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when + // a non-static data member is named in an unevaluated operand, or when + // a member is named in a dependent class scope function template explicit + // specialization that is neither declared static nor with an explicit object + // parameter. + if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand)) + return SemaRef.BuildPossibleImplicitMemberExpr( + SS, TemplateKWLoc, R, + Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr, + /*S=*/nullptr); + + // If we have neither explicit template arguments, nor the template keyword, + // it's a normal declaration name or member reference. + if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid()) + return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL()); + + // If we have template arguments, then rebuild the template-id expression. return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R, Old->requiresADL(), &TransArgs); } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 44e23919ea18e0aea165d30555fd4728869ec612..d64925676df7b153159263251b8bf06e30a48589 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -11786,6 +11786,15 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() { return OpenACCSelfClause::Create(getContext(), BeginLoc, LParenLoc, CondExpr, EndLoc); } + case OpenACCClauseKind::NumGangs: { + SourceLocation LParenLoc = readSourceLocation(); + unsigned NumClauses = readInt(); + llvm::SmallVector IntExprs; + for (unsigned I = 0; I < NumClauses; ++I) + IntExprs.push_back(readSubExpr()); + return OpenACCNumGangsClause::Create(getContext(), BeginLoc, LParenLoc, + IntExprs, EndLoc); + } case OpenACCClauseKind::NumWorkers: { SourceLocation LParenLoc = readSourceLocation(); Expr *IntExpr = readSubExpr(); @@ -11826,7 +11835,6 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() { case OpenACCClauseKind::Reduction: case OpenACCClauseKind::Collapse: case OpenACCClauseKind::Bind: - case OpenACCClauseKind::NumGangs: case OpenACCClauseKind::DeviceNum: case OpenACCClauseKind::DefaultAsync: case OpenACCClauseKind::DeviceType: diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index ca0460800898b3292e2b70758b96eb3d803b5659..baded0fe19831ff62d6b8d5739093fcad8407b20 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -2096,7 +2096,6 @@ void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) { VisitOverloadExpr(E); E->UnresolvedLookupExprBits.RequiresADL = CurrentUnpackingBits->getNextBit(); - E->UnresolvedLookupExprBits.Overloaded = CurrentUnpackingBits->getNextBit(); E->NamingClass = readDeclAs(); } diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 6dd87b5d200db6141dfb58ec7e56b8ff95c0bda1..018b854652a46e054d2faadb3dcec39eda92d03b 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -166,9 +166,9 @@ namespace { std::optional> GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) { - // Without implicit module map search, there's no good reason to know about - // any module maps that are not affecting. - if (!PP.getHeaderSearchInfo().getHeaderSearchOpts().ImplicitModuleMaps) + if (!PP.getHeaderSearchInfo() + .getHeaderSearchOpts() + .ModulesPruneNonAffectingModuleMaps) return std::nullopt; SmallVector ModulesToProcess{RootModule}; @@ -7657,6 +7657,14 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) { AddStmt(const_cast(SC->getConditionExpr())); return; } + case OpenACCClauseKind::NumGangs: { + const auto *NGC = cast(C); + writeSourceLocation(NGC->getLParenLoc()); + writeUInt32(NGC->getIntExprs().size()); + for (Expr *E : NGC->getIntExprs()) + AddStmt(E); + return; + } case OpenACCClauseKind::NumWorkers: { const auto *NWC = cast(C); writeSourceLocation(NWC->getLParenLoc()); @@ -7697,7 +7705,6 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) { case OpenACCClauseKind::Reduction: case OpenACCClauseKind::Collapse: case OpenACCClauseKind::Bind: - case OpenACCClauseKind::NumGangs: case OpenACCClauseKind::DeviceNum: case OpenACCClauseKind::DefaultAsync: case OpenACCClauseKind::DeviceType: diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index a736a7b0ef726ca5a40745d058b8dbda492beb5d..cd5f733baf76f4e5d6cfb3004d2fd375fa2281b6 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -2082,7 +2082,6 @@ void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) { VisitOverloadExpr(E); CurrentPackingBits.addBit(E->requiresADL()); - CurrentPackingBits.addBit(E->isOverloaded()); Record.AddDeclRef(E->getNamingClass()); Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP; } diff --git a/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp index f02d20d45678b3bd4cc4edd2ffecb8aa6dc7416c..c7479d74eafc3349b507b06f5629c83a53a806dc 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp @@ -56,23 +56,23 @@ public: private: // These are known in the LLVM project. The pairs are in the following form: - // {{{namespace, call}, argument-count}, {callback, kind}} + // {{match-mode, {namespace, call}, argument-count}, {callback, kind}} const CallDescriptionMap> CDM = { - {{{"llvm", "cast"}, 1}, + {{CDM::SimpleFunc, {"llvm", "cast"}, 1}, {&CastValueChecker::evalCast, CallKind::Function}}, - {{{"llvm", "dyn_cast"}, 1}, + {{CDM::SimpleFunc, {"llvm", "dyn_cast"}, 1}, {&CastValueChecker::evalDynCast, CallKind::Function}}, - {{{"llvm", "cast_or_null"}, 1}, + {{CDM::SimpleFunc, {"llvm", "cast_or_null"}, 1}, {&CastValueChecker::evalCastOrNull, CallKind::Function}}, - {{{"llvm", "dyn_cast_or_null"}, 1}, + {{CDM::SimpleFunc, {"llvm", "dyn_cast_or_null"}, 1}, {&CastValueChecker::evalDynCastOrNull, CallKind::Function}}, - {{{"clang", "castAs"}, 0}, + {{CDM::CXXMethod, {"clang", "castAs"}, 0}, {&CastValueChecker::evalCastAs, CallKind::Method}}, - {{{"clang", "getAs"}, 0}, + {{CDM::CXXMethod, {"clang", "getAs"}, 0}, {&CastValueChecker::evalGetAs, CallKind::Method}}, - {{{"llvm", "isa"}, 1}, + {{CDM::SimpleFunc, {"llvm", "isa"}, 1}, {&CastValueChecker::evalIsa, CallKind::InstanceOf}}, - {{{"llvm", "isa_and_nonnull"}, 1}, + {{CDM::SimpleFunc, {"llvm", "isa_and_nonnull"}, 1}, {&CastValueChecker::evalIsaAndNonNull, CallKind::InstanceOf}}}; void evalCast(const CallEvent &Call, DefinedOrUnknownSVal DV, diff --git a/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp index be7be15022d360d665b63777cbb7a588cdd3f9e5..3a0a01c23de03eebef3e3ef32527650cf5d84032 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp @@ -43,7 +43,8 @@ class ChrootChecker : public Checker { // This bug refers to possibly break out of a chroot() jail. const BugType BT_BreakJail{this, "Break out of jail"}; - const CallDescription Chroot{{"chroot"}, 1}, Chdir{{"chdir"}, 1}; + const CallDescription Chroot{CDM::CLibrary, {"chroot"}, 1}, + Chdir{CDM::CLibrary, {"chdir"}, 1}; public: ChrootChecker() {} diff --git a/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp index c46ebee0c94ff48eefc47295fc2a3976d2c3ae6b..6076a6bc789737a8f9bf823ec80726740f8f9c5c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp @@ -70,13 +70,15 @@ private: using EvalFn = std::function; const CallDescriptionMap TestCalls{ - {{{"ErrnoTesterChecker_setErrno"}, 1}, &ErrnoTesterChecker::evalSetErrno}, - {{{"ErrnoTesterChecker_getErrno"}, 0}, &ErrnoTesterChecker::evalGetErrno}, - {{{"ErrnoTesterChecker_setErrnoIfError"}, 0}, + {{CDM::SimpleFunc, {"ErrnoTesterChecker_setErrno"}, 1}, + &ErrnoTesterChecker::evalSetErrno}, + {{CDM::SimpleFunc, {"ErrnoTesterChecker_getErrno"}, 0}, + &ErrnoTesterChecker::evalGetErrno}, + {{CDM::SimpleFunc, {"ErrnoTesterChecker_setErrnoIfError"}, 0}, &ErrnoTesterChecker::evalSetErrnoIfError}, - {{{"ErrnoTesterChecker_setErrnoIfErrorRange"}, 0}, + {{CDM::SimpleFunc, {"ErrnoTesterChecker_setErrnoIfErrorRange"}, 0}, &ErrnoTesterChecker::evalSetErrnoIfErrorRange}, - {{{"ErrnoTesterChecker_setErrnoCheckState"}, 0}, + {{CDM::SimpleFunc, {"ErrnoTesterChecker_setErrnoCheckState"}, 0}, &ErrnoTesterChecker::evalSetErrnoCheckState}}; }; diff --git a/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp index 2e31c16e457c2e4566cd75f326c3d7bd66740654..cd1dd1b2fc511fd27af989998eb837de9aa7f070 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp @@ -27,8 +27,8 @@ using namespace ento; namespace { class MmapWriteExecChecker : public Checker { - CallDescription MmapFn; - CallDescription MprotectFn; + CallDescription MmapFn{CDM::CLibrary, {"mmap"}, 6}; + CallDescription MprotectFn{CDM::CLibrary, {"mprotect"}, 3}; static int ProtWrite; static int ProtExec; static int ProtRead; @@ -36,7 +36,6 @@ class MmapWriteExecChecker : public Checker { "Security"}; public: - MmapWriteExecChecker() : MmapFn({"mmap"}, 6), MprotectFn({"mprotect"}, 3) {} void checkPreCall(const CallEvent &Call, CheckerContext &C) const; int ProtExecOv; int ProtReadOv; diff --git a/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp index f7b7befe28ee7dc5076c51c359a5b9b7a592977f..19877964bd900a9c4758337b6618e273d1070769 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp @@ -129,9 +129,11 @@ static llvm::StringRef indefiniteArticleBasedOnVowel(char a) { class StdVariantChecker : public Checker { // Call descriptors to find relevant calls - CallDescription VariantConstructor{{"std", "variant", "variant"}}; - CallDescription VariantAssignmentOperator{{"std", "variant", "operator="}}; - CallDescription StdGet{{"std", "get"}, 1, 1}; + CallDescription VariantConstructor{CDM::CXXMethod, + {"std", "variant", "variant"}}; + CallDescription VariantAssignmentOperator{CDM::CXXMethod, + {"std", "variant", "operator="}}; + CallDescription StdGet{CDM::SimpleFunc, {"std", "get"}, 1, 1}; BugType BadVariantType{this, "BadVariantType", "BadVariantType"}; @@ -295,4 +297,4 @@ bool clang::ento::shouldRegisterStdVariantChecker( void clang::ento::registerStdVariantChecker(clang::ento::CheckerManager &mgr) { mgr.registerChecker(); -} \ No newline at end of file +} diff --git a/clang/lib/StaticAnalyzer/Checkers/StringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StringChecker.cpp index 2dc9e29ca90688cf81b6a3fba1e08d79220e70c9..8f1c31763e212c31b37cf9d7eede11bce628ad38 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StringChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StringChecker.cpp @@ -27,7 +27,7 @@ class StringChecker : public Checker { mutable const FunctionDecl *StringConstCharPtrCtor = nullptr; mutable CanQualType SizeTypeTy; const CallDescription TwoParamStdStringCtor = { - {"std", "basic_string", "basic_string"}, 2, 2}; + CDM::CXXMethod, {"std", "basic_string", "basic_string"}, 2, 2}; bool isCharToStringCtor(const CallEvent &Call, const ASTContext &ACtx) const; diff --git a/clang/lib/StaticAnalyzer/Checkers/cert/PutenvWithAutoChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/cert/PutenvWithAutoChecker.cpp index eae162cda6931073b0d965a8b006f30f59e28fe4..a82f7caf16b291f2b018671658fe62d044105551 100644 --- a/clang/lib/StaticAnalyzer/Checkers/cert/PutenvWithAutoChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/cert/PutenvWithAutoChecker.cpp @@ -30,7 +30,7 @@ class PutenvWithAutoChecker : public Checker { private: BugType BT{this, "'putenv' function should not be called with auto variables", categories::SecurityError}; - const CallDescription Putenv{{"putenv"}, 1}; + const CallDescription Putenv{CDM::CLibrary, {"putenv"}, 1}; public: void checkPostCall(const CallEvent &Call, CheckerContext &C) const; diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index ebba181eb2d842b4f05baa56d196c7d8997e02c0..ba29c12313901686c5939a20dbeadc8610971fad 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -2358,11 +2358,12 @@ StoreRef RegionStoreManager::killBinding(Store ST, Loc L) { RegionBindingsRef RegionStoreManager::bind(RegionBindingsConstRef B, Loc L, SVal V) { - if (L.getAs()) + // We only care about region locations. + auto MemRegVal = L.getAs(); + if (!MemRegVal) return B; - // If we get here, the location should be a region. - const MemRegion *R = L.castAs().getRegion(); + const MemRegion *R = MemRegVal->getRegion(); // Check if the region is a struct region. if (const TypedValueRegion* TR = dyn_cast(R)) { diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp index e19f19b2528c1540912bc3fe359a0193fe66c977..f46324ee9989eb87ad06a28a344f9c0cf8431b22 100644 --- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -179,6 +179,11 @@ makeCommonInvocationForModuleBuild(CompilerInvocation CI) { CI.resetNonModularOptions(); CI.clearImplicitModuleBuildOptions(); + // The scanner takes care to avoid passing non-affecting module maps to the + // explicit compiles. No need to do extra work just to find out there are no + // module map files to prune. + CI.getHeaderSearchOpts().ModulesPruneNonAffectingModuleMaps = false; + // Remove options incompatible with explicit module build or are likely to // differ between identical modules discovered from different translation // units. diff --git a/clang/test/AST/Interp/builtin-functions.cpp b/clang/test/AST/Interp/builtin-functions.cpp index 1a29a664d7ce5497495b4948484b4707b63e4fed..0cbab1fcd91d091ce85d7ce0afaaecca85cfa148 100644 --- a/clang/test/AST/Interp/builtin-functions.cpp +++ b/clang/test/AST/Interp/builtin-functions.cpp @@ -633,3 +633,9 @@ void test7(void) { X = CFSTR("foo", "bar"); // both-error {{too many arguments to function call}} #endif } + +/// The actual value on my machine is 22, but I have a feeling this will be different +/// on other targets, so just checking for != 0 here. Light testing is fine since +/// the actual implementation uses analyze_os_log::computeOSLogBufferLayout(), which +/// is tested elsewhere. +static_assert(__builtin_os_log_format_buffer_size("%{mask.xyz}s", "abc") != 0, ""); diff --git a/clang/test/AST/Interp/c.c b/clang/test/AST/Interp/c.c index 5ae9b1dc7bff869ba6586737d847bc75d3c2ea67..a5951158ed0e0d808303711ae1e69475fd006015 100644 --- a/clang/test/AST/Interp/c.c +++ b/clang/test/AST/Interp/c.c @@ -257,3 +257,9 @@ int Y __attribute__((annotate( 42, (struct TestStruct) { .a = 1, .b = 2 } ))); + +#ifdef __SIZEOF_INT128__ +const int *p = &b; +const __int128 K = (__int128)(int*)0; +const unsigned __int128 KU = (unsigned __int128)(int*)0; +#endif diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index 277438d2e6311431e60bb3c81a08261cf568e17a..2688b53adde2483bb801715f151f23ee44578926 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -1209,4 +1209,16 @@ constexpr int externvar1() { // both-error {{never produces a constant expressio namespace Extern { constexpr extern char Oops = 1; static_assert(Oops == 1, ""); + +#if __cplusplus >= 201402L + struct NonLiteral { + NonLiteral() {} + }; + NonLiteral nl; + constexpr NonLiteral &ExternNonLiteralVarDecl() { + extern NonLiteral nl; + return nl; + } + static_assert(&ExternNonLiteralVarDecl() == &nl, ""); +#endif } diff --git a/clang/test/AST/Interp/vectors.cpp b/clang/test/AST/Interp/vectors.cpp index 5c4694f122d812b6beae8f9a05670cb6e4ca52e3..49dae14fcf646f1e7b4fec1f641dc7e8b1be5893 100644 --- a/clang/test/AST/Interp/vectors.cpp +++ b/clang/test/AST/Interp/vectors.cpp @@ -8,6 +8,13 @@ static_assert(A[1] == 2, ""); // ref-error {{not an integral constant expression static_assert(A[2] == 3, ""); // ref-error {{not an integral constant expression}} static_assert(A[3] == 4, ""); // ref-error {{not an integral constant expression}} + +/// FIXME: It would be nice if the note said 'vector' instead of 'array'. +static_assert(A[12] == 4, ""); // ref-error {{not an integral constant expression}} \ + // expected-error {{not an integral constant expression}} \ + // expected-note {{cannot refer to element 12 of array of 4 elements in a constant expression}} + + /// VectorSplat casts typedef __attribute__(( ext_vector_type(4) )) float float4; constexpr float4 vec4_0 = (float4)0.5f; @@ -18,6 +25,19 @@ static_assert(vec4_0[3] == 0.5, ""); // ref-error {{not an integral constant exp constexpr int vec4_0_discarded = ((float4)12.0f, 0); +/// ImplicitValueInitExpr of vector type +constexpr float4 arr4[2] = { + {1,2,3,4}, +}; +static_assert(arr4[0][0] == 1, ""); // ref-error {{not an integral constant expression}} +static_assert(arr4[0][1] == 2, ""); // ref-error {{not an integral constant expression}} +static_assert(arr4[0][2] == 3, ""); // ref-error {{not an integral constant expression}} +static_assert(arr4[0][3] == 4, ""); // ref-error {{not an integral constant expression}} +static_assert(arr4[1][0] == 0, ""); // ref-error {{not an integral constant expression}} +static_assert(arr4[1][0] == 0, ""); // ref-error {{not an integral constant expression}} +static_assert(arr4[1][0] == 0, ""); // ref-error {{not an integral constant expression}} +static_assert(arr4[1][0] == 0, ""); // ref-error {{not an integral constant expression}} + /// From constant-expression-cxx11.cpp namespace Vector { diff --git a/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp b/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp index 8c03b58abb0edb6a81a290ff714e87441f0b07cf..cf740516db6f4b4e7d5b8459b7c8327835bc4d4c 100644 --- a/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp +++ b/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp @@ -2725,7 +2725,25 @@ int main() // CHECK-NEXT: "type": { // CHECK-NEXT: "qualType": "bool" // CHECK-NEXT: }, -// CHECK-NEXT: "valueCategory": "prvalue" +// CHECK-NEXT: "valueCategory": "prvalue", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "TemplateTypeParmType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "_Ty" +// CHECK-NEXT: }, +// CHECK-NEXT: "isDependent": true, +// CHECK-NEXT: "isInstantiationDependent": true, +// CHECK-NEXT: "depth": 0, +// CHECK-NEXT: "index": 0, +// CHECK-NEXT: "decl": { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "TemplateTypeParmDecl", +// CHECK-NEXT: "name": "_Ty" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -3003,7 +3021,25 @@ int main() // CHECK-NEXT: "type": { // CHECK-NEXT: "qualType": "bool" // CHECK-NEXT: }, -// CHECK-NEXT: "valueCategory": "prvalue" +// CHECK-NEXT: "valueCategory": "prvalue", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "TemplateTypeParmType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "_Ty" +// CHECK-NEXT: }, +// CHECK-NEXT: "isDependent": true, +// CHECK-NEXT: "isInstantiationDependent": true, +// CHECK-NEXT: "depth": 0, +// CHECK-NEXT: "index": 0, +// CHECK-NEXT: "decl": { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "TemplateTypeParmDecl", +// CHECK-NEXT: "name": "_Ty" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } diff --git a/clang/test/AST/ast-dump-traits.cpp b/clang/test/AST/ast-dump-traits.cpp index 99ad50f528eb796b1c35ebcae705680f19f633d9..3085e5883fd2e2836eea3932b4edc7c73cb07dfc 100644 --- a/clang/test/AST/ast-dump-traits.cpp +++ b/clang/test/AST/ast-dump-traits.cpp @@ -40,10 +40,19 @@ void test_unary_expr_or_type_trait() { // CHECK-NEXT: | | `-EnumDecl {{.*}} col:8{{( imported)?}} referenced E // CHECK-NEXT: | |-CStyleCastExpr {{.*}} 'void' // CHECK-NEXT: | | `-TypeTraitExpr {{.*}} 'bool' __is_enum +// CHECK-NEXT: | | `-ElaboratedType {{.*}} 'E' sugar +// CHECK-NEXT: | | `-EnumType {{.*}} 'E' +// CHECK-NEXT: | | `-Enum {{.*}} 'E' // CHECK-NEXT: | |-CStyleCastExpr {{.*}} 'void' // CHECK-NEXT: | | `-TypeTraitExpr {{.*}} 'bool' __is_same +// CHECK-NEXT: | | |-BuiltinType {{.*}} 'int' +// CHECK-NEXT: | | `-BuiltinType {{.*}} 'float' // CHECK-NEXT: | `-CStyleCastExpr {{.*}} 'void' // CHECK-NEXT: | `-TypeTraitExpr {{.*}} 'bool' __is_constructible +// CHECK-NEXT: |-BuiltinType {{.*}} 'int' +// CHECK-NEXT: |-BuiltinType {{.*}} 'int' +// CHECK-NEXT: |-BuiltinType {{.*}} 'int' +// CHECK-NEXT: `-BuiltinType {{.*}} 'int' // CHECK-NEXT: |-FunctionDecl {{.*}} line:20:6{{( imported)?}} test_array_type_trait 'void ()' // CHECK-NEXT: | `-CompoundStmt {{.*}} // CHECK-NEXT: | `-CStyleCastExpr {{.*}} 'void' diff --git a/clang/test/AST/bitint-suffix.cpp b/clang/test/AST/bitint-suffix.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dab2b16c74235d3438381dec8dd3f144a940c96b --- /dev/null +++ b/clang/test/AST/bitint-suffix.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -ast-dump -Wno-unused %s | FileCheck --strict-whitespace %s + +// CHECK: FunctionDecl 0x{{[^ ]*}} <{{.*}}:[[@LINE+1]]:1, line:{{[0-9]*}}:1> line:[[@LINE+1]]:6 func 'void ()' +void func() { + // Ensure that we calculate the correct type from the literal suffix. + + // Note: 0__wb should create an _BitInt(2) because a signed bit-precise + // integer requires one bit for the sign and one bit for the value, + // at a minimum. + // CHECK: TypedefDecl 0x{{[^ ]*}} col:29 zero_wb 'typeof (0wb)':'_BitInt(2)' + typedef __typeof__(0__wb) zero_wb; + // CHECK: TypedefDecl 0x{{[^ ]*}} col:30 neg_zero_wb 'typeof (-0wb)':'_BitInt(2)' + typedef __typeof__(-0__wb) neg_zero_wb; + // CHECK: TypedefDecl 0x{{[^ ]*}} col:29 one_wb 'typeof (1wb)':'_BitInt(2)' + typedef __typeof__(1__wb) one_wb; + // CHECK: TypedefDecl 0x{{[^ ]*}} col:30 neg_one_wb 'typeof (-1wb)':'_BitInt(2)' + typedef __typeof__(-1__wb) neg_one_wb; + + // CHECK: TypedefDecl 0x{{[^ ]*}} col:30 zero_uwb 'typeof (0uwb)':'unsigned _BitInt(1)' + typedef __typeof__(0__uwb) zero_uwb; + // CHECK: TypedefDecl 0x{{[^ ]*}} col:31 neg_zero_uwb 'typeof (-0uwb)':'unsigned _BitInt(1)' + typedef __typeof__(-0__uwb) neg_zero_uwb; + // CHECK: TypedefDecl 0x{{[^ ]*}} col:30 one_uwb 'typeof (1uwb)':'unsigned _BitInt(1)' + typedef __typeof__(1__uwb) one_uwb; + + // Try a value that is too large to fit in [u]intmax_t. + + // CHECK: TypedefDecl 0x{{[^ ]*}} col:49 huge_uwb 'typeof (18446744073709551616uwb)':'unsigned _BitInt(65)' + typedef __typeof__(18446744073709551616__uwb) huge_uwb; + // CHECK: TypedefDecl 0x{{[^ ]*}} col:48 huge_wb 'typeof (18446744073709551616wb)':'_BitInt(66)' + typedef __typeof__(18446744073709551616__wb) huge_wb; +} diff --git a/clang/test/Analysis/gh-issue-89185.c b/clang/test/Analysis/gh-issue-89185.c new file mode 100644 index 0000000000000000000000000000000000000000..8a907f198a5fd5321e03ba061ef708cf0df6011c --- /dev/null +++ b/clang/test/Analysis/gh-issue-89185.c @@ -0,0 +1,14 @@ +// 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}} + // FIXME: We should never reach here, as storing to a label is invalid. +} diff --git a/clang/test/ClangScanDeps/modules-full.cpp b/clang/test/ClangScanDeps/modules-full.cpp index 59efef0ecbaa64fce41cfe3b474d1642e6718055..a00a431eb56911ca52c740ece5254ca364bcf9ae 100644 --- a/clang/test/ClangScanDeps/modules-full.cpp +++ b/clang/test/ClangScanDeps/modules-full.cpp @@ -33,6 +33,7 @@ // CHECK-NEXT: "command-line": [ // CHECK-NEXT: "-cc1" // CHECK: "-emit-module" +// CHECK: "-fno-modules-prune-non-affecting-module-map-files" // CHECK: "-fmodule-file={{.*}}[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H2_DINCLUDE]]/header2-{{[A-Z0-9]+}}.pcm" // CHECK-NOT: "-fimplicit-module-maps" // CHECK: "-fmodule-name=header1" @@ -51,6 +52,7 @@ // CHECK-NEXT: "command-line": [ // CHECK-NEXT: "-cc1", // CHECK: "-emit-module", +// CHECK: "-fno-modules-prune-non-affecting-module-map-files" // CHECK-NOT: "-fimplicit-module-maps", // CHECK: "-fmodule-name=header1", // CHECK: "-fno-implicit-modules", @@ -68,6 +70,7 @@ // CHECK-NEXT: "command-line": [ // CHECK-NEXT: "-cc1", // CHECK: "-emit-module", +// CHECK: "-fno-modules-prune-non-affecting-module-map-files" // CHECK: "-fmodule-name=header2", // CHECK-NOT: "-fimplicit-module-maps", // CHECK: "-fno-implicit-modules", diff --git a/clang/test/CodeGen/PowerPC/builtins-ppc-htm.c b/clang/test/CodeGen/PowerPC/builtins-ppc-htm.c index 51585f27e0bc70d6e76cfccc25b4b02efdaf5b73..eeb13b097819cdba0b055f16b577eaa44158f316 100644 --- a/clang/test/CodeGen/PowerPC/builtins-ppc-htm.c +++ b/clang/test/CodeGen/PowerPC/builtins-ppc-htm.c @@ -1,6 +1,6 @@ // REQUIRES: powerpc-registered-target // RUN: %clang_cc1 -target-feature +altivec -target-feature +htm -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck %s -// RUN: not %clang_cc1 -target-feature +altivec -target-feature -htm -triple powerpc64-unknown-unknown -emit-llvm %s 2>&1 | FileCheck %s --check-prefix=ERROR +// RUN: not %clang_cc1 -target-feature +altivec -target-feature -htm -triple powerpc64-unknown-unknown -emit-llvm-only %s 2>&1 | FileCheck %s --check-prefix=ERROR void test1(long int *r, int code, long int *a, long int *b) { // CHECK-LABEL: define{{.*}} void @test1 diff --git a/clang/test/CodeGen/PowerPC/builtins-ppc-vec-ins-error.c b/clang/test/CodeGen/PowerPC/builtins-ppc-vec-ins-error.c index f5149bf4ce8fda723c2551df55ca61df143d17db..485ef84df086b7a64feceecd8ac2539011caea5a 100644 --- a/clang/test/CodeGen/PowerPC/builtins-ppc-vec-ins-error.c +++ b/clang/test/CodeGen/PowerPC/builtins-ppc-vec-ins-error.c @@ -1,17 +1,17 @@ // REQUIRES: powerpc-registered-target // RUN: %clang_cc1 -flax-vector-conversions=none -target-feature +vsx -target-cpu pwr10 -fsyntax-only \ -// RUN: -triple powerpc64le-unknown-unknown -emit-llvm -ferror-limit 10 %s -verify -D __TEST_ELT_SI +// RUN: -triple powerpc64le-unknown-unknown -emit-llvm-only -ferror-limit 10 %s -verify -D __TEST_ELT_SI // RUN: %clang_cc1 -flax-vector-conversions=none -target-feature +vsx -target-cpu pwr10 -fsyntax-only \ -// RUN: -triple powerpc64-unknown-unknown -emit-llvm -ferror-limit 10 %s -verify -D __TEST_ELT_F +// RUN: -triple powerpc64-unknown-unknown -emit-llvm-only -ferror-limit 10 %s -verify -D __TEST_ELT_F // RUN: %clang_cc1 -flax-vector-conversions=none -target-feature +vsx -target-cpu pwr10 -fsyntax-only \ -// RUN: -triple powerpc64le-unknown-unknown -emit-llvm -ferror-limit 10 %s -verify -D __TEST_ELT_SLL +// RUN: -triple powerpc64le-unknown-unknown -emit-llvm-only -ferror-limit 10 %s -verify -D __TEST_ELT_SLL // RUN: %clang_cc1 -flax-vector-conversions=none -target-feature +vsx -target-cpu pwr10 -fsyntax-only \ -// RUN: -triple powerpc64-unknown-unknown -emit-llvm -ferror-limit 10 %s -verify -D __TEST_ELT_D +// RUN: -triple powerpc64-unknown-unknown -emit-llvm-only -ferror-limit 10 %s -verify -D __TEST_ELT_D // RUN: %clang_cc1 -flax-vector-conversions=none -target-feature +vsx -target-cpu pwr10 -fsyntax-only \ -// RUN: -triple powerpc64le-unknown-unknown -emit-llvm -ferror-limit 10 %s -verify -D __TEST_UNALIGNED_UI +// RUN: -triple powerpc64le-unknown-unknown -emit-llvm-only -ferror-limit 10 %s -verify -D __TEST_UNALIGNED_UI // RUN: %clang_cc1 -flax-vector-conversions=none -target-feature +vsx -target-cpu pwr10 -fsyntax-only \ -// RUN: -triple powerpc64-unknown-unknown -emit-llvm -ferror-limit 10 %s -verify +// RUN: -triple powerpc64-unknown-unknown -emit-llvm-only -ferror-limit 10 %s -verify #include diff --git a/clang/test/CodeGen/RISCV/riscv-func-attr-target-err.c b/clang/test/CodeGen/RISCV/riscv-func-attr-target-err.c index b303d71304bf3ece9b14905e395618055f66a48a..66d15a7d1bc052a602522bc937d4d2e4113e3737 100644 --- a/clang/test/CodeGen/RISCV/riscv-func-attr-target-err.c +++ b/clang/test/CodeGen/RISCV/riscv-func-attr-target-err.c @@ -1,6 +1,6 @@ // REQUIRES: riscv-registered-target // RUN: not %clang_cc1 -triple riscv64 -target-feature +zifencei -target-feature +m -target-feature +a \ -// RUN: -emit-llvm %s 2>&1 | FileCheck %s +// RUN: -emit-llvm-only %s 2>&1 | FileCheck %s #include diff --git a/clang/test/CodeGen/attr-counted-by-pr88931.c b/clang/test/CodeGen/attr-counted-by-pr88931.c new file mode 100644 index 0000000000000000000000000000000000000000..cc3d751c7c6d83823fc22ad829a5cb6a44814b0e --- /dev/null +++ b/clang/test/CodeGen/attr-counted-by-pr88931.c @@ -0,0 +1,40 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -Wno-missing-declarations -emit-llvm -o - %s | FileCheck %s + +struct foo { + int x,y,z; + struct bar { + int count; + int array[] __attribute__((counted_by(count))); + }; +}; + +void init(void * __attribute__((pass_dynamic_object_size(0)))); + +// CHECK-LABEL: define dso_local void @test1( +// CHECK-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 4 +// CHECK-NEXT: tail call void @init(ptr noundef nonnull [[ARRAY]], i64 noundef -1) #[[ATTR2:[0-9]+]] +// CHECK-NEXT: ret void +// +void test1(struct bar *p) { + init(p->array); +} + +struct mux { + int count; + int array[] __attribute__((counted_by(count))); +}; + +struct bux { struct mux x; }; + +// CHECK-LABEL: define dso_local void @test2( +// CHECK-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @init(ptr noundef [[P]], i64 noundef -1) #[[ATTR2]] +// CHECK-NEXT: ret void +// +void test2(struct bux *p) { + init(p); +} diff --git a/clang/test/CodeGen/attr-counted-by-pr88931.cpp b/clang/test/CodeGen/attr-counted-by-pr88931.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2a8cc1d07e50d9acc22ec64cb92b04e455f0e37c --- /dev/null +++ b/clang/test/CodeGen/attr-counted-by-pr88931.cpp @@ -0,0 +1,21 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -Wall -emit-llvm -o - %s | FileCheck %s + +struct foo { + struct bar { + int array[]; + bar(); + }; +}; + +void init(void * __attribute__((pass_dynamic_object_size(0)))); + +// CHECK-LABEL: define dso_local void @_ZN3foo3barC1Ev( +// CHECK-SAME: ptr noundef nonnull align 4 dereferenceable(1) [[THIS:%.*]]) unnamed_addr #[[ATTR0:[0-9]+]] align 2 { +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @_Z4initPvU25pass_dynamic_object_size0(ptr noundef nonnull [[THIS]], i64 noundef -1) #[[ATTR2:[0-9]+]] +// CHECK-NEXT: ret void +// +foo::bar::bar() { + init(array); +} diff --git a/clang/test/CodeGen/debug-info-file-checksum.c b/clang/test/CodeGen/debug-info-file-checksum.c index e018dbf64fc98f2b7a09cf8483d34ba9848a62b4..2ca91d605d1c4b06d953179477fee5a0bed60639 100644 --- a/clang/test/CodeGen/debug-info-file-checksum.c +++ b/clang/test/CodeGen/debug-info-file-checksum.c @@ -1,3 +1,6 @@ +// AIX does not support -gdwarf-5. +// UNSUPPORTED: target={{.*}}-aix{{.*}} + // RUN: %clang -emit-llvm -S -g -gcodeview -x c \ // RUN: %S/Inputs/debug-info-file-checksum.c -o - | FileCheck %s // RUN: %clang -emit-llvm -S -g -gcodeview -Xclang -gsrc-hash=md5 \ diff --git a/clang/test/CodeGen/dwarf-version.c b/clang/test/CodeGen/dwarf-version.c index e63316ace69c872979fff06730c7a27ab3c21e05..258c258e5f5a26f46d8efec747bfb19abaa1aae0 100644 --- a/clang/test/CodeGen/dwarf-version.c +++ b/clang/test/CodeGen/dwarf-version.c @@ -46,8 +46,10 @@ // RUN: FileCheck %s --check-prefix=VER3 // RUN: %clang -target powerpc-ibm-aix-xcoff -gdwarf-4 -S -emit-llvm -o - %s | \ // RUN: FileCheck %s --check-prefix=VER4 -// RUN: %clang -target powerpc-ibm-aix-xcoff -gdwarf-5 -S -emit-llvm -o - %s | \ -// RUN: FileCheck %s --check-prefix=VER5 +// RUN: not %clang -target powerpc-ibm-aix-xcoff -gdwarf-5 -S -emit-llvm -o - %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=UNSUPPORTED-VER5 +// RUN: not %clang -target powerpc64-ibm-aix-xcoff -gdwarf-5 -S -emit-llvm -o - %s 2>&1| \ +// RUN: FileCheck %s --check-prefix=UNSUPPORTED-VER5 int main (void) { return 0; @@ -59,6 +61,7 @@ int main (void) { // VER3: !{i32 7, !"Dwarf Version", i32 3} // VER4: !{i32 7, !"Dwarf Version", i32 4} // VER5: !{i32 7, !"Dwarf Version", i32 5} +// UNSUPPORTED-VER5: error: unsupported option '-gdwarf-5' // NODWARF-NOT: !"Dwarf Version" // CODEVIEW: !{i32 2, !"CodeView", i32 1} diff --git a/clang/test/CodeGen/pgo-force-function-attrs.ll b/clang/test/CodeGen/pgo-force-function-attrs.ll new file mode 100644 index 0000000000000000000000000000000000000000..3e9ea95e4df410db9f897991398d23ede9f69b23 --- /dev/null +++ b/clang/test/CodeGen/pgo-force-function-attrs.ll @@ -0,0 +1,12 @@ +; RUN: %clang_cc1 -O2 -mllvm -pgo-cold-func-opt=optsize -mllvm -enable-pgo-force-function-attrs -fprofile-sample-use=%S/Inputs/pgo-sample.prof %s -emit-llvm -o - | FileCheck %s --check-prefix=OPTSIZE +; Check that no profile means no optsize +; RUN: %clang_cc1 -O2 -mllvm -pgo-cold-func-opt=optsize -mllvm -enable-pgo-force-function-attrs %s -emit-llvm -o - | FileCheck %s --check-prefix=NONE +; Check that no -pgo-cold-func-opt=optsize means no optsize +; RUN: %clang_cc1 -O2 -mllvm -enable-pgo-force-function-attrs -fprofile-sample-use=%S/Inputs/pgo-sample.prof %s -emit-llvm -o - | FileCheck %s --check-prefix=NONE + +; NONE-NOT: optsize +; OPTSIZE: optsize + +define void @f() cold { + ret void +} diff --git a/clang/test/CodeGen/ubsan-shift-bitint.c b/clang/test/CodeGen/ubsan-shift-bitint.c index 844d5c4ad846188fc01d0d2d695df8851cac310c..af65ed60918b0884db3d2aed77a0c71dcc715781 100644 --- a/clang/test/CodeGen/ubsan-shift-bitint.c +++ b/clang/test/CodeGen/ubsan-shift-bitint.c @@ -6,14 +6,14 @@ // CHECK-LABEL: define{{.*}} i32 @test_left_variable int test_left_variable(unsigned _BitInt(5) b, unsigned _BitInt(2) e) { // CHECK: [[E_REG:%.+]] = load [[E_SIZE:i2]] - // CHECK: icmp ule [[E_SIZE]] [[E_REG]], -1 + // CHECK: icmp ule [[E_SIZE]] [[E_REG]], -1, return b << e; } // CHECK-LABEL: define{{.*}} i32 @test_right_variable int test_right_variable(unsigned _BitInt(2) b, unsigned _BitInt(3) e) { // CHECK: [[E_REG:%.+]] = load [[E_SIZE:i3]] - // CHECK: icmp ule [[E_SIZE]] [[E_REG]], 1 + // CHECK: icmp ule [[E_SIZE]] [[E_REG]], 1, return b >> e; } @@ -34,3 +34,32 @@ int test_right_literal(unsigned _BitInt(2) b) { // CHECK: br i1 false, label %cont, label %handler.shift_out_of_bounds return b >> 4uwb; } + +// CHECK-LABEL: define{{.*}} i32 @test_signed_left_variable +int test_signed_left_variable(unsigned _BitInt(15) b, _BitInt(2) e) { + // CHECK: [[E_REG:%.+]] = load [[E_SIZE:i2]] + // CHECK: icmp ule [[E_SIZE]] [[E_REG]], 1, + return b << e; +} + +// CHECK-LABEL: define{{.*}} i32 @test_signed_right_variable +int test_signed_right_variable(unsigned _BitInt(32) b, _BitInt(4) e) { + // CHECK: [[E_REG:%.+]] = load [[E_SIZE:i4]] + // CHECK: icmp ule [[E_SIZE]] [[E_REG]], 7, + return b >> e; +} + +// CHECK-LABEL: define{{.*}} i32 @test_signed_left_literal +int test_signed_left_literal(unsigned _BitInt(16) b) { + // CHECK-NOT: br i1 true, label %cont, label %handler.shift_out_of_bounds + // CHECK: br i1 false, label %cont, label %handler.shift_out_of_bounds + return b << (_BitInt(4))-2wb; +} + +// CHECK-LABEL: define{{.*}} i32 @test_signed_right_literal +int test_signed_right_literal(unsigned _BitInt(16) b) { + // CHECK-NOT: br i1 true, label %cont, label %handler.shift_out_of_bounds + // CHECK: br i1 false, label %cont, label %handler.shift_out_of_bounds + return b >> (_BitInt(4))-8wb; +} + diff --git a/clang/test/CodeGenCXX/mangle-lambdas-gh88906.cpp b/clang/test/CodeGenCXX/mangle-lambdas-gh88906.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e7592cec5da776dea7aed148f86a1f4b2b66d78a --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-lambdas-gh88906.cpp @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu %s -emit-llvm -mconstructor-aliases -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -fclang-abi-compat=18 %s -emit-llvm -mconstructor-aliases -o - | FileCheck --check-prefix=CLANG18 %s +// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -mconstructor-aliases -o - | FileCheck --check-prefix=MSABI %s + + +class func { +public: + template + func(T){}; + template + func(T, U){}; +}; + +void GH88906(){ + class Test{ + public: + func a{[]{ }, []{ }}; + func b{[]{ }}; + func c{[]{ }}; + } test; +} + +// CHECK-LABEL: define internal void @_ZZ7GH88906vEN4TestC2Ev +// CHECK: call void @_ZN4funcC2IN7GH889064Test1aMUlvE_ENS3_UlvE0_EEET_T0_ +// CHECK: call void @_ZN4funcC2IN7GH889064Test1bMUlvE_EEET_ +// CHECK: call void @_ZN4funcC2IN7GH889064Test1cMUlvE_EEET_ + +// CHECK-LABEL: define internal void @_ZN4funcC2IN7GH889064Test1aMUlvE_ENS3_UlvE0_EEET_T0_ +// CHECK-LABEL: define internal void @_ZN4funcC2IN7GH889064Test1bMUlvE_EEET_ +// CHECK-LABEL: define internal void @_ZN4funcC2IN7GH889064Test1cMUlvE_EEET_ + +// CLANG18-LABEL: define internal void @_ZZ7GH88906vEN4TestC2Ev +// CLANG18: call void @_ZN4funcC2IZ7GH88906vEN4TestUlvE_EZ7GH88906vENS1_UlvE0_EEET_T0_ +// CLANG18: call void @_ZN4funcC2IZ7GH88906vEN4TestUlvE_EEET_ +// CLANG18: call void @_ZN4funcC2IZ7GH88906vEN4TestUlvE_EEET_ + + + +// MSABI-LABEL: define internal x86_thiscallcc noundef ptr @"??0Test@?1??GH88906@@YAXXZ@QAE@XZ" +// MSABI: call x86_thiscallcc noundef ptr @"??$?0V@a@Test@?1??GH88906@@YAXXZ@V@12?1??3@YAXXZ@@func@@QAE@V@a@Test@?1??GH88906@@YAXXZ@V@23?1??4@YAXXZ@@Z" +// MSABI: call x86_thiscallcc noundef ptr @"??$?0V@b@Test@?1??GH88906@@YAXXZ@@func@@QAE@V@b@Test@?1??GH88906@@YAXXZ@@Z" +// MSABI: call x86_thiscallcc noundef ptr @"??$?0V@c@Test@?1??GH88906@@YAXXZ@@func@@QAE@V@c@Test@?1??GH88906@@YAXXZ@@Z" + +// MSABI-LABEL: define internal x86_thiscallcc noundef ptr @"??$?0V@a@Test@?1??GH88906@@YAXXZ@V@12?1??3@YAXXZ@@func@@QAE@V@a@Test@?1??GH88906@@YAXXZ@V@23?1??4@YAXXZ@@Z" +// MSABI-LABEL: define internal x86_thiscallcc noundef ptr @"??$?0V@b@Test@?1??GH88906@@YAXXZ@@func@@QAE@V@b@Test@?1??GH88906@@YAXXZ@@Z" +// MSABI-LABEL: define internal x86_thiscallcc noundef ptr @"??$?0V@c@Test@?1??GH88906@@YAXXZ@@func@@QAE@V@c@Test@?1??GH88906@@YAXXZ@@Z" diff --git a/clang/test/CodeGenCXX/pragma-gcc-unroll.cpp b/clang/test/CodeGenCXX/pragma-gcc-unroll.cpp index ed75e0b6e3c364bd388fd423510b787f313abacb..8a94a5cc91e2396356d6733af6ef518071a92198 100644 --- a/clang/test/CodeGenCXX/pragma-gcc-unroll.cpp +++ b/clang/test/CodeGenCXX/pragma-gcc-unroll.cpp @@ -96,6 +96,26 @@ void template_test(double *List, int Length) { for_template_define_test(List, Length, Value); } +void for_unroll_zero_test(int *List, int Length) { + // CHECK: define {{.*}} @_Z20for_unroll_zero_testPii + #pragma GCC unroll 0 + for (int i = 0; i < Length; i++) { + // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_14:.*]] + List[i] = i * 2; + } +} + +void while_unroll_zero_test(int *List, int Length) { + // CHECK: define {{.*}} @_Z22while_unroll_zero_testPii + int i = 0; +#pragma GCC unroll(0) + while (i < Length) { + // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_15:.*]] + List[i] = i * 2; + i++; + } +} + // CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], [[MP:![0-9]+]], ![[UNROLL_ENABLE:.*]]} // CHECK: ![[UNROLL_ENABLE]] = !{!"llvm.loop.unroll.enable"} // CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2:.*]], ![[UNROLL_DISABLE:.*]]} @@ -107,3 +127,5 @@ void template_test(double *List, int Length) { // CHECK: ![[LOOP_5]] = distinct !{![[LOOP_5]], ![[UNROLL_8:.*]]} // CHECK: ![[LOOP_6]] = distinct !{![[LOOP_6]], ![[UNROLL_8:.*]]} // CHECK: ![[LOOP_7]] = distinct !{![[LOOP_7]], ![[UNROLL_8:.*]]} +// CHECK: ![[LOOP_14]] = distinct !{![[LOOP_14]], [[MP]], ![[UNROLL_DISABLE:.*]]} +// CHECK: ![[LOOP_15]] = distinct !{![[LOOP_15]], [[MP]], ![[UNROLL_DISABLE:.*]]} diff --git a/clang/test/CodeGenHLSL/builtins/lerp-builtin.hlsl b/clang/test/CodeGenHLSL/builtins/lerp-builtin.hlsl index 2fd5a19fc33521641ef04a378b33eef7586f36a6..cdc9abbd70e40bb926a4257e78abb6e94b779e96 100644 --- a/clang/test/CodeGenHLSL/builtins/lerp-builtin.hlsl +++ b/clang/test/CodeGenHLSL/builtins/lerp-builtin.hlsl @@ -1,15 +1,15 @@ // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -o - | FileCheck %s // CHECK-LABEL: builtin_lerp_half_vector -// CHECK: %dx.lerp = call <3 x half> @llvm.dx.lerp.v3f16(<3 x half> %0, <3 x half> %1, <3 x half> %2) -// CHECK: ret <3 x half> %dx.lerp +// CHECK: %hlsl.lerp = call <3 x half> @llvm.dx.lerp.v3f16(<3 x half> %0, <3 x half> %1, <3 x half> %2) +// CHECK: ret <3 x half> %hlsl.lerp half3 builtin_lerp_half_vector (half3 p0) { return __builtin_hlsl_lerp ( p0, p0, p0 ); } // CHECK-LABEL: builtin_lerp_floar_vector -// CHECK: %dx.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) -// CHECK: ret <2 x float> %dx.lerp +// CHECK: %hlsl.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) +// CHECK: ret <2 x float> %hlsl.lerp float2 builtin_lerp_floar_vector ( float2 p0) { return __builtin_hlsl_lerp ( p0, p0, p0 ); } diff --git a/clang/test/CodeGenHLSL/builtins/lerp.hlsl b/clang/test/CodeGenHLSL/builtins/lerp.hlsl index 49cd04a10115aee13f70700baddee400b6013d62..634b20be3a28d6d1a005ae8952d8fb121890f9a9 100644 --- a/clang/test/CodeGenHLSL/builtins/lerp.hlsl +++ b/clang/test/CodeGenHLSL/builtins/lerp.hlsl @@ -1,69 +1,92 @@ // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ -// RUN: --check-prefixes=CHECK,NATIVE_HALF +// RUN: --check-prefixes=CHECK,DXIL_CHECK,DXIL_NATIVE_HALF,NATIVE_HALF // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ -// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF +// RUN: -o - | FileCheck %s --check-prefixes=CHECK,DXIL_CHECK,NO_HALF,DXIL_NO_HALF +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ +// RUN: --check-prefixes=CHECK,NATIVE_HALF,SPIR_NATIVE_HALF,SPIR_CHECK +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ +// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF,SPIR_NO_HALF,SPIR_CHECK -// NATIVE_HALF: %dx.lerp = call half @llvm.dx.lerp.f16(half %0, half %1, half %2) -// NATIVE_HALF: ret half %dx.lerp -// NO_HALF: %dx.lerp = call float @llvm.dx.lerp.f32(float %0, float %1, float %2) -// NO_HALF: ret float %dx.lerp +// DXIL_NATIVE_HALF: %hlsl.lerp = call half @llvm.dx.lerp.f16(half %0, half %1, half %2) +// SPIR_NATIVE_HALF: %hlsl.lerp = call half @llvm.spv.lerp.f16(half %0, half %1, half %2) +// NATIVE_HALF: ret half %hlsl.lerp +// DXIL_NO_HALF: %hlsl.lerp = call float @llvm.dx.lerp.f32(float %0, float %1, float %2) +// SPIR_NO_HALF: %hlsl.lerp = call float @llvm.spv.lerp.f32(float %0, float %1, float %2) +// NO_HALF: ret float %hlsl.lerp half test_lerp_half(half p0) { return lerp(p0, p0, p0); } -// NATIVE_HALF: %dx.lerp = call <2 x half> @llvm.dx.lerp.v2f16(<2 x half> %0, <2 x half> %1, <2 x half> %2) -// NATIVE_HALF: ret <2 x half> %dx.lerp -// NO_HALF: %dx.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) -// NO_HALF: ret <2 x float> %dx.lerp +// DXIL_NATIVE_HALF: %hlsl.lerp = call <2 x half> @llvm.dx.lerp.v2f16(<2 x half> %0, <2 x half> %1, <2 x half> %2) +// SPIR_NATIVE_HALF: %hlsl.lerp = call <2 x half> @llvm.spv.lerp.v2f16(<2 x half> %0, <2 x half> %1, <2 x half> %2) +// NATIVE_HALF: ret <2 x half> %hlsl.lerp +// DXIL_NO_HALF: %hlsl.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) +// SPIR_NO_HALF: %hlsl.lerp = call <2 x float> @llvm.spv.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) +// NO_HALF: ret <2 x float> %hlsl.lerp half2 test_lerp_half2(half2 p0) { return lerp(p0, p0, p0); } -// NATIVE_HALF: %dx.lerp = call <3 x half> @llvm.dx.lerp.v3f16(<3 x half> %0, <3 x half> %1, <3 x half> %2) -// NATIVE_HALF: ret <3 x half> %dx.lerp -// NO_HALF: %dx.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %2) -// NO_HALF: ret <3 x float> %dx.lerp +// DXIL_NATIVE_HALF: %hlsl.lerp = call <3 x half> @llvm.dx.lerp.v3f16(<3 x half> %0, <3 x half> %1, <3 x half> %2) +// SPIR_NATIVE_HALF: %hlsl.lerp = call <3 x half> @llvm.spv.lerp.v3f16(<3 x half> %0, <3 x half> %1, <3 x half> %2) +// NATIVE_HALF: ret <3 x half> %hlsl.lerp +// DXIL_NO_HALF: %hlsl.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %2) +// SPIR_NO_HALF: %hlsl.lerp = call <3 x float> @llvm.spv.lerp.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %2) +// NO_HALF: ret <3 x float> %hlsl.lerp half3 test_lerp_half3(half3 p0) { return lerp(p0, p0, p0); } -// NATIVE_HALF: %dx.lerp = call <4 x half> @llvm.dx.lerp.v4f16(<4 x half> %0, <4 x half> %1, <4 x half> %2) -// NATIVE_HALF: ret <4 x half> %dx.lerp -// NO_HALF: %dx.lerp = call <4 x float> @llvm.dx.lerp.v4f32(<4 x float> %0, <4 x float> %1, <4 x float> %2) -// NO_HALF: ret <4 x float> %dx.lerp +// DXIL_NATIVE_HALF: %hlsl.lerp = call <4 x half> @llvm.dx.lerp.v4f16(<4 x half> %0, <4 x half> %1, <4 x half> %2) +// SPIR_NATIVE_HALF: %hlsl.lerp = call <4 x half> @llvm.spv.lerp.v4f16(<4 x half> %0, <4 x half> %1, <4 x half> %2) +// NATIVE_HALF: ret <4 x half> %hlsl.lerp +// DXIL_NO_HALF: %hlsl.lerp = call <4 x float> @llvm.dx.lerp.v4f32(<4 x float> %0, <4 x float> %1, <4 x float> %2) +// SPIR_NO_HALF: %hlsl.lerp = call <4 x float> @llvm.spv.lerp.v4f32(<4 x float> %0, <4 x float> %1, <4 x float> %2) +// NO_HALF: ret <4 x float> %hlsl.lerp half4 test_lerp_half4(half4 p0) { return lerp(p0, p0, p0); } -// CHECK: %dx.lerp = call float @llvm.dx.lerp.f32(float %0, float %1, float %2) -// CHECK: ret float %dx.lerp +// DXIL_CHECK: %hlsl.lerp = call float @llvm.dx.lerp.f32(float %0, float %1, float %2) +// SPIR_CHECK: %hlsl.lerp = call float @llvm.spv.lerp.f32(float %0, float %1, float %2) +// CHECK: ret float %hlsl.lerp float test_lerp_float(float p0) { return lerp(p0, p0, p0); } -// CHECK: %dx.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) -// CHECK: ret <2 x float> %dx.lerp +// DXIL_CHECK: %hlsl.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) +// SPIR_CHECK: %hlsl.lerp = call <2 x float> @llvm.spv.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) +// CHECK: ret <2 x float> %hlsl.lerp float2 test_lerp_float2(float2 p0) { return lerp(p0, p0, p0); } -// CHECK: %dx.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %2) -// CHECK: ret <3 x float> %dx.lerp +// DXIL_CHECK: %hlsl.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %2) +// SPIR_CHECK: %hlsl.lerp = call <3 x float> @llvm.spv.lerp.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %2) +// CHECK: ret <3 x float> %hlsl.lerp float3 test_lerp_float3(float3 p0) { return lerp(p0, p0, p0); } -// CHECK: %dx.lerp = call <4 x float> @llvm.dx.lerp.v4f32(<4 x float> %0, <4 x float> %1, <4 x float> %2) -// CHECK: ret <4 x float> %dx.lerp +// DXIL_CHECK: %hlsl.lerp = call <4 x float> @llvm.dx.lerp.v4f32(<4 x float> %0, <4 x float> %1, <4 x float> %2) +// SPIR_CHECK: %hlsl.lerp = call <4 x float> @llvm.spv.lerp.v4f32(<4 x float> %0, <4 x float> %1, <4 x float> %2) +// CHECK: ret <4 x float> %hlsl.lerp float4 test_lerp_float4(float4 p0) { return lerp(p0, p0, p0); } -// CHECK: %dx.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %splat.splat, <2 x float> %1, <2 x float> %2) -// CHECK: ret <2 x float> %dx.lerp +// DXIL_CHECK: %hlsl.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %splat.splat, <2 x float> %1, <2 x float> %2) +// SPIR_CHECK: %hlsl.lerp = call <2 x float> @llvm.spv.lerp.v2f32(<2 x float> %splat.splat, <2 x float> %1, <2 x float> %2) +// CHECK: ret <2 x float> %hlsl.lerp float2 test_lerp_float2_splat(float p0, float2 p1) { return lerp(p0, p1, p1); } -// CHECK: %dx.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %splat.splat, <3 x float> %1, <3 x float> %2) -// CHECK: ret <3 x float> %dx.lerp +// DXIL_CHECK: %hlsl.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %splat.splat, <3 x float> %1, <3 x float> %2) +// SPIR_CHECK: %hlsl.lerp = call <3 x float> @llvm.spv.lerp.v3f32(<3 x float> %splat.splat, <3 x float> %1, <3 x float> %2) +// CHECK: ret <3 x float> %hlsl.lerp float3 test_lerp_float3_splat(float p0, float3 p1) { return lerp(p0, p1, p1); } -// CHECK: %dx.lerp = call <4 x float> @llvm.dx.lerp.v4f32(<4 x float> %splat.splat, <4 x float> %1, <4 x float> %2) -// CHECK: ret <4 x float> %dx.lerp +// DXIL_CHECK: %hlsl.lerp = call <4 x float> @llvm.dx.lerp.v4f32(<4 x float> %splat.splat, <4 x float> %1, <4 x float> %2) +// SPIR_CHECK: %hlsl.lerp = call <4 x float> @llvm.spv.lerp.v4f32(<4 x float> %splat.splat, <4 x float> %1, <4 x float> %2) +// CHECK: ret <4 x float> %hlsl.lerp float4 test_lerp_float4_splat(float p0, float4 p1) { return lerp(p0, p1, p1); } // CHECK: %conv = sitofp i32 %2 to float // CHECK: %splat.splatinsert = insertelement <2 x float> poison, float %conv, i64 0 // CHECK: %splat.splat = shufflevector <2 x float> %splat.splatinsert, <2 x float> poison, <2 x i32> zeroinitializer -// CHECK: %dx.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %splat.splat) -// CHECK: ret <2 x float> %dx.lerp +// DXIL_CHECK: %hlsl.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %splat.splat) +// SPIR_CHECK: %hlsl.lerp = call <2 x float> @llvm.spv.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %splat.splat) +// CHECK: ret <2 x float> %hlsl.lerp float2 test_lerp_float2_int_splat(float2 p0, int p1) { return lerp(p0, p0, p1); } @@ -71,8 +94,9 @@ float2 test_lerp_float2_int_splat(float2 p0, int p1) { // CHECK: %conv = sitofp i32 %2 to float // CHECK: %splat.splatinsert = insertelement <3 x float> poison, float %conv, i64 0 // CHECK: %splat.splat = shufflevector <3 x float> %splat.splatinsert, <3 x float> poison, <3 x i32> zeroinitializer -// CHECK: %dx.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %splat.splat) -// CHECK: ret <3 x float> %dx.lerp +// DXIL_CHECK: %hlsl.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %splat.splat) +// SPIR_CHECK: %hlsl.lerp = call <3 x float> @llvm.spv.lerp.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %splat.splat) +// CHECK: ret <3 x float> %hlsl.lerp float3 test_lerp_float3_int_splat(float3 p0, int p1) { return lerp(p0, p0, p1); } diff --git a/clang/test/CodeGenHLSL/builtins/mad.hlsl b/clang/test/CodeGenHLSL/builtins/mad.hlsl index 749eac6d64736d476ee76b4c12648f08de4de091..bd4f38067a5c59fe50bbd6bb76e8961ae4ee38df 100644 --- a/clang/test/CodeGenHLSL/builtins/mad.hlsl +++ b/clang/test/CodeGenHLSL/builtins/mad.hlsl @@ -1,182 +1,238 @@ // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ -// RUN: --check-prefixes=CHECK,NATIVE_HALF +// RUN: --check-prefixes=CHECK,DXIL_CHECK,DXIL_NATIVE_HALF,NATIVE_HALF // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ -// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF +// RUN: -o - | FileCheck %s --check-prefixes=CHECK,DXIL_CHECK,NO_HALF + +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ +// RUN: --check-prefixes=CHECK,NATIVE_HALF,SPIR_NATIVE_HALF,SPIR_CHECK +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ +// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF,SPIR_CHECK #ifdef __HLSL_ENABLE_16_BIT -// NATIVE_HALF: %dx.umad = call i16 @llvm.dx.umad.i16(i16 %0, i16 %1, i16 %2) -// NATIVE_HALF: ret i16 %dx.umad +// DXIL_NATIVE_HALF: %dx.umad = call i16 @llvm.dx.umad.i16(i16 %0, i16 %1, i16 %2) +// DXIL_NATIVE_HALF: ret i16 %dx.umad +// SPIR_NATIVE_HALF: mul nuw i16 %{{.*}}, %{{.*}} +// SPIR_NATIVE_HALF: add nuw i16 %{{.*}}, %{{.*}} uint16_t test_mad_uint16_t(uint16_t p0, uint16_t p1, uint16_t p2) { return mad(p0, p1, p2); } -// NATIVE_HALF: %dx.umad = call <2 x i16> @llvm.dx.umad.v2i16(<2 x i16> %0, <2 x i16> %1, <2 x i16> %2) -// NATIVE_HALF: ret <2 x i16> %dx.umad +// DXIL_NATIVE_HALF: %dx.umad = call <2 x i16> @llvm.dx.umad.v2i16(<2 x i16> %0, <2 x i16> %1, <2 x i16> %2) +// DXIL_NATIVE_HALF: ret <2 x i16> %dx.umad +// SPIR_NATIVE_HALF: mul nuw <2 x i16> %{{.*}}, %{{.*}} +// SPIR_NATIVE_HALF: add nuw <2 x i16> %{{.*}}, %{{.*}} uint16_t2 test_mad_uint16_t2(uint16_t2 p0, uint16_t2 p1, uint16_t2 p2) { return mad(p0, p1, p2); } -// NATIVE_HALF: %dx.umad = call <3 x i16> @llvm.dx.umad.v3i16(<3 x i16> %0, <3 x i16> %1, <3 x i16> %2) -// NATIVE_HALF: ret <3 x i16> %dx.umad +// DXIL_NATIVE_HALF: %dx.umad = call <3 x i16> @llvm.dx.umad.v3i16(<3 x i16> %0, <3 x i16> %1, <3 x i16> %2) +// DXIL_NATIVE_HALF: ret <3 x i16> %dx.umad +// SPIR_NATIVE_HALF: mul nuw <3 x i16> %{{.*}}, %{{.*}} +// SPIR_NATIVE_HALF: add nuw <3 x i16> %{{.*}}, %{{.*}} uint16_t3 test_mad_uint16_t3(uint16_t3 p0, uint16_t3 p1, uint16_t3 p2) { return mad(p0, p1, p2); } -// NATIVE_HALF: %dx.umad = call <4 x i16> @llvm.dx.umad.v4i16(<4 x i16> %0, <4 x i16> %1, <4 x i16> %2) -// NATIVE_HALF: ret <4 x i16> %dx.umad +// DXIL_NATIVE_HALF: %dx.umad = call <4 x i16> @llvm.dx.umad.v4i16(<4 x i16> %0, <4 x i16> %1, <4 x i16> %2) +// DXIL_NATIVE_HALF: ret <4 x i16> %dx.umad +// SPIR_NATIVE_HALF: mul nuw <4 x i16> %{{.*}}, %{{.*}} +// SPIR_NATIVE_HALF: add nuw <4 x i16> %{{.*}}, %{{.*}} uint16_t4 test_mad_uint16_t4(uint16_t4 p0, uint16_t4 p1, uint16_t4 p2) { return mad(p0, p1, p2); } -// NATIVE_HALF: %dx.imad = call i16 @llvm.dx.imad.i16(i16 %0, i16 %1, i16 %2) -// NATIVE_HALF: ret i16 %dx.imad +// DXIL_NATIVE_HALF: %dx.imad = call i16 @llvm.dx.imad.i16(i16 %0, i16 %1, i16 %2) +// DXIL_NATIVE_HALF: ret i16 %dx.imad +// SPIR_NATIVE_HALF: mul nsw i16 %{{.*}}, %{{.*}} +// SPIR_NATIVE_HALF: add nsw i16 %{{.*}}, %{{.*}} int16_t test_mad_int16_t(int16_t p0, int16_t p1, int16_t p2) { return mad(p0, p1, p2); } -// NATIVE_HALF: %dx.imad = call <2 x i16> @llvm.dx.imad.v2i16(<2 x i16> %0, <2 x i16> %1, <2 x i16> %2) -// NATIVE_HALF: ret <2 x i16> %dx.imad +// DXIL_NATIVE_HALF: %dx.imad = call <2 x i16> @llvm.dx.imad.v2i16(<2 x i16> %0, <2 x i16> %1, <2 x i16> %2) +// DXIL_NATIVE_HALF: ret <2 x i16> %dx.imad +// SPIR_NATIVE_HALF: mul nsw <2 x i16> %{{.*}}, %{{.*}} +// SPIR_NATIVE_HALF: add nsw <2 x i16> %{{.*}}, %{{.*}} int16_t2 test_mad_int16_t2(int16_t2 p0, int16_t2 p1, int16_t2 p2) { return mad(p0, p1, p2); } -// NATIVE_HALF: %dx.imad = call <3 x i16> @llvm.dx.imad.v3i16(<3 x i16> %0, <3 x i16> %1, <3 x i16> %2) -// NATIVE_HALF: ret <3 x i16> %dx.imad +// DXIL_NATIVE_HALF: %dx.imad = call <3 x i16> @llvm.dx.imad.v3i16(<3 x i16> %0, <3 x i16> %1, <3 x i16> %2) +// DXIL_NATIVE_HALF: ret <3 x i16> %dx.imad +// SPIR_NATIVE_HALF: mul nsw <3 x i16> %{{.*}}, %{{.*}} +// SPIR_NATIVE_HALF: add nsw <3 x i16> %{{.*}}, %{{.*}} int16_t3 test_mad_int16_t3(int16_t3 p0, int16_t3 p1, int16_t3 p2) { return mad(p0, p1, p2); } -// NATIVE_HALF: %dx.imad = call <4 x i16> @llvm.dx.imad.v4i16(<4 x i16> %0, <4 x i16> %1, <4 x i16> %2) -// NATIVE_HALF: ret <4 x i16> %dx.imad +// DXIL_NATIVE_HALF: %dx.imad = call <4 x i16> @llvm.dx.imad.v4i16(<4 x i16> %0, <4 x i16> %1, <4 x i16> %2) +// DXIL_NATIVE_HALF: ret <4 x i16> %dx.imad +// SPIR_NATIVE_HALF: mul nsw <4 x i16> %{{.*}}, %{{.*}} +// SPIR_NATIVE_HALF: add nsw <4 x i16> %{{.*}}, %{{.*}} int16_t4 test_mad_int16_t4(int16_t4 p0, int16_t4 p1, int16_t4 p2) { return mad(p0, p1, p2); } #endif // __HLSL_ENABLE_16_BIT -// NATIVE_HALF: %dx.fmad = call half @llvm.fmuladd.f16(half %0, half %1, half %2) -// NATIVE_HALF: ret half %dx.fmad -// NO_HALF: %dx.fmad = call float @llvm.fmuladd.f32(float %0, float %1, float %2) -// NO_HALF: ret float %dx.fmad +// NATIVE_HALF: %hlsl.fmad = call half @llvm.fmuladd.f16(half %0, half %1, half %2) +// NATIVE_HALF: ret half %hlsl.fmad +// NO_HALF: %hlsl.fmad = call float @llvm.fmuladd.f32(float %0, float %1, float %2) +// NO_HALF: ret float %hlsl.fmad half test_mad_half(half p0, half p1, half p2) { return mad(p0, p1, p2); } -// NATIVE_HALF: %dx.fmad = call <2 x half> @llvm.fmuladd.v2f16(<2 x half> %0, <2 x half> %1, <2 x half> %2) -// NATIVE_HALF: ret <2 x half> %dx.fmad -// NO_HALF: %dx.fmad = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) -// NO_HALF: ret <2 x float> %dx.fmad +// NATIVE_HALF: %hlsl.fmad = call <2 x half> @llvm.fmuladd.v2f16(<2 x half> %0, <2 x half> %1, <2 x half> %2) +// NATIVE_HALF: ret <2 x half> %hlsl.fmad +// NO_HALF: %hlsl.fmad = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) +// NO_HALF: ret <2 x float> %hlsl.fmad half2 test_mad_half2(half2 p0, half2 p1, half2 p2) { return mad(p0, p1, p2); } -// NATIVE_HALF: %dx.fmad = call <3 x half> @llvm.fmuladd.v3f16(<3 x half> %0, <3 x half> %1, <3 x half> %2) -// NATIVE_HALF: ret <3 x half> %dx.fmad -// NO_HALF: %dx.fmad = call <3 x float> @llvm.fmuladd.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %2) -// NO_HALF: ret <3 x float> %dx.fmad +// NATIVE_HALF: %hlsl.fmad = call <3 x half> @llvm.fmuladd.v3f16(<3 x half> %0, <3 x half> %1, <3 x half> %2) +// NATIVE_HALF: ret <3 x half> %hlsl.fmad +// NO_HALF: %hlsl.fmad = call <3 x float> @llvm.fmuladd.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %2) +// NO_HALF: ret <3 x float> %hlsl.fmad half3 test_mad_half3(half3 p0, half3 p1, half3 p2) { return mad(p0, p1, p2); } -// NATIVE_HALF: %dx.fmad = call <4 x half> @llvm.fmuladd.v4f16(<4 x half> %0, <4 x half> %1, <4 x half> %2) -// NATIVE_HALF: ret <4 x half> %dx.fmad -// NO_HALF: %dx.fmad = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %0, <4 x float> %1, <4 x float> %2) -// NO_HALF: ret <4 x float> %dx.fmad +// NATIVE_HALF: %hlsl.fmad = call <4 x half> @llvm.fmuladd.v4f16(<4 x half> %0, <4 x half> %1, <4 x half> %2) +// NATIVE_HALF: ret <4 x half> %hlsl.fmad +// NO_HALF: %hlsl.fmad = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %0, <4 x float> %1, <4 x float> %2) +// NO_HALF: ret <4 x float> %hlsl.fmad half4 test_mad_half4(half4 p0, half4 p1, half4 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.fmad = call float @llvm.fmuladd.f32(float %0, float %1, float %2) -// CHECK: ret float %dx.fmad +// CHECK: %hlsl.fmad = call float @llvm.fmuladd.f32(float %0, float %1, float %2) +// CHECK: ret float %hlsl.fmad float test_mad_float(float p0, float p1, float p2) { return mad(p0, p1, p2); } -// CHECK: %dx.fmad = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) -// CHECK: ret <2 x float> %dx.fmad +// CHECK: %hlsl.fmad = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) +// CHECK: ret <2 x float> %hlsl.fmad float2 test_mad_float2(float2 p0, float2 p1, float2 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.fmad = call <3 x float> @llvm.fmuladd.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %2) -// CHECK: ret <3 x float> %dx.fmad +// CHECK: %hlsl.fmad = call <3 x float> @llvm.fmuladd.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %2) +// CHECK: ret <3 x float> %hlsl.fmad float3 test_mad_float3(float3 p0, float3 p1, float3 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.fmad = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %0, <4 x float> %1, <4 x float> %2) -// CHECK: ret <4 x float> %dx.fmad +// CHECK: %hlsl.fmad = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %0, <4 x float> %1, <4 x float> %2) +// CHECK: ret <4 x float> %hlsl.fmad float4 test_mad_float4(float4 p0, float4 p1, float4 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.fmad = call double @llvm.fmuladd.f64(double %0, double %1, double %2) -// CHECK: ret double %dx.fmad +// CHECK: %hlsl.fmad = call double @llvm.fmuladd.f64(double %0, double %1, double %2) +// CHECK: ret double %hlsl.fmad double test_mad_double(double p0, double p1, double p2) { return mad(p0, p1, p2); } -// CHECK: %dx.fmad = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %0, <2 x double> %1, <2 x double> %2) -// CHECK: ret <2 x double> %dx.fmad +// CHECK: %hlsl.fmad = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %0, <2 x double> %1, <2 x double> %2) +// CHECK: ret <2 x double> %hlsl.fmad double2 test_mad_double2(double2 p0, double2 p1, double2 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.fmad = call <3 x double> @llvm.fmuladd.v3f64(<3 x double> %0, <3 x double> %1, <3 x double> %2) -// CHECK: ret <3 x double> %dx.fmad +// CHECK: %hlsl.fmad = call <3 x double> @llvm.fmuladd.v3f64(<3 x double> %0, <3 x double> %1, <3 x double> %2) +// CHECK: ret <3 x double> %hlsl.fmad double3 test_mad_double3(double3 p0, double3 p1, double3 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.fmad = call <4 x double> @llvm.fmuladd.v4f64(<4 x double> %0, <4 x double> %1, <4 x double> %2) -// CHECK: ret <4 x double> %dx.fmad +// CHECK: %hlsl.fmad = call <4 x double> @llvm.fmuladd.v4f64(<4 x double> %0, <4 x double> %1, <4 x double> %2) +// CHECK: ret <4 x double> %hlsl.fmad double4 test_mad_double4(double4 p0, double4 p1, double4 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.imad = call i32 @llvm.dx.imad.i32(i32 %0, i32 %1, i32 %2) -// CHECK: ret i32 %dx.imad +// DXIL_CHECK: %dx.imad = call i32 @llvm.dx.imad.i32(i32 %0, i32 %1, i32 %2) +// DXIL_CHECK: ret i32 %dx.imad +// SPIR_CHECK: mul nsw i32 %{{.*}}, %{{.*}} +// SPIR_CHECK: add nsw i32 %{{.*}}, %{{.*}} int test_mad_int(int p0, int p1, int p2) { return mad(p0, p1, p2); } -// CHECK: %dx.imad = call <2 x i32> @llvm.dx.imad.v2i32(<2 x i32> %0, <2 x i32> %1, <2 x i32> %2) -// CHECK: ret <2 x i32> %dx.imad +// DXIL_CHECK: %dx.imad = call <2 x i32> @llvm.dx.imad.v2i32(<2 x i32> %0, <2 x i32> %1, <2 x i32> %2) +// DXIL_CHECK: ret <2 x i32> %dx.imad +// SPIR_CHECK: mul nsw <2 x i32> %{{.*}}, %{{.*}} +// SPIR_CHECK: add nsw <2 x i32> %{{.*}}, %{{.*}} int2 test_mad_int2(int2 p0, int2 p1, int2 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.imad = call <3 x i32> @llvm.dx.imad.v3i32(<3 x i32> %0, <3 x i32> %1, <3 x i32> %2) -// CHECK: ret <3 x i32> %dx.imad +// DXIL_CHECK: %dx.imad = call <3 x i32> @llvm.dx.imad.v3i32(<3 x i32> %0, <3 x i32> %1, <3 x i32> %2) +// DXIL_CHECK: ret <3 x i32> %dx.imad +// SPIR_CHECK: mul nsw <3 x i32> %{{.*}}, %{{.*}} +// SPIR_CHECK: add nsw <3 x i32> %{{.*}}, %{{.*}} int3 test_mad_int3(int3 p0, int3 p1, int3 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.imad = call <4 x i32> @llvm.dx.imad.v4i32(<4 x i32> %0, <4 x i32> %1, <4 x i32> %2) -// CHECK: ret <4 x i32> %dx.imad +// DXIL_CHECK: %dx.imad = call <4 x i32> @llvm.dx.imad.v4i32(<4 x i32> %0, <4 x i32> %1, <4 x i32> %2) +// DXIL_CHECK: ret <4 x i32> %dx.imad +// SPIR_CHECK: mul nsw <4 x i32> %{{.*}}, %{{.*}} +// SPIR_CHECK: add nsw <4 x i32> %{{.*}}, %{{.*}} int4 test_mad_int4(int4 p0, int4 p1, int4 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.imad = call i64 @llvm.dx.imad.i64(i64 %0, i64 %1, i64 %2) -// CHECK: ret i64 %dx.imad +// DXIL_CHECK: %dx.imad = call i64 @llvm.dx.imad.i64(i64 %0, i64 %1, i64 %2) +// DXIL_CHECK: ret i64 %dx.imad +// SPIR_CHECK: mul nsw i64 %{{.*}}, %{{.*}} +// SPIR_CHECK: add nsw i64 %{{.*}}, %{{.*}} int64_t test_mad_int64_t(int64_t p0, int64_t p1, int64_t p2) { return mad(p0, p1, p2); } -// CHECK: %dx.imad = call <2 x i64> @llvm.dx.imad.v2i64(<2 x i64> %0, <2 x i64> %1, <2 x i64> %2) -// CHECK: ret <2 x i64> %dx.imad +// DXIL_CHECK: %dx.imad = call <2 x i64> @llvm.dx.imad.v2i64(<2 x i64> %0, <2 x i64> %1, <2 x i64> %2) +// DXIL_CHECK: ret <2 x i64> %dx.imad +// SPIR_CHECK: mul nsw <2 x i64> %{{.*}}, %{{.*}} +// SPIR_CHECK: add nsw <2 x i64> %{{.*}}, %{{.*}} int64_t2 test_mad_int64_t2(int64_t2 p0, int64_t2 p1, int64_t2 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.imad = call <3 x i64> @llvm.dx.imad.v3i64(<3 x i64> %0, <3 x i64> %1, <3 x i64> %2) -// CHECK: ret <3 x i64> %dx.imad +// DXIL_CHECK: %dx.imad = call <3 x i64> @llvm.dx.imad.v3i64(<3 x i64> %0, <3 x i64> %1, <3 x i64> %2) +// DXIL_CHECK: ret <3 x i64> %dx.imad +// SPIR_CHECK: mul nsw <3 x i64> %{{.*}}, %{{.*}} +// SPIR_CHECK: add nsw <3 x i64> %{{.*}}, %{{.*}} int64_t3 test_mad_int64_t3(int64_t3 p0, int64_t3 p1, int64_t3 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.imad = call <4 x i64> @llvm.dx.imad.v4i64(<4 x i64> %0, <4 x i64> %1, <4 x i64> %2) -// CHECK: ret <4 x i64> %dx.imad +// DXIL_CHECK: %dx.imad = call <4 x i64> @llvm.dx.imad.v4i64(<4 x i64> %0, <4 x i64> %1, <4 x i64> %2) +// DXIL_CHECK: ret <4 x i64> %dx.imad +// SPIR_CHECK: mul nsw <4 x i64> %{{.*}}, %{{.*}} +// SPIR_CHECK: add nsw <4 x i64> %{{.*}}, %{{.*}} int64_t4 test_mad_int64_t4(int64_t4 p0, int64_t4 p1, int64_t4 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.umad = call i32 @llvm.dx.umad.i32(i32 %0, i32 %1, i32 %2) -// CHECK: ret i32 %dx.umad +// DXIL_CHECK: %dx.umad = call i32 @llvm.dx.umad.i32(i32 %0, i32 %1, i32 %2) +// DXIL_CHECK: ret i32 %dx.umad +// SPIR_CHECK: mul nuw i32 %{{.*}}, %{{.*}} +// SPIR_CHECK: add nuw i32 %{{.*}}, %{{.*}} uint test_mad_uint(uint p0, uint p1, uint p2) { return mad(p0, p1, p2); } -// CHECK: %dx.umad = call <2 x i32> @llvm.dx.umad.v2i32(<2 x i32> %0, <2 x i32> %1, <2 x i32> %2) -// CHECK: ret <2 x i32> %dx.umad +// DXIL_CHECK: %dx.umad = call <2 x i32> @llvm.dx.umad.v2i32(<2 x i32> %0, <2 x i32> %1, <2 x i32> %2) +// DXIL_CHECK: ret <2 x i32> %dx.umad +// SPIR_CHECK: mul nuw <2 x i32> %{{.*}}, %{{.*}} +// SPIR_CHECK: add nuw <2 x i32> %{{.*}}, %{{.*}} uint2 test_mad_uint2(uint2 p0, uint2 p1, uint2 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.umad = call <3 x i32> @llvm.dx.umad.v3i32(<3 x i32> %0, <3 x i32> %1, <3 x i32> %2) -// CHECK: ret <3 x i32> %dx.umad +// DXIL_CHECK: %dx.umad = call <3 x i32> @llvm.dx.umad.v3i32(<3 x i32> %0, <3 x i32> %1, <3 x i32> %2) +// DXIL_CHECK: ret <3 x i32> %dx.umad +// SPIR_CHECK: mul nuw <3 x i32> %{{.*}}, %{{.*}} +// SPIR_CHECK: add nuw <3 x i32> %{{.*}}, %{{.*}} uint3 test_mad_uint3(uint3 p0, uint3 p1, uint3 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.umad = call <4 x i32> @llvm.dx.umad.v4i32(<4 x i32> %0, <4 x i32> %1, <4 x i32> %2) -// CHECK: ret <4 x i32> %dx.umad +// DXIL_CHECK: %dx.umad = call <4 x i32> @llvm.dx.umad.v4i32(<4 x i32> %0, <4 x i32> %1, <4 x i32> %2) +// DXIL_CHECK: ret <4 x i32> %dx.umad +// SPIR_CHECK: mul nuw <4 x i32> %{{.*}}, %{{.*}} +// SPIR_CHECK: add nuw <4 x i32> %{{.*}}, %{{.*}} uint4 test_mad_uint4(uint4 p0, uint4 p1, uint4 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.umad = call i64 @llvm.dx.umad.i64(i64 %0, i64 %1, i64 %2) -// CHECK: ret i64 %dx.umad +// DXIL_CHECK: %dx.umad = call i64 @llvm.dx.umad.i64(i64 %0, i64 %1, i64 %2) +// DXIL_CHECK: ret i64 %dx.umad +// SPIR_CHECK: mul nuw i64 %{{.*}}, %{{.*}} +// SPIR_CHECK: add nuw i64 %{{.*}}, %{{.*}} uint64_t test_mad_uint64_t(uint64_t p0, uint64_t p1, uint64_t p2) { return mad(p0, p1, p2); } -// CHECK: %dx.umad = call <2 x i64> @llvm.dx.umad.v2i64(<2 x i64> %0, <2 x i64> %1, <2 x i64> %2) -// CHECK: ret <2 x i64> %dx.umad +// DXIL_CHECK: %dx.umad = call <2 x i64> @llvm.dx.umad.v2i64(<2 x i64> %0, <2 x i64> %1, <2 x i64> %2) +// DXIL_CHECK: ret <2 x i64> %dx.umad +// SPIR_CHECK: mul nuw <2 x i64> %{{.*}}, %{{.*}} +// SPIR_CHECK: add nuw <2 x i64> %{{.*}}, %{{.*}} uint64_t2 test_mad_uint64_t2(uint64_t2 p0, uint64_t2 p1, uint64_t2 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.umad = call <3 x i64> @llvm.dx.umad.v3i64(<3 x i64> %0, <3 x i64> %1, <3 x i64> %2) -// CHECK: ret <3 x i64> %dx.umad +// DXIL_CHECK: %dx.umad = call <3 x i64> @llvm.dx.umad.v3i64(<3 x i64> %0, <3 x i64> %1, <3 x i64> %2) +// DXIL_CHECK: ret <3 x i64> %dx.umad +// SPIR_CHECK: mul nuw <3 x i64> %{{.*}}, %{{.*}} +// SPIR_CHECK: add nuw <3 x i64> %{{.*}}, %{{.*}} uint64_t3 test_mad_uint64_t3(uint64_t3 p0, uint64_t3 p1, uint64_t3 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.umad = call <4 x i64> @llvm.dx.umad.v4i64(<4 x i64> %0, <4 x i64> %1, <4 x i64> %2) -// CHECK: ret <4 x i64> %dx.umad +// DXIL_CHECK: %dx.umad = call <4 x i64> @llvm.dx.umad.v4i64(<4 x i64> %0, <4 x i64> %1, <4 x i64> %2) +// DXIL_CHECK: ret <4 x i64> %dx.umad +// SPIR_CHECK: mul nuw <4 x i64> %{{.*}}, %{{.*}} +// SPIR_CHECK: add nuw <4 x i64> %{{.*}}, %{{.*}} uint64_t4 test_mad_uint64_t4(uint64_t4 p0, uint64_t4 p1, uint64_t4 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.fmad = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> %splat.splat, <2 x float> %1, <2 x float> %2) -// CHECK: ret <2 x float> %dx.fmad +// CHECK: %hlsl.fmad = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> %splat.splat, <2 x float> %1, <2 x float> %2) +// CHECK: ret <2 x float> %hlsl.fmad float2 test_mad_float2_splat(float p0, float2 p1, float2 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.fmad = call <3 x float> @llvm.fmuladd.v3f32(<3 x float> %splat.splat, <3 x float> %1, <3 x float> %2) -// CHECK: ret <3 x float> %dx.fmad +// CHECK: %hlsl.fmad = call <3 x float> @llvm.fmuladd.v3f32(<3 x float> %splat.splat, <3 x float> %1, <3 x float> %2) +// CHECK: ret <3 x float> %hlsl.fmad float3 test_mad_float3_splat(float p0, float3 p1, float3 p2) { return mad(p0, p1, p2); } -// CHECK: %dx.fmad = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %splat.splat, <4 x float> %1, <4 x float> %2) -// CHECK: ret <4 x float> %dx.fmad +// CHECK: %hlsl.fmad = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %splat.splat, <4 x float> %1, <4 x float> %2) +// CHECK: ret <4 x float> %hlsl.fmad float4 test_mad_float4_splat(float p0, float4 p1, float4 p2) { return mad(p0, p1, p2); } // CHECK: %conv = sitofp i32 %2 to float // CHECK: %splat.splatinsert = insertelement <2 x float> poison, float %conv, i64 0 // CHECK: %splat.splat = shufflevector <2 x float> %splat.splatinsert, <2 x float> poison, <2 x i32> zeroinitializer -// CHECK: %dx.fmad = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %splat.splat) -// CHECK: ret <2 x float> %dx.fmad +// CHECK: %hlsl.fmad = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %splat.splat) +// CHECK: ret <2 x float> %hlsl.fmad float2 test_mad_float2_int_splat(float2 p0, float2 p1, int p2) { return mad(p0, p1, p2); } @@ -184,8 +240,8 @@ float2 test_mad_float2_int_splat(float2 p0, float2 p1, int p2) { // CHECK: %conv = sitofp i32 %2 to float // CHECK: %splat.splatinsert = insertelement <3 x float> poison, float %conv, i64 0 // CHECK: %splat.splat = shufflevector <3 x float> %splat.splatinsert, <3 x float> poison, <3 x i32> zeroinitializer -// CHECK: %dx.fmad = call <3 x float> @llvm.fmuladd.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %splat.splat) -// CHECK: ret <3 x float> %dx.fmad +// CHECK: %hlsl.fmad = call <3 x float> @llvm.fmuladd.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %splat.splat) +// CHECK: ret <3 x float> %hlsl.fmad float3 test_mad_float3_int_splat(float3 p0, float3 p1, int p2) { return mad(p0, p1, p2); } diff --git a/clang/test/CoverageMapping/statement-expression.c b/clang/test/CoverageMapping/statement-expression.c new file mode 100644 index 0000000000000000000000000000000000000000..5f9ab5838af3423f6a45ab445d8c4b36997177a4 --- /dev/null +++ b/clang/test/CoverageMapping/statement-expression.c @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name statement-expression.c %s + +// No crash for the following examples, where GNU Statement Expression extension +// could introduce region terminators (break, goto etc) before implicit +// initializers in a struct or an array. +// See https://github.com/llvm/llvm-project/pull/89564 + +struct Foo { + int field1; + int field2; +}; + +void f1(void) { + struct Foo foo = { + .field1 = ({ + switch (0) { + case 0: + break; // A region terminator + } + 0; + }), + // ImplicitValueInitExpr introduced here for .field2 + }; +} + +void f2(void) { + int arr[3] = { + [0] = ({ + goto L0; // A region terminator +L0: + 0; + }), + // ImplicitValueInitExpr introduced here for subscript [1] + [2] = 0, + }; +} diff --git a/clang/test/Driver/aix-toolchain-include.cpp b/clang/test/Driver/aix-toolchain-include.cpp index 31dc4fa9eb6a195947fd944c3bcc2fbdbce5827b..b0074bf0ba1fdbf36fac67713aa13895526fbdfc 100644 --- a/clang/test/Driver/aix-toolchain-include.cpp +++ b/clang/test/Driver/aix-toolchain-include.cpp @@ -5,28 +5,28 @@ // RUN: --target=powerpc-ibm-aix \ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_aix_tree \ -// RUN: -fopenmp \ +// RUN: -fopenmp=libomp \ // RUN: | FileCheck -check-prefixes=CHECK-INTERNAL-INCLUDE,CHECK-INTERNAL-INCLUDE-CXX %s // RUN: %clangxx -### %s 2>&1 \ // RUN: --target=powerpc64-ibm-aix \ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_aix_tree \ -// RUN: -fopenmp \ +// RUN: -fopenmp=libomp \ // RUN: | FileCheck -check-prefixes=CHECK-INTERNAL-INCLUDE,CHECK-INTERNAL-INCLUDE-CXX %s // RUN: %clang -### -xc %s 2>&1 \ // RUN: --target=powerpc-ibm-aix \ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_aix_tree \ -// RUN: -fopenmp \ +// RUN: -fopenmp=libomp \ // RUN: | FileCheck -check-prefix=CHECK-INTERNAL-INCLUDE %s // RUN: %clang -### -xc %s 2>&1 \ // RUN: --target=powerpc64-ibm-aix \ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_aix_tree \ -// RUN: -fopenmp \ +// RUN: -fopenmp=libomp \ // RUN: | FileCheck -check-prefix=CHECK-INTERNAL-INCLUDE %s // CHECK-INTERNAL-INCLUDE: "-cc1" @@ -78,7 +78,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_aix_tree \ // RUN: -nostdlibinc \ -// RUN: -fopenmp \ +// RUN: -fopenmp=libomp \ // RUN: | FileCheck -check-prefix=CHECK-NOSTDLIBINC-INCLUDE %s // RUN: %clangxx -### %s 2>&1 \ @@ -86,7 +86,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_aix_tree \ // RUN: -nostdlibinc \ -// RUN: -fopenmp \ +// RUN: -fopenmp=libomp \ // RUN: | FileCheck -check-prefix=CHECK-NOSTDLIBINC-INCLUDE %s // RUN: %clang -### -xc %s 2>&1 \ @@ -94,7 +94,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_aix_tree \ // RUN: -nostdlibinc \ -// RUN: -fopenmp \ +// RUN: -fopenmp=libomp \ // RUN: | FileCheck -check-prefix=CHECK-NOSTDLIBINC-INCLUDE %s // RUN: %clang -### -xc %s 2>&1 \ @@ -102,7 +102,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_aix_tree \ // RUN: -nostdlibinc \ -// RUN: -fopenmp \ +// RUN: -fopenmp=libomp \ // RUN: | FileCheck -check-prefix=CHECK-NOSTDLIBINC-INCLUDE %s // CHECK-NOSTDLIBINC-INCLUDE: "-cc1" @@ -120,7 +120,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_aix_tree \ // RUN: -nobuiltininc \ -// RUN: -fopenmp \ +// RUN: -fopenmp=libomp \ // RUN: | FileCheck -check-prefixes=CHECK-NOBUILTININC-INCLUDE,CHECK-NOBUILTININC-INCLUDE-CXX %s // RUN: %clangxx -### %s 2>&1 \ @@ -128,7 +128,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_aix_tree \ // RUN: -nobuiltininc \ -// RUN: -fopenmp \ +// RUN: -fopenmp=libomp \ // RUN: | FileCheck -check-prefixes=CHECK-NOBUILTININC-INCLUDE,CHECK-NOBUILTININC-INCLUDE-CXX %s // RUN: %clang -### -xc %s 2>&1 \ @@ -136,7 +136,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_aix_tree \ // RUN: -nobuiltininc \ -// RUN: -fopenmp \ +// RUN: -fopenmp=libomp \ // RUN: | FileCheck -check-prefix=CHECK-NOBUILTININC-INCLUDE %s // RUN: %clang -### -xc %s 2>&1 \ @@ -144,7 +144,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_aix_tree \ // RUN: -nobuiltininc \ -// RUN: -fopenmp \ +// RUN: -fopenmp=libomp \ // RUN: | FileCheck -check-prefix=CHECK-NOBUILTININC-INCLUDE %s // CHECK-NOBUILTININC-INCLUDE: "-cc1" @@ -162,7 +162,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_aix_tree \ // RUN: -nostdinc++ \ -// RUN: -fopenmp \ +// RUN: -fopenmp=libomp \ // RUN: | FileCheck -check-prefix=CHECK-NOSTDINCXX-INCLUDE %s // RUN: %clangxx -### %s 2>&1 \ @@ -170,7 +170,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_aix_tree \ // RUN: -nostdinc++ \ -// RUN: -fopenmp \ +// RUN: -fopenmp=libomp \ // RUN: | FileCheck -check-prefix=CHECK-NOSTDINCXX-INCLUDE %s // CHECK-NOSTDINCXX-INCLUDE: "-cc1" diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c index 5b6dfe308a76eae703bc216db2410369ae59e6d4..7731300ae9f5258583e1082107376085dfbc0572 100644 --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c @@ -790,6 +790,7 @@ // RUN: %clang_cl -vctoolsdir "" /arm64EC /c -### -- %s 2>&1 | FileCheck --check-prefix=ARM64EC %s // ARM64EC-NOT: /arm64EC has been overridden by specified target // ARM64EC: "-triple" "arm64ec-pc-windows-msvc19.33.0" +// ARM64EC-SAME: "--dependent-lib=softintrin" // RUN: %clang_cl -vctoolsdir "" /arm64EC /c -target x86_64-pc-windows-msvc -### -- %s 2>&1 | FileCheck --check-prefix=ARM64EC_OVERRIDE %s // ARM64EC_OVERRIDE: warning: /arm64EC has been overridden by specified target: x86_64-pc-windows-msvc; option ignored diff --git a/clang/test/Driver/cl-outputs.c b/clang/test/Driver/cl-outputs.c index 4d58f0fb548b5793de03e7de76e5deec422f60ee..4298657ac49f5c8e86001d4070eb94354747b76b 100644 --- a/clang/test/Driver/cl-outputs.c +++ b/clang/test/Driver/cl-outputs.c @@ -118,6 +118,7 @@ // RUN: %clang_cl /Fefoo.ext -### -- %s 2>&1 | FileCheck -check-prefix=FeEXT %s // RUN: %clang_cl /Fe:foo.ext -### -- %s 2>&1 | FileCheck -check-prefix=FeEXT %s +// RUN: %clang_cl /Fe: foo.ext -### -- %s 2>&1 | FileCheck -check-prefix=FeEXT %s // FeEXT: "-out:foo.ext" // RUN: %clang_cl /LD /Fefoo.ext -### -- %s 2>&1 | FileCheck -check-prefix=FeEXTDLL %s @@ -270,6 +271,8 @@ // P: "-o" "cl-outputs.i" // RUN: %clang_cl /P /Fifoo -### -- %s 2>&1 | FileCheck -check-prefix=Fi1 %s +// RUN: %clang_cl /P /Fi:foo -### -- %s 2>&1 | FileCheck -check-prefix=Fi1 %s +// RUN: %clang_cl /P /Fi: foo -### -- %s 2>&1 | FileCheck -check-prefix=Fi1 %s // Fi1: "-E" // Fi1: "-o" "foo.i" @@ -302,6 +305,7 @@ // RELATIVE_OBJPATH1: "-object-file-name=a.obj" // RUN: %clang_cl -fdebug-compilation-dir=. /Z7 /Fo:a.obj -### -- %s 2>&1 | FileCheck -check-prefix=RELATIVE_OBJPATH1_COLON %s +// RUN: %clang_cl -fdebug-compilation-dir=. /Z7 /Fo: a.obj -### -- %s 2>&1 | FileCheck -check-prefix=RELATIVE_OBJPATH1_COLON %s // RELATIVE_OBJPATH1_COLON: "-object-file-name=a.obj" // RUN: %clang_cl -fdebug-compilation-dir=. /Z7 /Fofoo/a.obj -### -- %s 2>&1 | FileCheck -check-prefix=RELATIVE_OBJPATH2 %s diff --git a/clang/test/Driver/cl-pch.cpp b/clang/test/Driver/cl-pch.cpp index d09b177eb617def0c3f77d9bd08aea929b050e0c..cc4fc435a61c20689a15542c18878a0ef9c741ca 100644 --- a/clang/test/Driver/cl-pch.cpp +++ b/clang/test/Driver/cl-pch.cpp @@ -99,6 +99,12 @@ // /Yu /Fpout.pch => out.pch is filename // RUN: %clang_cl -Werror /Yupchfile.h /FIpchfile.h /Fpout.pch /c -### -- %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK-YUFP1 %s +// /Yu /Fp:out.pch => out.pch is filename +// RUN: %clang_cl -Werror /Yupchfile.h /FIpchfile.h /Fp:out.pch /c -### -- %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-YUFP1 %s +// /Yu /Fp: out.pch => out.pch is filename +// RUN: %clang_cl -Werror /Yupchfile.h /FIpchfile.h /Fp: out.pch /c -### -- %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-YUFP1 %s // Use .pch file, but don't build it. // CHECK-YUFP1: -include-pch // CHECK-YUFP1: out.pch diff --git a/clang/test/Driver/clang-offload-bundler-zstd.c b/clang/test/Driver/clang-offload-bundler-zstd.c index 4485e57309bbbc5b9489b496d5751b3ed783862a..a424981c69716f00eff413abd8b60e1240f2434d 100644 --- a/clang/test/Driver/clang-offload-bundler-zstd.c +++ b/clang/test/Driver/clang-offload-bundler-zstd.c @@ -22,19 +22,22 @@ // Check compression/decompression of offload bundle. // // RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ -// RUN: -input=%t.tgt1 -input=%t.tgt2 -output=%t.hip.bundle.bc -compress -verbose 2>&1 | \ -// RUN: FileCheck -check-prefix=COMPRESS %s +// RUN: -input=%t.tgt1 -input=%t.tgt2 -output=%t.hip.bundle.bc -compress -verbose >%t.1.txt 2>&1 // RUN: clang-offload-bundler -type=bc -list -input=%t.hip.bundle.bc | FileCheck -check-prefix=NOHOST %s // RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ -// RUN: -output=%t.res.tgt1 -output=%t.res.tgt2 -input=%t.hip.bundle.bc -unbundle -verbose 2>&1 | \ -// RUN: FileCheck -check-prefix=DECOMPRESS %s +// RUN: -output=%t.res.tgt1 -output=%t.res.tgt2 -input=%t.hip.bundle.bc -unbundle -verbose >%t.2.txt 2>&1 +// RUN: cat %t.1.txt %t.2.txt | FileCheck %s // RUN: diff %t.tgt1 %t.res.tgt1 // RUN: diff %t.tgt2 %t.res.tgt2 // -// COMPRESS: Compression method used: zstd -// COMPRESS: Compression level: 3 -// DECOMPRESS: Decompression method: zstd -// DECOMPRESS: Hashes match: Yes +// CHECK: Compressed bundle format version: 2 +// CHECK: Total file size (including headers): [[SIZE:[0-9]*]] bytes +// CHECK: Compression method used: zstd +// CHECK: Compression level: 3 +// CHECK: Compressed bundle format version: 2 +// CHECK: Total file size (from header): [[SIZE]] bytes +// CHECK: Decompression method: zstd +// CHECK: Hashes match: Yes // NOHOST-NOT: host- // NOHOST-DAG: hip-amdgcn-amd-amdhsa--gfx900 // NOHOST-DAG: hip-amdgcn-amd-amdhsa--gfx906 diff --git a/clang/test/Driver/debug-options-embed-source.c b/clang/test/Driver/debug-options-embed-source.c new file mode 100644 index 0000000000000000000000000000000000000000..acb00fca62ee03e8469b9b735a1199ef38c568af --- /dev/null +++ b/clang/test/Driver/debug-options-embed-source.c @@ -0,0 +1,13 @@ +// AIX does not support -gdwarf-5 which is required by -gembed-source +// UNSUPPORTED: target={{.*}}-aix{{.*}} + +// RUN: %clang -### -gdwarf-5 -gembed-source %s 2>&1 | FileCheck -check-prefix=GEMBED_5 %s +// RUN: not %clang -### -gdwarf-2 -gembed-source %s 2>&1 | FileCheck -check-prefix=GEMBED_2 %s +// RUN: %clang -### -gdwarf-5 -gno-embed-source %s 2>&1 | FileCheck -check-prefix=NOGEMBED_5 %s +// RUN: %clang -### -gdwarf-2 -gno-embed-source %s 2>&1 | FileCheck -check-prefix=NOGEMBED_2 %s +// +// GEMBED_5: "-gembed-source" +// GEMBED_2: error: invalid argument '-gembed-source' only allowed with '-gdwarf-5' +// NOGEMBED_5-NOT: "-gembed-source" +// NOGEMBED_2-NOT: error: invalid argument '-gembed-source' only allowed with '-gdwarf-5' +// diff --git a/clang/test/Driver/debug-options.c b/clang/test/Driver/debug-options.c index a6acfe88a38611c769658a2a423780cbb60af433..7d061410a229f035b50a00f6147d3f200f096b4c 100644 --- a/clang/test/Driver/debug-options.c +++ b/clang/test/Driver/debug-options.c @@ -410,16 +410,6 @@ // MACRO: "-debug-info-macro" // NOMACRO-NOT: "-debug-info-macro" // -// RUN: %clang -### -gdwarf-5 -gembed-source %s 2>&1 | FileCheck -check-prefix=GEMBED_5 %s -// RUN: not %clang -### -gdwarf-2 -gembed-source %s 2>&1 | FileCheck -check-prefix=GEMBED_2 %s -// RUN: %clang -### -gdwarf-5 -gno-embed-source %s 2>&1 | FileCheck -check-prefix=NOGEMBED_5 %s -// RUN: %clang -### -gdwarf-2 -gno-embed-source %s 2>&1 | FileCheck -check-prefix=NOGEMBED_2 %s -// -// GEMBED_5: "-gembed-source" -// GEMBED_2: error: invalid argument '-gembed-source' only allowed with '-gdwarf-5' -// NOGEMBED_5-NOT: "-gembed-source" -// NOGEMBED_2-NOT: error: invalid argument '-gembed-source' only allowed with '-gdwarf-5' -// // RUN: %clang -### -g -fno-eliminate-unused-debug-types -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=DEBUG_UNUSED_TYPES %s // DEBUG_UNUSED_TYPES: "-debug-info-kind=unused-types" @@ -466,9 +456,9 @@ // RUN: %clang -### -target x86_64 -c -g %s 2>&1 | FileCheck --check-prefix=FULL_TEMP_NAMES --implicit-check-not=debug-forward-template-params %s // FULL_TEMP_NAMES-NOT: -gsimple-template-names -//// Test -g[no-]template-alias (enabled by default with SCE debugger tuning and DWARFv5). +//// Test -g[no-]template-alias (enabled by default with SCE debugger tuning and DWARF version >= 4). // RUN: %clang -### -target x86_64 -c -gdwarf-5 -gsce %s 2>&1 | FileCheck %s --check-prefixes=TEMPLATE-ALIAS -// RUN: %clang -### -target x86_64 -c -gdwarf-4 -gsce %s 2>&1 | FileCheck %s --check-prefixes=NO-TEMPLATE-ALIAS +// RUN: %clang -### -target x86_64 -c -gdwarf-3 -gsce %s 2>&1 | FileCheck %s --check-prefixes=NO-TEMPLATE-ALIAS // RUN: %clang -### -target x86_64 -c -gdwarf-5 -gsce -gtemplate-alias %s 2>&1 | FileCheck %s --check-prefixes=TEMPLATE-ALIAS // RUN: %clang -### -target x86_64 -c -gdwarf-5 -gsce -gno-template-alias %s 2>&1 | FileCheck %s --check-prefixes=NO-TEMPLATE-ALIAS // RUN: %clang -### -target x86_64 -c -gdwarf-5 -gtemplate-alias %s 2>&1 | FileCheck %s --check-prefixes=TEMPLATE-ALIAS diff --git a/clang/test/Driver/integrated-as.c b/clang/test/Driver/integrated-as.c index d7658fdfd63374c241f3020f51a69cfcd47c6160..e78fde873cf47f3d535c2b9d7faadefc008991f6 100644 --- a/clang/test/Driver/integrated-as.c +++ b/clang/test/Driver/integrated-as.c @@ -1,10 +1,16 @@ // XFAIL: target={{.*}}-aix{{.*}} -// RUN: %clang -### -c -save-temps -integrated-as %s 2>&1 | FileCheck %s +// RUN: %clang -### -c -save-temps -integrated-as --target=x86_64 %s 2>&1 | FileCheck %s // CHECK: cc1as // CHECK: -mrelax-all +// RISC-V does not enable -mrelax-all +// RUN: %clang -### -c -save-temps -integrated-as --target=riscv64 %s 2>&1 | FileCheck %s -check-prefix=RISCV-RELAX + +// RISCV-RELAX: cc1as +// RISCV-RELAX-NOT: -mrelax-all + // RUN: %clang -### -fintegrated-as -c -save-temps %s 2>&1 | FileCheck %s -check-prefix FIAS // FIAS: cc1as diff --git a/clang/test/Driver/riscv-features.c b/clang/test/Driver/riscv-features.c index 5e1db5ba1ed3e96ddf939c9063c7cc98a11031d1..cfe293cd4667ff24c224a73353bfca8923beb2b7 100644 --- a/clang/test/Driver/riscv-features.c +++ b/clang/test/Driver/riscv-features.c @@ -37,6 +37,8 @@ // RUN: %clang --target=riscv32-unknown-elf -### %s -mno-strict-align 2>&1 | FileCheck %s -check-prefix=FAST-UNALIGNED-ACCESS // RUN: %clang --target=riscv32-unknown-elf -### %s -mstrict-align 2>&1 | FileCheck %s -check-prefix=NO-FAST-UNALIGNED-ACCESS +// RUN: touch %t.o +// RUN: %clang --target=riscv32-unknown-elf -### %t.o -mno-strict-align -mstrict-align // FAST-UNALIGNED-ACCESS: "-target-feature" "+unaligned-scalar-mem" "-target-feature" "+unaligned-vector-mem" // NO-FAST-UNALIGNED-ACCESS: "-target-feature" "-unaligned-scalar-mem" "-target-feature" "-unaligned-vector-mem" diff --git a/clang/test/FixIt/format-darwin-enum-class.cpp b/clang/test/FixIt/format-darwin-enum-class.cpp index 5aa1a80d8614c20ebcd1d3b59cfa7c853142e64d..6d0bb80e982d7e2cf1644f212e23d85906f6be60 100644 --- a/clang/test/FixIt/format-darwin-enum-class.cpp +++ b/clang/test/FixIt/format-darwin-enum-class.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -verify -Wformat %s -// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -fdiagnostics-parseable-fixits -Wformat %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -verify -Wformat-pedantic %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -fdiagnostics-parseable-fixits -Wformat-pedantic %s 2>&1 | FileCheck %s extern "C" int printf(const char * restrict, ...); diff --git a/clang/test/FixIt/format.cpp b/clang/test/FixIt/format.cpp index 4e6573a4f9e54e3e96a685e167149fab0aa4327b..d663c0fb35e1385e34a2c9fce1a5af11971d80c6 100644 --- a/clang/test/FixIt/format.cpp +++ b/clang/test/FixIt/format.cpp @@ -1,5 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wformat %s -// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -Wformat %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-pedantic %s +// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -Wformat-pedantic %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -Wformat %s -verify=okay +// okay-no-diagnostics extern "C" int printf(const char *, ...); #define LOG(...) printf(__VA_ARGS__) diff --git a/clang/test/Lexer/bitint-constants-compat.c b/clang/test/Lexer/bitint-constants-compat.c index 607ae88a6188bbb800d85580a24f884000fc8339..d8bff94ef88caa39ca4edec28bbc0bc5b71ca11f 100644 --- a/clang/test/Lexer/bitint-constants-compat.c +++ b/clang/test/Lexer/bitint-constants-compat.c @@ -1,14 +1,23 @@ // RUN: %clang_cc1 -std=c17 -fsyntax-only -verify=ext -Wno-unused %s // RUN: %clang_cc1 -std=c2x -fsyntax-only -verify=compat -Wpre-c2x-compat -Wno-unused %s -// RUN: %clang_cc1 -fsyntax-only -verify=cpp -Wno-unused -x c++ %s +// RUN: %clang_cc1 -fsyntax-only -verify=cpp -Wbit-int-extension -Wno-unused -x c++ %s #if 18446744073709551615uwb // ext-warning {{'_BitInt' suffix for literals is a C23 extension}} \ compat-warning {{'_BitInt' suffix for literals is incompatible with C standards before C23}} \ cpp-error {{invalid suffix 'uwb' on integer constant}} #endif +#if 18446744073709551615__uwb // ext-error {{invalid suffix '__uwb' on integer constant}} \ + compat-error {{invalid suffix '__uwb' on integer constant}} \ + cpp-warning {{'_BitInt' suffix for literals is a Clang extension}} +#endif + void func(void) { 18446744073709551615wb; // ext-warning {{'_BitInt' suffix for literals is a C23 extension}} \ compat-warning {{'_BitInt' suffix for literals is incompatible with C standards before C23}} \ cpp-error {{invalid suffix 'wb' on integer constant}} + + 18446744073709551615__wb; // ext-error {{invalid suffix '__wb' on integer constant}} \ + compat-error {{invalid suffix '__wb' on integer constant}} \ + cpp-warning {{'_BitInt' suffix for literals is a Clang extension}} } diff --git a/clang/test/Lexer/bitint-constants.cpp b/clang/test/Lexer/bitint-constants.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fb6ac35467cd6716442d9c4d338514b08b1b2039 --- /dev/null +++ b/clang/test/Lexer/bitint-constants.cpp @@ -0,0 +1,178 @@ +// RUN: %clang_cc1 -triple aarch64-unknown-unknown -fsyntax-only -verify -Wno-unused %s + +// Test that the preprocessor behavior makes sense. +#if 1__wb != 1 +#error "wb suffix must be recognized by preprocessor" +#endif +#if 1__uwb != 1 +#error "uwb suffix must be recognized by preprocessor" +#endif +#if !(-1__wb < 0) +#error "wb suffix must be interpreted as signed" +#endif +#if !(-1__uwb > 0) +#error "uwb suffix must be interpreted as unsigned" +#endif + +#if 18446744073709551615__uwb != 18446744073709551615ULL +#error "expected the max value for uintmax_t to compare equal" +#endif + +// Test that the preprocessor gives appropriate diagnostics when the +// literal value is larger than what can be stored in a [u]intmax_t. +#if 18446744073709551616__wb != 0ULL // expected-error {{integer literal is too large to be represented in any integer type}} +#error "never expected to get here due to error" +#endif +#if 18446744073709551616__uwb != 0ULL // expected-error {{integer literal is too large to be represented in any integer type}} +#error "never expected to get here due to error" +#endif + +// Despite using a bit-precise integer, this is expected to overflow +// because all preprocessor arithmetic is done in [u]intmax_t, so this +// should result in the value 0. +#if 18446744073709551615__uwb + 1 != 0ULL +#error "expected modulo arithmetic with uintmax_t width" +#endif + +// Because this bit-precise integer is signed, it will also overflow, +// but Clang handles that by converting to uintmax_t instead of +// intmax_t. +#if 18446744073709551615__wb + 1 != 0LL // expected-warning {{integer literal is too large to be represented in a signed integer type, interpreting as unsigned}} +#error "expected modulo arithmetic with uintmax_t width" +#endif + +// Test that just because the preprocessor can't figure out the bit +// width doesn't mean we can't form the constant, it just means we +// can't use the value in a preprocessor conditional. +unsigned _BitInt(65) Val = 18446744073709551616__uwb; +// UDL test to make sure underscore parsing is correct +unsigned operator ""_(const char *); + +void ValidSuffix(void) { + // Decimal literals. + 1__wb; + 1__WB; + -1__wb; + _Static_assert((int)1__wb == 1, "not 1?"); + _Static_assert((int)-1__wb == -1, "not -1?"); + + 1__uwb; + 1__uWB; + 1__Uwb; + 1__UWB; + 1u__wb; + 1__WBu; + 1U__WB; + _Static_assert((unsigned int)1__uwb == 1u, "not 1?"); + + 1'2__wb; + 1'2__uwb; + _Static_assert((int)1'2__wb == 12, "not 12?"); + _Static_assert((unsigned int)1'2__uwb == 12u, "not 12?"); + + // Hexadecimal literals. + 0x1__wb; + 0x1__uwb; + 0x0'1'2'3__wb; + 0xA'B'c'd__uwb; + _Static_assert((int)0x0'1'2'3__wb == 0x0123, "not 0x0123"); + _Static_assert((unsigned int)0xA'B'c'd__uwb == 0xABCDu, "not 0xABCD"); + + // Binary literals. + 0b1__wb; + 0b1__uwb; + 0b1'0'1'0'0'1__wb; + 0b0'1'0'1'1'0__uwb; + _Static_assert((int)0b1__wb == 1, "not 1?"); + _Static_assert((unsigned int)0b1__uwb == 1u, "not 1?"); + + // Octal literals. + 01__wb; + 01__uwb; + 0'6'0__wb; + 0'0'1__uwb; + 0__wbu; + 0__WBu; + 0U__wb; + 0U__WB; + 0__wb; + _Static_assert((int)0__wb == 0, "not 0?"); + _Static_assert((unsigned int)0__wbu == 0u, "not 0?"); + + // Imaginary or Complex. These are allowed because _Complex can work with any + // integer type, and that includes _BitInt. + 1__wbi; + 1i__wb; + 1__wbj; + + //UDL test as single underscore + unsigned i = 1.0_; +} + +void InvalidSuffix(void) { + // Can't mix the case of wb or WB, and can't rearrange the letters. + 0__wB; // expected-error {{invalid suffix '__wB' on integer constant}} + 0__Wb; // expected-error {{invalid suffix '__Wb' on integer constant}} + 0__bw; // expected-error {{invalid suffix '__bw' on integer constant}} + 0__BW; // expected-error {{invalid suffix '__BW' on integer constant}} + + // Trailing digit separators should still diagnose. + 1'2'__wb; // expected-error {{digit separator cannot appear at end of digit sequence}} + 1'2'__uwb; // expected-error {{digit separator cannot appear at end of digit sequence}} + + // Long. + 1l__wb; // expected-error {{invalid suffix}} + 1__wbl; // expected-error {{invalid suffix}} + 1l__uwb; // expected-error {{invalid suffix}} + 1__l; // expected-error {{invalid suffix}} + 1ul__wb; // expected-error {{invalid suffix}} + + // Long long. + 1ll__wb; // expected-error {{invalid suffix}} + 1__uwbll; // expected-error {{invalid suffix}} + + // Floating point. + 0.1__wb; // expected-error {{invalid suffix}} + 0.1f__wb; // expected-error {{invalid suffix}} + + // Repetitive suffix. + 1__wb__wb; // expected-error {{invalid suffix}} + 1__uwbuwb; // expected-error {{invalid suffix}} + 1__wbuwb; // expected-error {{invalid suffix}} + 1__uwbwb; // expected-error {{invalid suffix}} + + // Missing or extra characters in suffix. + 1__; // expected-error {{invalid suffix}} + 1__u; // expected-error {{invalid suffix}} + 1___; // expected-error {{invalid suffix}} + 1___WB; // expected-error {{invalid suffix}} + 1__wb__; // expected-error {{invalid suffix}} + 1__w; // expected-error {{invalid suffix}} + 1__b; // expected-error {{invalid suffix}} +} + +void ValidSuffixInvalidValue(void) { + // This is a valid suffix, but the value is larger than one that fits within + // the width of BITINT_MAXWIDTH. When this value changes in the future, the + // test cases should pick a new value that can't be represented by a _BitInt, + // but also add a test case that a 129-bit literal still behaves as-expected. + _Static_assert(__BITINT_MAXWIDTH__ <= 128, + "Need to pick a bigger constant for the test case below."); + 0xFFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF'1__wb; // expected-error {{integer literal is too large to be represented in any signed integer type}} + 0xFFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF'1__uwb; // expected-error {{integer literal is too large to be represented in any integer type}} +} + +void TestTypes(void) { + // 2 value bits, one sign bit + _Static_assert(__is_same(decltype(3__wb), _BitInt(3))); + // 2 value bits, one sign bit + _Static_assert(__is_same(decltype(-3__wb), _BitInt(3))); + // 2 value bits, no sign bit + _Static_assert(__is_same(decltype(3__uwb), unsigned _BitInt(2))); + // 4 value bits, one sign bit + _Static_assert(__is_same(decltype(0xF__wb), _BitInt(5))); + // 4 value bits, one sign bit + _Static_assert(__is_same(decltype(-0xF__wb), _BitInt(5))); + // 4 value bits, no sign bit + _Static_assert(__is_same(decltype(0xF__uwb), unsigned _BitInt(4))); +} diff --git a/clang/test/Modules/add-remove-irrelevant-module-map.m b/clang/test/Modules/add-remove-irrelevant-module-map.m deleted file mode 100644 index 7e3e58037e6f21100c15fa294b72b58d7c08371b..0000000000000000000000000000000000000000 --- a/clang/test/Modules/add-remove-irrelevant-module-map.m +++ /dev/null @@ -1,32 +0,0 @@ -// RUN: rm -rf %t && mkdir %t -// RUN: split-file %s %t - -//--- a/module.modulemap -module a {} - -//--- b/module.modulemap -module b {} - -//--- c/module.modulemap -module c {} - -//--- module.modulemap -module m { header "m.h" } -//--- m.h -@import c; - -//--- test-simple.m -// expected-no-diagnostics -@import m; - -// Build modules with the non-affecting "a/module.modulemap". -// RUN: %clang_cc1 -I %t/a -I %t/b -I %t/c -I %t -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -fdisable-module-hash %t/test-simple.m -verify -// RUN: mv %t/cache %t/cache-with - -// Build modules without the non-affecting "a/module.modulemap". -// RUN: rm -rf %t/a/module.modulemap -// RUN: %clang_cc1 -I %t/a -I %t/b -I %t/c -I %t -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -fdisable-module-hash %t/test-simple.m -verify -// RUN: mv %t/cache %t/cache-without - -// Check that the PCM files are bit-for-bit identical. -// RUN: diff %t/cache-with/m.pcm %t/cache-without/m.pcm diff --git a/clang/test/Modules/pr85122.cppm b/clang/test/Modules/pr85122.cppm new file mode 100644 index 0000000000000000000000000000000000000000..a4c89f13711a36a7160e4389060036ad1d6403a8 --- /dev/null +++ b/clang/test/Modules/pr85122.cppm @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -std=c++20 %s -Wall -fsyntax-only -verify + +// expected-no-diagnostics +export module a; + +export constexpr auto a = []{}; diff --git a/clang/test/Modules/prune-non-affecting-module-map-files.m b/clang/test/Modules/prune-non-affecting-module-map-files.m new file mode 100644 index 0000000000000000000000000000000000000000..ba2b3a306eaf460c85fc3594e90943b13d33f967 --- /dev/null +++ b/clang/test/Modules/prune-non-affecting-module-map-files.m @@ -0,0 +1,62 @@ +// Check that the presence of non-affecting module map files does not affect the +// contents of PCM files. + +// RUN: rm -rf %t && mkdir %t +// RUN: split-file %s %t + +//--- a/module.modulemap +module a {} + +//--- b/module.modulemap +module b {} + +//--- c/module.modulemap +module c { header "c.h" } +//--- c/c.h +@import b; + +//--- tu.m +@import c; + +//--- explicit-mms-common-args.rsp +-fmodule-map-file=b/module.modulemap -fmodule-map-file=c/module.modulemap -fmodules -fmodules-cache-path=cache -fdisable-module-hash -fsyntax-only tu.m +//--- implicit-search-args.rsp +-I a -I b -I c -fimplicit-module-maps -fmodules -fmodules-cache-path=cache -fdisable-module-hash -fsyntax-only tu.m +//--- implicit-search-args.rsp-end + +// Test with explicit module map files. +// +// RUN: %clang_cc1 -working-directory %t @%t/explicit-mms-common-args.rsp +// RUN: mv %t/cache %t/cache-explicit-no-a-prune +// RUN: %clang_cc1 -working-directory %t @%t/explicit-mms-common-args.rsp -fno-modules-prune-non-affecting-module-map-files +// RUN: mv %t/cache %t/cache-explicit-no-a-keep +// +// RUN: %clang_cc1 -working-directory %t -fmodule-map-file=a/module.modulemap @%t/explicit-mms-common-args.rsp +// RUN: mv %t/cache %t/cache-explicit-a-prune +// RUN: %clang_cc1 -working-directory %t -fmodule-map-file=a/module.modulemap @%t/explicit-mms-common-args.rsp -fno-modules-prune-non-affecting-module-map-files +// RUN: mv %t/cache %t/cache-explicit-a-keep +// +// RUN: diff %t/cache-explicit-no-a-prune/c.pcm %t/cache-explicit-a-prune/c.pcm +// RUN: not diff %t/cache-explicit-no-a-keep/c.pcm %t/cache-explicit-a-keep/c.pcm + +// Test with implicit module map search. +// +// RUN: %clang_cc1 -working-directory %t @%t/implicit-search-args.rsp +// RUN: mv %t/cache %t/cache-implicit-no-a-prune +// RUN: %clang_cc1 -working-directory %t @%t/implicit-search-args.rsp -fno-modules-prune-non-affecting-module-map-files +// RUN: mv %t/cache %t/cache-implicit-no-a-keep +// +// FIXME: Instead of removing "a/module.modulemap" from the file system, we +// could drop the "-I a" search path argument in combination with the +// "-fmodules-skip-header-search-paths" flag. Unfortunately, that flag +// does not prevent serialization of the search path usage bit vector, +// making the files differ anyways. +// RUN: rm %t/a/module.modulemap +// +// RUN: %clang_cc1 -working-directory %t @%t/implicit-search-args.rsp +// RUN: mv %t/cache %t/cache-implicit-a-prune +// RUN: %clang_cc1 -working-directory %t @%t/implicit-search-args.rsp -fno-modules-prune-non-affecting-module-map-files +// RUN: mv %t/cache %t/cache-implicit-a-keep +// +// RUN: diff %t/cache-implicit-no-a-prune/c.pcm %t/cache-implicit-a-prune/c.pcm +// RUN: not diff %t/cache-implicit-no-a-keep/c.pcm %t/cache-implicit-a-keep/c.pcm diff --git a/clang/test/Parser/pragma-unroll.cpp b/clang/test/Parser/pragma-unroll.cpp index c89cf49a002065971e8c5633b458af970901f7a8..f41bd7a18d5a4199c0bcd7d705dc1e7e807aa970 100644 --- a/clang/test/Parser/pragma-unroll.cpp +++ b/clang/test/Parser/pragma-unroll.cpp @@ -40,14 +40,18 @@ void test(int *List, int Length) { /* expected-error {{expected ')'}} */ #pragma unroll(() /* expected-error {{expected expression}} */ #pragma unroll - -/* expected-error {{invalid value '0'; must be positive}} */ #pragma unroll(0) -/* expected-error {{invalid value '0'; must be positive}} */ #pragma unroll 0 +/* The values of 0 and 1 block any unrolling of the loop. */ #pragma unroll 0 /* expected-error {{value '3000000000' is too large}} */ #pragma unroll(3000000000) /* expected-error {{value '3000000000' is too large}} */ #pragma unroll 3000000000 while (i-8 < Length) { List[i] = i; } +/* The values of 0 and 1 block any unrolling of the loop. */ #pragma unroll(0) + while (i-8 < Length) { + List[i] = i; + } + #pragma unroll /* expected-error {{expected a for, while, or do-while loop to follow '#pragma unroll'}} */ int j = Length; #pragma unroll 4 diff --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c index ddf40f71701eda4522e9df5032352d165e956b7d..799f22b8c120e599c2fdcf775934a2928ec5b264 100644 --- a/clang/test/ParserOpenACC/parse-clauses.c +++ b/clang/test/ParserOpenACC/parse-clauses.c @@ -911,16 +911,12 @@ void IntExprParsing() { #pragma acc parallel num_gangs(invalid) {} - // expected-error@+2{{expected ')'}} - // expected-note@+1{{to match this '('}} #pragma acc parallel num_gangs(5, 4) {} - // expected-warning@+1{{OpenACC clause 'num_gangs' not yet implemented, clause ignored}} #pragma acc parallel num_gangs(5) {} - // expected-warning@+1{{OpenACC clause 'num_gangs' not yet implemented, clause ignored}} #pragma acc parallel num_gangs(returns_int()) {} diff --git a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c index 55c97c73e8b6952a634bdd0095afc741bfbeaa64..6a1feeb9bf53976325eda4e393c738a392c103b9 100644 --- a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c +++ b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c @@ -1,6 +1,6 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve \ -// RUN: -target-feature +sme2 -target-feature +sve2 -target-feature +neon -fsyntax-only -verify %s +// RUN: -target-feature +sme2 -target-feature +sve2 -target-feature +neon -Waarch64-sme-attributes -fsyntax-only -verify %s // REQUIRES: aarch64-registered-target @@ -33,6 +33,7 @@ svuint32_t incompat_sve_sm(svbool_t pg, svuint32_t a, int16_t b) __arm_streaming return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b); } +// expected-warning@+1 {{passing/returning a VL-dependent argument to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}} __arm_locally_streaming svuint32_t incompat_sve_ls(svbool_t pg, svuint32_t a, int64_t b) { // expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming function}} return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b); @@ -48,6 +49,7 @@ svuint32_t incompat_sve2_sm(svbool_t pg, svuint32_t a, int64_t b) __arm_streamin return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b); } +// expected-warning@+1 {{passing/returning a VL-dependent argument to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}} __arm_locally_streaming svuint32_t incompat_sve2_ls(svbool_t pg, svuint32_t a, int64_t b) { // expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming function}} return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b); @@ -68,6 +70,7 @@ svfloat64_t streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) __arm_ return svadd_n_f64_m(pg, a, b); } +// expected-warning@+1 {{passing/returning a VL-dependent argument to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}} __arm_locally_streaming svfloat64_t locally_streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) { // expected-no-warning return svadd_n_f64_m(pg, a, b); @@ -83,6 +86,7 @@ svint16_t streaming_caller_sve2(svint16_t op1, svint16_t op2) __arm_streaming { return svmul_lane_s16(op1, op2, 0); } +// expected-warning@+1 {{passing/returning a VL-dependent argument to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}} __arm_locally_streaming svint16_t locally_streaming_caller_sve2(svint16_t op1, svint16_t op2) { // expected-no-warning return svmul_lane_s16(op1, op2, 0); diff --git a/clang/test/Sema/aarch64-sme-func-attrs.c b/clang/test/Sema/aarch64-sme-func-attrs.c index bfc8768c3f36e1c0c07cf1b1362275870aca2323..12de16509ccb8d276282c14263614d83e29dc6b3 100644 --- a/clang/test/Sema/aarch64-sme-func-attrs.c +++ b/clang/test/Sema/aarch64-sme-func-attrs.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -fsyntax-only -verify %s -// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -fsyntax-only -verify=expected-cpp -x c++ %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +sve -Waarch64-sme-attributes -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +sve -Waarch64-sme-attributes -fsyntax-only -verify=expected-cpp -x c++ %s // Valid attributes @@ -496,3 +496,135 @@ void fmv_caller() { just_fine(); incompatible_locally_streaming(); } + +void sme_streaming_with_vl_arg(__SVInt8_t a) __arm_streaming { } + +__SVInt8_t sme_streaming_returns_vl(void) __arm_streaming { __SVInt8_t r; return r; } + +void sme_streaming_compatible_with_vl_arg(__SVInt8_t a) __arm_streaming_compatible { } + +__SVInt8_t sme_streaming_compatible_returns_vl(void) __arm_streaming_compatible { __SVInt8_t r; return r; } + +void sme_no_streaming_with_vl_arg(__SVInt8_t a) { } + +__SVInt8_t sme_no_streaming_returns_vl(void) { __SVInt8_t r; return r; } + +// expected-warning@+2 {{passing/returning a VL-dependent argument to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}} +// expected-cpp-warning@+1 {{passing/returning a VL-dependent argument to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}} +__arm_locally_streaming void sme_locally_streaming_with_vl_arg(__SVInt8_t a) { } + +// expected-warning@+2 {{passing/returning a VL-dependent argument to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}} +// expected-cpp-warning@+1 {{passing/returning a VL-dependent argument to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}} +__arm_locally_streaming __SVInt8_t sme_locally_streaming_returns_vl(void) { __SVInt8_t r; return r; } + +void sme_no_streaming_calling_streaming_with_vl_args() { + __SVInt8_t a; + // expected-warning@+2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}} + // expected-cpp-warning@+1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}} + sme_streaming_with_vl_arg(a); +} + +void sme_no_streaming_calling_streaming_with_return_vl() { + // expected-warning@+2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}} + // expected-cpp-warning@+1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}} + __SVInt8_t r = sme_streaming_returns_vl(); +} + +void sme_streaming_calling_non_streaming_with_vl_args(void) __arm_streaming { + __SVInt8_t a; + // expected-warning@+2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}} + // expected-cpp-warning@+1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}} + sme_no_streaming_with_vl_arg(a); +} + +void sme_streaming_calling_non_streaming_with_return_vl(void) __arm_streaming { + // expected-warning@+2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}} + // expected-cpp-warning@+1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}} + __SVInt8_t r = sme_no_streaming_returns_vl(); +} + +void sme_no_streaming_calling_streaming_with_vl_args_param(__SVInt8_t arg, void (*sc)( __SVInt8_t arg) __arm_streaming) { + // expected-warning@+2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}} + // expected-cpp-warning@+1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}} + sc(arg); +} + +__SVInt8_t sme_no_streaming_calling_streaming_return_vl_param(__SVInt8_t (*s)(void) __arm_streaming) { + // expected-warning@+2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}} + // expected-cpp-warning@+1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}} + return s(); +} + +void sme_streaming_compatible_calling_streaming_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible { + // expected-warning@+2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}} + // expected-cpp-warning@+1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}} + sme_streaming_with_vl_arg(arg); +} + +void sme_streaming_compatible_calling_sme_streaming_return_vl(void) __arm_streaming_compatible { + // expected-warning@+2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}} + // expected-cpp-warning@+1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}} + __SVInt8_t r = sme_streaming_returns_vl(); +} + +void sme_streaming_compatible_calling_no_streaming_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible { + // expected-warning@+2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}} + // expected-cpp-warning@+1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}} + sme_no_streaming_with_vl_arg(arg); +} + +void sme_streaming_compatible_calling_no_sme_streaming_return_vl(void) __arm_streaming_compatible { + // expected-warning@+2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}} + // expected-cpp-warning@+1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}} + __SVInt8_t r = sme_no_streaming_returns_vl(); +} + +void sme_streaming_calling_streaming(__SVInt8_t arg, void (*s)( __SVInt8_t arg) __arm_streaming) __arm_streaming { + s(arg); +} + +__SVInt8_t sme_streaming_calling_streaming_return_vl(__SVInt8_t (*s)(void) __arm_streaming) __arm_streaming { + return s(); +} + +void sme_streaming_calling_streaming_with_vl_args(__SVInt8_t a) __arm_streaming { + sme_streaming_with_vl_arg(a); +} + +void sme_streaming_calling_streaming_with_return_vl(void) __arm_streaming { + __SVInt8_t r = sme_streaming_returns_vl(); +} + +void sme_streaming_calling_streaming_compatible_with_vl_args(__SVInt8_t a) __arm_streaming { + sme_streaming_compatible_with_vl_arg(a); +} + +void sme_streaming_calling_streaming_compatible_with_return_vl(void) __arm_streaming { + __SVInt8_t r = sme_streaming_compatible_returns_vl(); +} + +void sme_no_streaming_calling_streaming_compatible_with_vl_args() { + __SVInt8_t a; + sme_streaming_compatible_with_vl_arg(a); +} + +void sme_no_streaming_calling_streaming_compatible_with_return_vl() { + __SVInt8_t r = sme_streaming_compatible_returns_vl(); +} + +void sme_no_streaming_calling_non_streaming_compatible_with_vl_args() { + __SVInt8_t a; + sme_no_streaming_with_vl_arg(a); +} + +void sme_no_streaming_calling_non_streaming_compatible_with_return_vl() { + __SVInt8_t r = sme_no_streaming_returns_vl(); +} + +void sme_streaming_compatible_calling_streaming_compatible_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible { + sme_streaming_compatible_with_vl_arg(arg); +} + +void sme_streaming_compatible_calling_streaming_compatible_with_return_vl(void) __arm_streaming_compatible { + __SVInt8_t r = sme_streaming_compatible_returns_vl(); +} diff --git a/clang/test/Sema/bitint-bitfield-promote.c b/clang/test/Sema/bitint-bitfield-promote.c new file mode 100644 index 0000000000000000000000000000000000000000..e82e94975cfd4ac36825ca99f865ac6fc8b01e87 --- /dev/null +++ b/clang/test/Sema/bitint-bitfield-promote.c @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c23 %s + +// GH87641 noticed that integer promotion of a bit-field of bit-precise integer +// type was promoting to int rather than the type of the bit-field. +struct S { + unsigned _BitInt(7) x : 2; + unsigned _BitInt(2) y : 2; + unsigned _BitInt(72) z : 28; + _BitInt(31) a : 12; + _BitInt(33) b : 33; +}; + +// We don't have to worry about promotion cases where the bit-precise type is +// smaller than the width of the bit-field; that can't happen. +struct T { + unsigned _BitInt(28) oh_no : 72; // expected-error {{width of bit-field 'oh_no' (72 bits) exceeds the width of its type (28 bits)}} +}; + +static_assert( + _Generic(+(struct S){}.x, + int : 0, + unsigned _BitInt(7) : 1, + unsigned _BitInt(2) : 2 + ) == 1); + +static_assert( + _Generic(+(struct S){}.y, + int : 0, + unsigned _BitInt(7) : 1, + unsigned _BitInt(2) : 2 + ) == 2); + +static_assert( + _Generic(+(struct S){}.z, + int : 0, + unsigned _BitInt(72) : 1, + unsigned _BitInt(28) : 2 + ) == 1); + +static_assert( + _Generic(+(struct S){}.a, + int : 0, + _BitInt(31) : 1, + _BitInt(12) : 2, + unsigned _BitInt(31) : 3 + ) == 1); + +static_assert( + _Generic(+(struct S){}.b, + int : 0, + long long : 1, + _BitInt(33) : 2, + unsigned _BitInt(33) : 3 + ) == 2); diff --git a/clang/test/Sema/ppc-attr-target-inline.c b/clang/test/Sema/ppc-attr-target-inline.c index 07ed006822658437bef3055d32e45cac807b914e..ad198b842bb0329a474de8ce5cb0beebeff05498 100644 --- a/clang/test/Sema/ppc-attr-target-inline.c +++ b/clang/test/Sema/ppc-attr-target-inline.c @@ -1,5 +1,5 @@ // REQUIRES: powerpc-registered-target -// RUN: %clang_cc1 -triple powerpc64le -target-feature +htm -fsyntax-only -emit-llvm %s -verify +// RUN: %clang_cc1 -triple powerpc64le -target-feature +htm -fsyntax-only -emit-llvm-only %s -verify __attribute__((always_inline)) int test1(int *x) { diff --git a/clang/test/Sema/unroll-template-value-crash.cpp b/clang/test/Sema/unroll-template-value-crash.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d8953c4845c265fae4aeda2bdb0f5c8d77f43ece --- /dev/null +++ b/clang/test/Sema/unroll-template-value-crash.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -x c++ -verify %s +// expected-no-diagnostics + +template void foo() { + #pragma unroll Unroll + for (int i = 0; i < Unroll; ++i); + + #pragma GCC unroll Unroll + for (int i = 0; i < Unroll; ++i); +} diff --git a/clang/test/SemaCXX/aarch64-sve-resolve-type.cpp b/clang/test/SemaCXX/aarch64-sve-resolve-type.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a563848cdcf98bf3f00dbfd9dc241dc3f1f043d --- /dev/null +++ b/clang/test/SemaCXX/aarch64-sve-resolve-type.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fsyntax-only %s + +// REQUIRES: aarch64-registered-target || arm-registered-target + +// expected-no-diagnostics + +struct a {}; +__SVFloat32_t b(a); +template using e = decltype(b(c())); +e f(a); +template using h = decltype(f(c())); +template struct i { + static void j() { + a d; + g()(d); + } +}; +struct k { + template void operator()(c) { + [](h) {}; + } + void l() { i::j; } +}; diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp index 6f04264a655ad5376081203ee14e408ed25c13d7..508a3a5da76a915ff6f0726b51eb8cbf5fdf4783 100644 --- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp +++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp @@ -289,3 +289,21 @@ using String = Array; // Verify no crash on constructing the aggregate deduction guides. String s("hello"); } // namespace test21 + +// GH89013 +namespace test22 { +class Base {}; +template +class Derived final : public Base {}; + +template +requires __is_base_of(Base, D) +struct Foo { + explicit Foo(D) {} +}; + +template +using AFoo = Foo>; + +AFoo a(Derived{}); +} // namespace test22 diff --git a/clang/test/SemaCXX/cxx23-assume.cpp b/clang/test/SemaCXX/cxx23-assume.cpp index 478da092471affa037b12dcf0d6441281e2d4e3e..8676970de14f61ed2a45df2d3e71f559ca86bbe7 100644 --- a/clang/test/SemaCXX/cxx23-assume.cpp +++ b/clang/test/SemaCXX/cxx23-assume.cpp @@ -1,5 +1,7 @@ // RUN: %clang_cc1 -std=c++23 -x c++ %s -verify // RUN: %clang_cc1 -std=c++20 -pedantic -x c++ %s -verify=ext,expected +// RUN: %clang_cc1 -std=c++23 -x c++ %s -verify -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 -std=c++20 -pedantic -x c++ %s -verify=ext,expected -fexperimental-new-constant-interpreter struct A{}; struct B{ explicit operator bool() { return true; } }; diff --git a/clang/test/SemaCXX/cxx2c-pack-indexing.cpp b/clang/test/SemaCXX/cxx2c-pack-indexing.cpp index e13635383b6ca6b909b23cf8d8160568e1f1ec4e..606715e6aacffdbbd5fadcd5525ceacf4e6dc278 100644 --- a/clang/test/SemaCXX/cxx2c-pack-indexing.cpp +++ b/clang/test/SemaCXX/cxx2c-pack-indexing.cpp @@ -154,3 +154,9 @@ void f() { } } + +namespace GH88929 { + bool b = a...[0]; // expected-error {{use of undeclared identifier 'a'}} + using E = P...[0]; // expected-error {{unknown type name 'P'}} \ + // expected-error {{expected ';' after alias declaration}} +} diff --git a/clang/test/SemaCXX/format-strings.cpp b/clang/test/SemaCXX/format-strings.cpp index f554e905d6455bde4aed34c06d8dba7f1924b041..48cf23999a94f7ba79d4fe527dbf0db3566db559 100644 --- a/clang/test/SemaCXX/format-strings.cpp +++ b/clang/test/SemaCXX/format-strings.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -Wformat-non-iso -fblocks %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -Wformat-non-iso -Wformat-pedantic -fblocks %s // RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -Wformat-non-iso -fblocks -std=c++98 %s -// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -Wformat-non-iso -fblocks -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -Wformat-non-iso -Wformat-pedantic -fblocks -std=c++11 %s #include diff --git a/clang/test/SemaCXX/static-assert-cxx26.cpp b/clang/test/SemaCXX/static-assert-cxx26.cpp index f4ede74f9214a44bb7fb68962871980cdb5f1830..7d896d8b365b740e3dec35971f7cb47eabccca6b 100644 --- a/clang/test/SemaCXX/static-assert-cxx26.cpp +++ b/clang/test/SemaCXX/static-assert-cxx26.cpp @@ -341,3 +341,77 @@ struct Callable { } data; }; static_assert(false, Callable{}); // expected-error {{static assertion failed: hello}} + +namespace GH89407 { +struct A { + constexpr __SIZE_TYPE__ size() const { return -1; } + constexpr const char* data() const { return ""; } +}; + +struct B { + constexpr long long size() const { return 18446744073709551615U; } + constexpr const char* data() const { return ""; } +}; + +struct C { + constexpr __int128 size() const { return -1; } + constexpr const char* data() const { return ""; } +}; + +struct D { + constexpr unsigned __int128 size() const { return -1; } + constexpr const char* data() const { return ""; } +}; + +struct E { + constexpr __SIZE_TYPE__ size() const { return 18446744073709551615U; } + constexpr const char* data() const { return ""; } +}; + +static_assert(true, A{}); // expected-error {{the message in this static assertion is not a constant expression}} + // expected-note@-1 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} +static_assert(true, B{}); // expected-error {{call to 'size()' evaluates to -1, which cannot be narrowed to type 'unsigned long'}} + // expected-error@-1 {{the message in this static assertion is not a constant expression}} + // expected-note@-2 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} +static_assert(true, C{}); // expected-error {{call to 'size()' evaluates to -1, which cannot be narrowed to type 'unsigned long'}} + // expected-error@-1 {{the message in this static assertion is not a constant expression}} + // expected-note@-2 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} +static_assert(true, D{}); // expected-error {{call to 'size()' evaluates to 340282366920938463463374607431768211455, which cannot be narrowed to type 'unsigned long'}} + // expected-error@-1 {{the message in this static assertion is not a constant expression}} + // expected-note@-2 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} +static_assert(true, E{}); // expected-error {{the message in this static assertion is not a constant expression}} + // expected-note@-1 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} + +static_assert( + false, // expected-error {{static assertion failed}} + A{} // expected-error {{the message in a static assertion must be produced by a constant expression}} + // expected-note@-1 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} +); + +static_assert( + false, // expected-error {{static assertion failed}} + B{} // expected-error {{call to 'size()' evaluates to -1, which cannot be narrowed to type 'unsigned long'}} + // expected-error@-1 {{the message in a static assertion must be produced by a constant expression}} + // expected-note@-2 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} +); + +static_assert( + false, // expected-error {{static assertion failed}} + C{} // expected-error {{call to 'size()' evaluates to -1, which cannot be narrowed to type 'unsigned long'}} + // expected-error@-1 {{the message in a static assertion must be produced by a constant expression}} + // expected-note@-2 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} +); + +static_assert( + false, // expected-error {{static assertion failed}} + D{} // expected-error {{call to 'size()' evaluates to 340282366920938463463374607431768211455, which cannot be narrowed to type 'unsigned long'}} + // expected-error@-1 {{the message in a static assertion must be produced by a constant expression}} + // expected-note@-2 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} +); + +static_assert( + false, // expected-error {{static assertion failed}} + E{} // expected-error {{the message in a static assertion must be produced by a constant expression}} + // expected-note@-1 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} +); +} diff --git a/clang/test/SemaHLSL/BuiltIns/any-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/any-errors.hlsl index 862b94652073122e6249d7a60e2df9b58c838cab..7bb5308c5d5ba7bfa8066b6430d20a01cf7defd4 100644 --- a/clang/test/SemaHLSL/BuiltIns/any-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/any-errors.hlsl @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -verify-ignore-unexpected bool test_too_few_arg() { return __builtin_hlsl_elementwise_any(); diff --git a/clang/test/SemaHLSL/BuiltIns/clamp-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/clamp-errors.hlsl index 4c0e5315ce532e14360d5ca899a6e559d899e640..f669098ef515d8d4e97131b6af0f5395188b25c4 100644 --- a/clang/test/SemaHLSL/BuiltIns/clamp-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/clamp-errors.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -verify-ignore-unexpected float2 test_no_second_arg(float2 p0) { return __builtin_hlsl_elementwise_clamp(p0); diff --git a/clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl index ba7ffc20484ae01b511f370e1fa25e254606527a..095f3c12ba8731d047bf2c5dd16edfef5cea9494 100644 --- a/clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -verify-ignore-unexpected float test_no_second_arg(float2 p0) { return __builtin_hlsl_dot(p0); diff --git a/clang/test/SemaHLSL/BuiltIns/exp-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/exp-errors.hlsl index e2e79abb74a32d213cacef1a53ebde3004f2a917..321fc915ec01fcbde4433f7c2143cf662a178575 100644 --- a/clang/test/SemaHLSL/BuiltIns/exp-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/exp-errors.hlsl @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected -DTEST_FUNC=__builtin_elementwise_exp -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected -DTEST_FUNC=__builtin_elementwise_exp2 +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -verify-ignore-unexpected -DTEST_FUNC=__builtin_elementwise_exp +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -verify-ignore-unexpected -DTEST_FUNC=__builtin_elementwise_exp2 float test_too_few_arg() { return TEST_FUNC(); // expected-error@-1 {{too few arguments to function call, expected 1, have 0}} diff --git a/clang/test/SemaHLSL/BuiltIns/frac-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/frac-errors.hlsl index f82b5942fd46b6112f153e7538dd4d9cd362b7d6..f3cfbcf29d69c2b9bac4bd68d901c6202ae48b77 100644 --- a/clang/test/SemaHLSL/BuiltIns/frac-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/frac-errors.hlsl @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -verify-ignore-unexpected float test_too_few_arg() { return __builtin_hlsl_elementwise_frac(); diff --git a/clang/test/SemaHLSL/BuiltIns/half-float-only-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/half-float-only-errors.hlsl index 98c02c38675f4e13989e3fef87bf6168641abe68..ef0928f8fef0d6069595b40f44b610d01c5b9dc6 100644 --- a/clang/test/SemaHLSL/BuiltIns/half-float-only-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/half-float-only-errors.hlsl @@ -1,15 +1,15 @@ -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_ceil -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_cos -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_exp -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_exp2 -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_floor -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_log -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_log2 -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_log10 -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_sin -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_sqrt -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_roundeven -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_trunc +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_ceil +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_cos +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_exp +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_exp2 +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_floor +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_log +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_log2 +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_log10 +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_sin +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_sqrt +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_roundeven +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_trunc double2 test_double_builtin(double2 p0) { return TEST_FUNC(p0); diff --git a/clang/test/SemaHLSL/BuiltIns/isinf-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/isinf-errors.hlsl index 7ddfd56638273bdf0aecf1fef9dd5bf4cd4ab036..e2f03812705fd51ffe5bad94866647487b02c964 100644 --- a/clang/test/SemaHLSL/BuiltIns/isinf-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/isinf-errors.hlsl @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -verify-ignore-unexpected bool test_too_few_arg() { return __builtin_hlsl_elementwise_isinf(); diff --git a/clang/test/SemaHLSL/BuiltIns/lerp-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/lerp-errors.hlsl index 83751f68357edf36c3135107353c07061fd8fede..d23357239b7e8ab500ae78e8444ad02a2b555d5c 100644 --- a/clang/test/SemaHLSL/BuiltIns/lerp-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/lerp-errors.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -verify-ignore-unexpected float2 test_no_second_arg(float2 p0) { return __builtin_hlsl_lerp(p0); diff --git a/clang/test/SemaHLSL/BuiltIns/mad-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/mad-errors.hlsl index 97ce931bf1b5b591de99c91609829462e8a27ea2..636910b7ac8abc3381639114ecd0738eec3b08d6 100644 --- a/clang/test/SemaHLSL/BuiltIns/mad-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/mad-errors.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -verify-ignore-unexpected float2 test_no_second_arg(float2 p0) { return __builtin_hlsl_mad(p0); diff --git a/clang/test/SemaHLSL/BuiltIns/pow-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/pow-errors.hlsl index 949028aacf24b610c7932f75f8a544190395d9f0..5a2c9a3ef62ff56fcb39b9cb93cd9de2594b3316 100644 --- a/clang/test/SemaHLSL/BuiltIns/pow-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/pow-errors.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify double2 test_double_builtin(double2 p0, double2 p1) { return __builtin_elementwise_pow(p0,p1); diff --git a/clang/test/SemaHLSL/BuiltIns/rcp-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/rcp-errors.hlsl index fa6fd813f19e64e6b13b5eda1717385d101bce96..6bc5b9bed3047c575ca898895bf95e09ef1f3617 100644 --- a/clang/test/SemaHLSL/BuiltIns/rcp-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/rcp-errors.hlsl @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -verify-ignore-unexpected float test_too_few_arg() { return __builtin_hlsl_elementwise_rcp(); diff --git a/clang/test/SemaHLSL/BuiltIns/reversebits-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/reversebits-errors.hlsl index 6e66db6d1cca9e2f110980cbd88ba47d3d375e14..49cd895d98c52d242271d6b41a259b48f185eb4b 100644 --- a/clang/test/SemaHLSL/BuiltIns/reversebits-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/reversebits-errors.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify double2 test_int_builtin(double2 p0) { diff --git a/clang/test/SemaHLSL/BuiltIns/round-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/round-errors.hlsl index fed4573063acb531934b7fff6d17aab6f744bf38..bede89015298b689d3f18348369abccf234e0c8a 100644 --- a/clang/test/SemaHLSL/BuiltIns/round-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/round-errors.hlsl @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -verify-ignore-unexpected float test_too_few_arg() { return __builtin_elementwise_round(); diff --git a/clang/test/SemaHLSL/BuiltIns/rsqrt-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/rsqrt-errors.hlsl index c027a698c5e58fd576f19e0cc6604519110a9eca..e9a295172c7f8e3929793b610babfae559fe30a0 100644 --- a/clang/test/SemaHLSL/BuiltIns/rsqrt-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/rsqrt-errors.hlsl @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -verify-ignore-unexpected float test_too_few_arg() { return __builtin_hlsl_elementwise_rsqrt(); diff --git a/clang/test/SemaOpenACC/compute-construct-intexpr-clause-ast.cpp b/clang/test/SemaOpenACC/compute-construct-intexpr-clause-ast.cpp index 889025c26818d844e55fff15de6f6574a2fa4268..5a4c9f05ee089e56fce680dd0aff6d692a7967d3 100644 --- a/clang/test/SemaOpenACC/compute-construct-intexpr-clause-ast.cpp +++ b/clang/test/SemaOpenACC/compute-construct-intexpr-clause-ast.cpp @@ -88,6 +88,34 @@ void NormalUses() { // CHECK-NEXT: WhileStmt // CHECK-NEXT: CXXBoolLiteralExpr // CHECK-NEXT: CompoundStmt + +#pragma acc parallel num_gangs(some_int(), some_long(), some_short()) + while(true){} + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}parallel + // CHECK-NEXT: num_gangs clause + // CHECK-NEXT: CallExpr{{.*}}'int' + // CHECK-NEXT: ImplicitCastExpr{{.*}}'int (*)()' + // CHECK-NEXT: DeclRefExpr{{.*}}'int ()' lvalue Function{{.*}} 'some_int' 'int ()' + // CHECK-NEXT: CallExpr{{.*}}'long' + // CHECK-NEXT: ImplicitCastExpr{{.*}}'long (*)()' + // CHECK-NEXT: DeclRefExpr{{.*}}'long ()' lvalue Function{{.*}} 'some_long' 'long ()' + // CHECK-NEXT: CallExpr{{.*}}'short' + // CHECK-NEXT: ImplicitCastExpr{{.*}}'short (*)()' + // CHECK-NEXT: DeclRefExpr{{.*}}'short ()' lvalue Function{{.*}} 'some_short' 'short ()' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: CompoundStmt + +#pragma acc kernels num_gangs(some_int()) + while(true){} + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}kernels + // CHECK-NEXT: num_gangs clause + // CHECK-NEXT: CallExpr{{.*}}'int' + // CHECK-NEXT: ImplicitCastExpr{{.*}}'int (*)()' + // CHECK-NEXT: DeclRefExpr{{.*}}'int ()' lvalue Function{{.*}} 'some_int' 'int ()' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: CompoundStmt } template @@ -187,6 +215,31 @@ void TemplUses(T t, U u) { // CHECK-NEXT: CXXBoolLiteralExpr // CHECK-NEXT: CompoundStmt +#pragma acc kernels num_gangs(u) + while(true){} + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}kernels + // CHECK-NEXT: num_gangs clause + // CHECK-NEXT: DeclRefExpr{{.*}} 'U' lvalue ParmVar{{.*}} 'u' 'U' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: CompoundStmt + +#pragma acc parallel num_gangs(u, U::value) + while(true){} + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}parallel + // CHECK-NEXT: num_gangs clause + // CHECK-NEXT: DeclRefExpr{{.*}} 'U' lvalue ParmVar{{.*}} 'u' 'U' + // CHECK-NEXT: DependentScopeDeclRefExpr{{.*}} '' lvalue + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'U' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: CompoundStmt + + + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl{{.*}}EndMarker + int EndMarker; + // Check the instantiated versions of the above. // CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (CorrectConvert, HasInt)' implicit_instantiation // CHECK-NEXT: TemplateArgument type 'CorrectConvert' @@ -288,6 +341,32 @@ void TemplUses(T t, U u) { // CHECK-NEXT: WhileStmt // CHECK-NEXT: CXXBoolLiteralExpr // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}kernels + // CHECK-NEXT: num_gangs clause + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'char' + // CHECK-NEXT: CXXMemberCallExpr{{.*}}'char' + // CHECK-NEXT: MemberExpr{{.*}} '' .operator char + // CHECK-NEXT: DeclRefExpr{{.*}} 'HasInt' lvalue ParmVar + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}parallel + // CHECK-NEXT: num_gangs clause + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'char' + // CHECK-NEXT: CXXMemberCallExpr{{.*}}'char' + // CHECK-NEXT: MemberExpr{{.*}} '' .operator char + // CHECK-NEXT: DeclRefExpr{{.*}} 'HasInt' lvalue ParmVar + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}} 'const int' lvalue Var{{.*}} 'value' 'const int' + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'HasInt' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl{{.*}}EndMarker } struct HasInt { diff --git a/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.c b/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.c new file mode 100644 index 0000000000000000000000000000000000000000..cdc6847b47f9482c78174f624c447bb2e7f81ebc --- /dev/null +++ b/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.c @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +short getS(); +void Test() { +#pragma acc kernels num_gangs(1) + while(1); + + // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'serial' directive}} +#pragma acc serial num_gangs(1) + while(1); + +#pragma acc parallel num_gangs(1) + while(1); + + // expected-error@+2{{OpenACC 'num_gangs' clause cannot appear more than once on a 'kernels' directive}} + // expected-note@+1{{previous clause is here}} +#pragma acc kernels num_gangs(1) num_gangs(2) + while(1); + + // expected-error@+2{{OpenACC 'num_gangs' clause cannot appear more than once on a 'parallel' directive}} + // expected-note@+1{{previous clause is here}} +#pragma acc parallel num_gangs(1) num_gangs(2) + while(1); + + // expected-error@+1{{too many integer expression arguments provided to OpenACC 'num_gangs' clause: 'kernels' directive expects maximum of 1, 2 were provided}} +#pragma acc kernels num_gangs(1, getS()) + while(1); + + // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'serial' directive}} +#pragma acc serial num_gangs(1, getS()) + while(1); +#pragma acc parallel num_gangs(1, getS()) + while(1); + + struct NotConvertible{} NC; + // expected-error@+1{{OpenACC clause 'num_gangs' requires expression of integer type ('struct NotConvertible' invalid)}} +#pragma acc parallel num_gangs(NC) + while(1); + + // expected-error@+1{{OpenACC clause 'num_gangs' requires expression of integer type ('struct NotConvertible' invalid)}} +#pragma acc parallel num_gangs(1, NC) + while(1); + + // expected-error@+1{{OpenACC clause 'num_gangs' requires expression of integer type ('struct NotConvertible' invalid)}} +#pragma acc parallel num_gangs(NC, 1) + while(1); + +#pragma acc parallel num_gangs(getS(), 1, getS()) + while(1); + + // expected-error@+1{{too many integer expression arguments provided to OpenACC 'num_gangs' clause: 'parallel' directive expects maximum of 3, 4 were provided}} +#pragma acc parallel num_gangs(getS(), 1, getS(), 1) + while(1); +} diff --git a/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.cpp b/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ec3df87a065572f71518fccb8384eb3e36043240 --- /dev/null +++ b/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.cpp @@ -0,0 +1,160 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +struct NotConvertible{} NC; +struct Incomplete *SomeIncomplete; // #INCOMPLETE +enum E{} SomeE; +enum class E2{} SomeE2; + +struct CorrectConvert { + operator int(); +} Convert; + +struct ExplicitConvertOnly { + explicit operator int() const; // #EXPL_CONV +} Explicit; + +struct AmbiguousConvert{ + operator int(); // #AMBIG_INT + operator short(); // #AMBIG_SHORT + operator float(); +} Ambiguous; + +short some_short(); +int some_int(); +long some_long(); + +void Test() { +#pragma acc kernels num_gangs(1) + while(1); + + // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'serial' directive}} +#pragma acc serial num_gangs(1) + while(1); + +#pragma acc parallel num_gangs(1) + while(1); + + // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'serial' directive}} +#pragma acc serial num_gangs(some_short(), some_int(), some_long()) + while(1); + +#pragma acc parallel num_gangs(some_short(), some_int(), some_long()) + while(1); + + // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'serial' directive}} +#pragma acc serial num_gangs(some_short(), some_int(), some_long(), SomeE) + while(1); + + // expected-error@+1{{too many integer expression arguments provided to OpenACC 'num_gangs' clause: 'parallel' directive expects maximum of 3, 4 were provided}} +#pragma acc parallel num_gangs(some_short(), some_int(), some_long(), SomeE) + while(1); + + // expected-error@+1{{too many integer expression arguments provided to OpenACC 'num_gangs' clause: 'kernels' directive expects maximum of 1, 2 were provided}} +#pragma acc kernels num_gangs(1, 2) + while(1); + + // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'serial' directive}} +#pragma acc serial num_gangs(1, 2) + while(1); + +#pragma acc parallel num_gangs(1, 2) + while(1); + + // expected-error@+3{{multiple conversions from expression type 'struct AmbiguousConvert' to an integral type}} + // expected-note@#AMBIG_INT{{conversion to integral type 'int'}} + // expected-note@#AMBIG_SHORT{{conversion to integral type 'short'}} +#pragma acc parallel num_gangs(Ambiguous) + while(1); + + // expected-error@+1{{OpenACC clause 'num_gangs' requires expression of integer type ('struct NotConvertible' invalid)}} +#pragma acc parallel num_gangs(NC, SomeE) + while(1); + + // expected-error@+1{{OpenACC clause 'num_gangs' requires expression of integer type ('struct NotConvertible' invalid)}} +#pragma acc parallel num_gangs(SomeE, NC) + while(1); + + // expected-error@+3{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} + // expected-error@+1{{OpenACC clause 'num_gangs' requires expression of integer type ('struct NotConvertible' invalid)}} +#pragma acc parallel num_gangs(Explicit, NC) + while(1); + + // expected-error@+4{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} + // expected-error@+2{{OpenACC clause 'num_gangs' requires expression of integer type ('struct NotConvertible' invalid)}} + // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'serial' directive}} +#pragma acc serial num_gangs(Explicit, NC) + while(1); + + // expected-error@+6{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} + // expected-error@+4{{OpenACC clause 'num_gangs' requires expression of integer type ('struct NotConvertible' invalid)}} + // expected-error@+3{{multiple conversions from expression type 'struct AmbiguousConvert' to an integral type}} + // expected-note@#AMBIG_INT{{conversion to integral type 'int'}} + // expected-note@#AMBIG_SHORT{{conversion to integral type 'short'}} +#pragma acc parallel num_gangs(Explicit, NC, Ambiguous) + while(1); + + // expected-error@+7{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} + // expected-error@+5{{OpenACC clause 'num_gangs' requires expression of integer type ('struct NotConvertible' invalid)}} + // expected-error@+4{{multiple conversions from expression type 'struct AmbiguousConvert' to an integral type}} + // expected-note@#AMBIG_INT{{conversion to integral type 'int'}} + // expected-note@#AMBIG_SHORT{{conversion to integral type 'short'}} + // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'serial' directive}} +#pragma acc serial num_gangs(Explicit, NC, Ambiguous) + while(1); + // TODO +} + +struct HasInt { + using IntTy = int; + using ShortTy = short; + static constexpr int value = 1; + static constexpr AmbiguousConvert ACValue; + static constexpr ExplicitConvertOnly EXValue; + + operator char(); +}; + +template +void TestInst() { + // expected-error@+2{{no member named 'Invalid' in 'HasInt'}} + // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'serial' directive}} +#pragma acc serial num_gangs(HasInt::Invalid) + while(1); + + // expected-error@+2{{no member named 'Invalid' in 'HasInt'}} + // expected-note@#INST{{in instantiation of function template specialization}} +#pragma acc parallel num_gangs(T::Invalid) + while(1); + + // expected-error@+1{{no member named 'Invalid' in 'HasInt'}} +#pragma acc parallel num_gangs(1, HasInt::Invalid) + while(1); + + // expected-error@+1{{no member named 'Invalid' in 'HasInt'}} +#pragma acc parallel num_gangs(T::Invalid, 1) + while(1); + + // expected-error@+2{{no member named 'Invalid' in 'HasInt'}} + // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'serial' directive}} +#pragma acc serial num_gangs(1, HasInt::Invalid) + while(1); + + // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'serial' directive}} +#pragma acc serial num_gangs(T::Invalid, 1) + while(1); + +#pragma acc parallel num_gangs(T::value, typename T::IntTy{}) + while(1); + + // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'serial' directive}} +#pragma acc serial num_gangs(T::value, typename T::IntTy{}) + while(1); +} + +void Inst() { + TestInst(); // #INST +} diff --git a/clang/test/SemaTemplate/deduction-guide.cpp b/clang/test/SemaTemplate/deduction-guide.cpp index 58f08aa1eed65029489f2f8a5c05b1f5e6350c84..ff5e39216762faf291206242cc8467b1a43b3404 100644 --- a/clang/test/SemaTemplate/deduction-guide.cpp +++ b/clang/test/SemaTemplate/deduction-guide.cpp @@ -260,3 +260,31 @@ AG ag = {1}; // CHECK: |-TemplateArgument type 'int' // CHECK: | `-BuiltinType {{.*}} 'int' // CHECK: `-ParmVarDecl {{.*}} 'int' + +template +requires (sizeof(D) == 4) +struct Foo { + Foo(D); +}; + +template +using AFoo = Foo>; +// Verify that the require-clause from the Foo deduction guide is transformed. +// The D occurrence should be rewritten to G. +// +// CHECK-LABEL: Dumping +// CHECK: FunctionTemplateDecl {{.*}} implicit +// CHECK-NEXT: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 0 U +// CHECK-NEXT: |-ParenExpr {{.*}} 'bool' +// CHECK-NEXT: | `-BinaryOperator {{.*}} 'bool' '==' +// CHECK-NEXT: | |-UnaryExprOrTypeTraitExpr {{.*}} 'G' +// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} +// CHECK-NEXT: | `-IntegerLiteral {{.*}} +// CHECK-NEXT: |-CXXDeductionGuideDecl {{.*}} implicit 'auto (G) -> Foo>' +// CHECK-NEXT: | `-ParmVarDecl {{.*}} 'G' +// CHECK-NEXT: `-CXXDeductionGuideDecl {{.*}} implicit used 'auto (G) -> Foo>' implicit_instantiation +// CHECK-NEXT: |-TemplateArgument type 'int' +// CHECK-NEXT: | `-BuiltinType {{.*}} 'int' +// CHECK-NEXT: `-ParmVarDecl {{.*}} 'G' + +AFoo aa(G{}); diff --git a/clang/test/SemaTemplate/instantiate-using-decl.cpp b/clang/test/SemaTemplate/instantiate-using-decl.cpp index 0bbb3ca9c88c8b5e1898a768ef57913edf6fb1df..28d83764385131d02ab735b9a447da77724ba76a 100644 --- a/clang/test/SemaTemplate/instantiate-using-decl.cpp +++ b/clang/test/SemaTemplate/instantiate-using-decl.cpp @@ -121,7 +121,7 @@ template struct Derived : Base { (void)&field; // expected-error@+1 {{call to non-static member function without an object argument}} (void)method; - // expected-error@+1 {{call to non-static member function without an object argument}} + // expected-error@+1 {{must explicitly qualify name of member function when taking its address}} (void)&method; // expected-error@+1 {{call to non-static member function without an object argument}} method(); diff --git a/clang/test/SemaTemplate/ms-function-specialization-class-scope.cpp b/clang/test/SemaTemplate/ms-function-specialization-class-scope.cpp index dcab9bfaeabcb080e55111f289b6d3655cd64c2a..c49d2cb2422fabf776a1dbbb7807630a9c00b47f 100644 --- a/clang/test/SemaTemplate/ms-function-specialization-class-scope.cpp +++ b/clang/test/SemaTemplate/ms-function-specialization-class-scope.cpp @@ -1,7 +1,6 @@ -// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s -// RUN: %clang_cc1 -fms-extensions -fdelayed-template-parsing -fsyntax-only -verify %s +// RUN: %clang_cc1 -fms-extensions -fsyntax-only -Wno-unused-value -verify %s +// RUN: %clang_cc1 -fms-extensions -fdelayed-template-parsing -fsyntax-only -Wno-unused-value -verify %s -// expected-no-diagnostics class A { public: template A(U p) {} @@ -76,3 +75,453 @@ struct S { int f<0>(int); }; } + +namespace UsesThis { + template + struct A { + int x; + + static inline int y; + + template + static void f(); + + template + void g(); + + template + static auto h() -> A*; + + void i(); + + static void j(); + + template<> + void f() { + this->x; // expected-error {{invalid use of 'this' outside of a non-static member function}} + x; // expected-error {{invalid use of member 'x' in static member function}} + A::x; // expected-error {{invalid use of member 'x' in static member function}} + +x; // expected-error {{invalid use of member 'x' in static member function}} + +A::x; // expected-error {{invalid use of member 'x' in static member function}} + &x; // expected-error {{invalid use of member 'x' in static member function}} + &A::x; + this->y; // expected-error {{invalid use of 'this' outside of a non-static member function}} + y; + A::y; + +y; + +A::y; + &y; + &A::y; + f(); + f(); + g(); // expected-error {{call to non-static member function without an object argument}} + g(); // expected-error {{call to non-static member function without an object argument}} + i(); // expected-error {{call to non-static member function without an object argument}} + j(); + &i; // expected-error 2{{must explicitly qualify name of member function when taking its address}} + &j; + &A::i; + &A::j; + } + + template<> + void g() { + this->x; + x; + A::x; + +x; + +A::x; + &x; + &A::x; + this->y; + y; + A::y; + +y; + +A::y; + &y; + &A::y; + f(); + f(); + g(); + g(); + i(); + j(); + &i; // expected-error 2{{must explicitly qualify name of member function when taking its address}} + &j; + &A::i; + &A::j; + } + + template<> + auto h() -> decltype(this); // expected-error {{'this' cannot be used in a static member function declaration}} + }; + + template struct A; // expected-note 3{{in instantiation of}} + + template + struct Foo { + template + int bar(X x) { + return 0; + } + + template <> + int bar(int x) { + return bar(5.0); // ok + } + }; + + void call() { + Foo f; + f.bar(1); + } + + struct B { + int x0; + static inline int y0; + + int f0(int); + static int g0(int); + + int x2; + static inline int y2; + + int f2(int); + static int g2(int); + }; + + template + struct D : B { + int x1; + static inline int y1; + + int f1(int); + static int g1(int); + + using B::x2; + using B::y2; + using B::f2; + using B::g2; + + template + void non_static_spec(U); + + template + static void static_spec(U); + + template<> + void non_static_spec(int z) { + ++z; + ++x0; + ++x1; + ++x2; + ++y0; + ++y1; + ++y2; + + &z; + &x0; + &x1; + &x2; + &y0; + &y1; + &y2; + + &f0; // expected-error {{must explicitly qualify name of member function when taking its address}} + &f1; // expected-error 2{{must explicitly qualify name of member function when taking its address}} + &f2; // expected-error 2{{must explicitly qualify name of member function when taking its address}} + &g0; + &g1; + &g2; + + &B::x0; + &D::x1; + &B::x2; + &B::y0; + &D::y1; + &B::y2; + &B::f0; + &D::f1; + &B::f2; + &B::g0; + &D::g1; + &B::g2; + + f0(0); + f0(z); + f0(x0); + f0(x1); + f0(x2); + f0(y0); + f0(y1); + f0(y2); + g0(0); + g0(z); + g0(x0); + g0(x1); + g0(x2); + g0(y0); + g0(y1); + g0(y2); + + f1(0); + f1(z); + f1(x0); + f1(x1); + f1(x2); + f1(y0); + f1(y1); + f1(y2); + g1(0); + g1(z); + g1(x0); + g1(x1); + g1(x2); + g1(y0); + g1(y1); + g1(y2); + + f2(0); + f2(z); + f2(x0); + f2(x1); + f2(x2); + f2(y0); + f2(y1); + f2(y2); + g2(0); + g2(z); + g2(x0); + g2(x1); + g2(x2); + g2(y0); + g2(y1); + g2(y2); + } + + template<> + void static_spec(int z) { + ++z; + ++x0; // expected-error {{invalid use of member 'x0' in static member function}} + ++x1; // expected-error {{invalid use of member 'x1' in static member function}} + ++x2; // expected-error {{invalid use of member 'x2' in static member function}} + ++y0; + ++y1; + ++y2; + + &z; + &x0; // expected-error {{invalid use of member 'x0' in static member function}} + &x1; // expected-error {{invalid use of member 'x1' in static member function}} + &x2; // expected-error {{invalid use of member 'x2' in static member function}} + &y0; + &y1; + &y2; + + &f0; // expected-error {{must explicitly qualify name of member function when taking its address}} + &f1; // expected-error 2{{must explicitly qualify name of member function when taking its address}} + &f2; // expected-error 2{{must explicitly qualify name of member function when taking its address}} + &g0; + &g1; + &g2; + + &B::x0; + &D::x1; + &B::x2; + &B::y0; + &D::y1; + &B::y2; + &B::f0; + &D::f1; + &B::f2; + &B::g0; + &D::g1; + &B::g2; + + f0(0); // expected-error {{call to non-static member function without an object argument}} + f0(z); // expected-error {{call to non-static member function without an object argument}} + f0(x0); // expected-error {{call to non-static member function without an object argument}} + f0(x1); // expected-error {{call to non-static member function without an object argument}} + f0(x2); // expected-error {{call to non-static member function without an object argument}} + f0(y0); // expected-error {{call to non-static member function without an object argument}} + f0(y1); // expected-error {{call to non-static member function without an object argument}} + f0(y2); // expected-error {{call to non-static member function without an object argument}} + g0(0); + g0(z); + g0(x0); // expected-error {{invalid use of member 'x0' in static member function}} + g0(x1); // expected-error {{invalid use of member 'x1' in static member function}} + g0(x2); // expected-error {{invalid use of member 'x2' in static member function}} + g0(y0); + g0(y1); + g0(y2); + + f1(0); // expected-error {{call to non-static member function without an object argument}} + f1(z); // expected-error {{call to non-static member function without an object argument}} + f1(x0); // expected-error {{call to non-static member function without an object argument}} + f1(x1); // expected-error {{call to non-static member function without an object argument}} + f1(x2); // expected-error {{call to non-static member function without an object argument}} + f1(y0); // expected-error {{call to non-static member function without an object argument}} + f1(y1); // expected-error {{call to non-static member function without an object argument}} + f1(y2); // expected-error {{call to non-static member function without an object argument}} + g1(0); + g1(z); + g1(x0); // expected-error {{invalid use of member 'x0' in static member function}} + g1(x1); // expected-error {{invalid use of member 'x1' in static member function}} + g1(x2); // expected-error {{invalid use of member 'x2' in static member function}} + g1(y0); + g1(y1); + g1(y2); + + f2(0); // expected-error {{call to non-static member function without an object argument}} + f2(z); // expected-error {{call to non-static member function without an object argument}} + f2(x0); // expected-error {{call to non-static member function without an object argument}} + f2(x1); // expected-error {{call to non-static member function without an object argument}} + f2(x2); // expected-error {{call to non-static member function without an object argument}} + f2(y0); // expected-error {{call to non-static member function without an object argument}} + f2(y1); // expected-error {{call to non-static member function without an object argument}} + f2(y2); // expected-error {{call to non-static member function without an object argument}} + g2(0); + g2(z); + g2(x0); // expected-error {{invalid use of member 'x0' in static member function}} + g2(x1); // expected-error {{invalid use of member 'x1' in static member function}} + g2(x2); // expected-error {{invalid use of member 'x2' in static member function}} + g2(y0); + g2(y1); + g2(y2); + } + }; + + template struct D; // expected-note 2{{in instantiation of}} + + template + struct E : T { + int x1; + static inline int y1; + + int f1(int); + static int g1(int); + + using T::x0; + using T::y0; + using T::f0; + using T::g0; + + template + void non_static_spec(U); + + template + static void static_spec(U); + + template<> + void non_static_spec(int z) { + ++z; + ++x0; + ++x1; + ++y0; + ++y1; + + &z; + &x0; + &x1; + &y0; + &y1; + + &f0; // expected-error {{must explicitly qualify name of member function when taking its address}} + &f1; // expected-error 2{{must explicitly qualify name of member function when taking its address}} + &g0; + &g1; + + &T::x0; + &E::x1; + &T::y0; + &E::y1; + &T::f0; + &E::f1; + &T::g0; + &E::g1; + + f0(0); + f0(z); + f0(x0); + f0(x1); + f0(y0); + f0(y1); + g0(0); + g0(z); + g0(x0); + g0(x1); + g0(y0); + g0(y1); + + f1(0); + f1(z); + f1(x0); + f1(x1); + f1(y0); + f1(y1); + g1(0); + g1(z); + g1(x0); + g1(x1); + g1(y0); + g1(y1); + } + + template<> + void static_spec(int z) { + ++z; + ++x0; // expected-error {{invalid use of member 'x0' in static member function}} + ++x1; // expected-error {{invalid use of member 'x1' in static member function}} + ++y0; + ++y1; + + &z; + &x0; // expected-error {{invalid use of member 'x0' in static member function}} + &x1; // expected-error {{invalid use of member 'x1' in static member function}} + &y0; + &y1; + + &f0; // expected-error {{must explicitly qualify name of member function when taking its address}} + &f1; // expected-error 2{{must explicitly qualify name of member function when taking its address}} + &g0; + &g1; + + &T::x0; + &E::x1; + &T::y0; + &E::y1; + &T::f0; + &E::f1; + &T::g0; + &E::g1; + + f0(0); // expected-error {{call to non-static member function without an object argument}} + f0(z); // expected-error {{call to non-static member function without an object argument}} + f0(x0); // expected-error {{call to non-static member function without an object argument}} + f0(x1); // expected-error {{call to non-static member function without an object argument}} + f0(y0); // expected-error {{call to non-static member function without an object argument}} + f0(y1); // expected-error {{call to non-static member function without an object argument}} + g0(0); + g0(z); + g0(x0); // expected-error {{invalid use of member 'x0' in static member function}} + g0(x1); // expected-error {{invalid use of member 'x1' in static member function}} + g0(y0); + g0(y1); + + f1(0); // expected-error {{call to non-static member function without an object argument}} + f1(z); // expected-error {{call to non-static member function without an object argument}} + f1(x0); // expected-error {{call to non-static member function without an object argument}} + f1(x1); // expected-error {{call to non-static member function without an object argument}} + f1(y0); // expected-error {{call to non-static member function without an object argument}} + f1(y1); // expected-error {{call to non-static member function without an object argument}} + g1(0); + g1(z); + g1(x0); // expected-error {{invalid use of member 'x0' in static member function}} + g1(x1); // expected-error {{invalid use of member 'x1' in static member function}} + g1(y0); + g1(y1); + } + }; + + template struct E; // expected-note 2{{in instantiation of}} + +} diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index cbc1d85bb33dfc39048a04a57095c4b96b53f103..74163f30e19b1dca7fae73c145b5bef39cccada5 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -2803,6 +2803,10 @@ void OpenACCClauseEnqueue::VisitVectorLengthClause( const OpenACCVectorLengthClause &C) { Visitor.AddStmt(C.getIntExpr()); } +void OpenACCClauseEnqueue::VisitNumGangsClause(const OpenACCNumGangsClause &C) { + for (Expr *IE : C.getIntExprs()) + Visitor.AddStmt(IE); +} } // namespace void EnqueueVisitor::EnqueueChildren(const OpenACCClause *C) { diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index acc596fef87b7600f630c4c97184ffe9c4b7e119..4ee64de697d37ad9d16c851e9c7a31b4fb500a37 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -6721,6 +6721,23 @@ TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionBody) { EXPECT_FALSE(FromL->isDependentLambda()); } +TEST_P(ASTImporterOptionSpecificTestBase, + ReturnTypeDeclaredInsideOfCXX11LambdaWithoutTrailingReturn) { + Decl *From, *To; + std::tie(From, To) = getImportedDecl( + R"( + void foo() { + (void) []() { + struct X {}; + return X(); + }; + } + )", + Lang_CXX11, "", Lang_CXX11, "foo"); // c++11 only + auto *ToLambda = FirstDeclMatcher().match(To, lambdaExpr()); + EXPECT_TRUE(ToLambda); +} + TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) { Decl *FromTU = getTuDecl( R"( diff --git a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp b/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp index cc20623f881ff450208b821353060e9c7229ec30..4195648161246c71551ad45601d1f96e49faa9af 100644 --- a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp @@ -150,56 +150,6 @@ TEST_F(EnvironmentTest, CreateValueRecursiveType) { EXPECT_THAT(PV, NotNull()); } -TEST_F(EnvironmentTest, JoinRecords) { - using namespace ast_matchers; - - std::string Code = R"cc( - struct S {}; - // Need to use the type somewhere so that the `QualType` gets created; - S s; - )cc"; - - auto Unit = - tooling::buildASTFromCodeWithArgs(Code, {"-fsyntax-only", "-std=c++11"}); - auto &Context = Unit->getASTContext(); - - ASSERT_EQ(Context.getDiagnostics().getClient()->getNumErrors(), 0U); - - auto Results = - match(qualType(hasDeclaration(recordDecl(hasName("S")))).bind("SType"), - Context); - const QualType *TyPtr = selectFirst("SType", Results); - ASSERT_THAT(TyPtr, NotNull()); - QualType Ty = *TyPtr; - ASSERT_FALSE(Ty.isNull()); - - auto *ConstructExpr = CXXConstructExpr::CreateEmpty(Context, 0); - ConstructExpr->setType(Ty); - ConstructExpr->setValueKind(VK_PRValue); - - // Two different `RecordValue`s with the same location are joined into a - // third `RecordValue` with that same location. - { - Environment Env1(DAContext); - auto &Val1 = *cast(Env1.createValue(Ty)); - RecordStorageLocation &Loc = Val1.getLoc(); - Env1.setValue(Loc, Val1); - - Environment Env2(DAContext); - auto &Val2 = Env2.create(Loc); - Env2.setValue(Loc, Val2); - Env2.setValue(Loc, Val2); - - Environment::ValueModel Model; - Environment EnvJoined = - Environment::join(Env1, Env2, Model, Environment::DiscardExprState); - auto *JoinedVal = cast(EnvJoined.getValue(Loc)); - EXPECT_NE(JoinedVal, &Val1); - EXPECT_NE(JoinedVal, &Val2); - EXPECT_EQ(&JoinedVal->getLoc(), &Loc); - } -} - TEST_F(EnvironmentTest, DifferentReferenceLocInJoin) { // This tests the case where the storage location for a reference-type // variable is different for two states being joined. We used to believe this @@ -453,35 +403,4 @@ TEST_F(EnvironmentTest, Contains(Member)); } -TEST_F(EnvironmentTest, RefreshRecordValue) { - using namespace ast_matchers; - - std::string Code = R"cc( - struct S {}; - void target () { - S s; - s; - } - )cc"; - - auto Unit = - tooling::buildASTFromCodeWithArgs(Code, {"-fsyntax-only", "-std=c++11"}); - auto &Context = Unit->getASTContext(); - - ASSERT_EQ(Context.getDiagnostics().getClient()->getNumErrors(), 0U); - - auto Results = match(functionDecl(hasName("target")).bind("target"), Context); - const auto *Target = selectFirst("target", Results); - ASSERT_THAT(Target, NotNull()); - - Results = match(declRefExpr(to(varDecl(hasName("s")))).bind("s"), Context); - const auto *DRE = selectFirst("s", Results); - ASSERT_THAT(DRE, NotNull()); - - Environment Env(DAContext, *Target); - EXPECT_THAT(Env.getStorageLocation(*DRE), IsNull()); - refreshRecordValue(*DRE, Env); - EXPECT_THAT(Env.getStorageLocation(*DRE), NotNull()); -} - } // namespace diff --git a/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp b/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp index 55baa4e2a537757bbef087cf515553e8c4409af5..88b92668c850c6129b67ecd8020f5afd4eea7fba 100644 --- a/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp @@ -85,10 +85,6 @@ TEST(RecordOpsTest, CopyRecord) { EXPECT_NE(Env.getValue(S1.getSyntheticField("synth_int")), Env.getValue(S2.getSyntheticField("synth_int"))); - auto *S1Val = cast(Env.getValue(S1)); - auto *S2Val = cast(Env.getValue(S2)); - EXPECT_NE(S1Val, S2Val); - copyRecord(S1, S2, Env); EXPECT_EQ(getFieldValue(&S1, *OuterIntDecl, Env), @@ -98,10 +94,6 @@ TEST(RecordOpsTest, CopyRecord) { getFieldValue(&Inner2, *InnerIntDecl, Env)); EXPECT_EQ(Env.getValue(S1.getSyntheticField("synth_int")), Env.getValue(S2.getSyntheticField("synth_int"))); - - S1Val = cast(Env.getValue(S1)); - S2Val = cast(Env.getValue(S2)); - EXPECT_NE(S1Val, S2Val); }); } diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index 97ec32126c1dc4c0d99cd147e85be54b39b3e795..bb16138126c8f973ad1b184b6b0b7ff617f9d5ff 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -260,9 +260,6 @@ TEST(TransferTest, StructIncomplete) { ASSERT_THAT(FooValue, NotNull()); EXPECT_TRUE(isa(FooValue->getPointeeLoc())); - auto *FooPointeeValue = Env.getValue(FooValue->getPointeeLoc()); - ASSERT_THAT(FooPointeeValue, NotNull()); - EXPECT_TRUE(isa(FooPointeeValue)); }); } @@ -311,9 +308,10 @@ TEST(TransferTest, StructFieldUnmodeled) { const auto *FooLoc = cast(Env.getStorageLocation(*FooDecl)); - const auto *UnmodeledLoc = FooLoc->getChild(*UnmodeledDecl); - ASSERT_TRUE(isa(UnmodeledLoc)); - EXPECT_THAT(Env.getValue(*UnmodeledLoc), IsNull()); + const auto &UnmodeledLoc = + *cast(FooLoc->getChild(*UnmodeledDecl)); + StorageLocation &UnmodeledXLoc = getFieldLoc(UnmodeledLoc, "X", ASTCtx); + EXPECT_EQ(Env.getValue(UnmodeledXLoc), nullptr); const ValueDecl *ZabDecl = findValueDecl(ASTCtx, "Zab"); ASSERT_THAT(ZabDecl, NotNull()); @@ -492,9 +490,6 @@ TEST(TransferTest, ReferenceVarDecl) { const StorageLocation *FooLoc = Env.getStorageLocation(*FooDecl); ASSERT_TRUE(isa_and_nonnull(FooLoc)); - - const Value *FooReferentVal = Env.getValue(*FooLoc); - EXPECT_TRUE(isa_and_nonnull(FooReferentVal)); }); } @@ -585,22 +580,21 @@ TEST(TransferTest, SelfReferentialReferenceVarDecl) { const auto &FooReferentLoc = *cast(BarLoc.getChild(*FooRefDecl)); - EXPECT_THAT(Env.getValue(FooReferentLoc), NotNull()); - EXPECT_THAT(getFieldValue(&FooReferentLoc, *BarDecl, Env), IsNull()); + EXPECT_EQ(Env.getValue(*cast( + FooReferentLoc.getChild(*BarDecl)) + ->getChild(*FooPtrDecl)), + nullptr); const auto &FooPtrVal = *cast(getFieldValue(&BarLoc, *FooPtrDecl, Env)); const auto &FooPtrPointeeLoc = cast(FooPtrVal.getPointeeLoc()); - EXPECT_THAT(Env.getValue(FooPtrPointeeLoc), NotNull()); - EXPECT_THAT(getFieldValue(&FooPtrPointeeLoc, *BarDecl, Env), IsNull()); - - EXPECT_THAT(getFieldValue(&BarLoc, *BazRefDecl, Env), NotNull()); + EXPECT_EQ(Env.getValue(*cast( + FooPtrPointeeLoc.getChild(*BarDecl)) + ->getChild(*FooPtrDecl)), + nullptr); - const auto &BazPtrVal = - *cast(getFieldValue(&BarLoc, *BazPtrDecl, Env)); - const StorageLocation &BazPtrPointeeLoc = BazPtrVal.getPointeeLoc(); - EXPECT_THAT(Env.getValue(BazPtrPointeeLoc), NotNull()); + EXPECT_TRUE(isa(getFieldValue(&BarLoc, *BazPtrDecl, Env))); }); } @@ -631,9 +625,6 @@ TEST(TransferTest, PointerVarDecl) { const PointerValue *FooVal = cast(Env.getValue(*FooLoc)); const StorageLocation &FooPointeeLoc = FooVal->getPointeeLoc(); EXPECT_TRUE(isa(&FooPointeeLoc)); - - const Value *FooPointeeVal = Env.getValue(FooPointeeLoc); - EXPECT_TRUE(isa_and_nonnull(FooPointeeVal)); }); } @@ -740,20 +731,14 @@ TEST(TransferTest, SelfReferentialPointerVarDecl) { const auto &BarPointeeLoc = cast(BarVal.getPointeeLoc()); - EXPECT_THAT(getFieldValue(&BarPointeeLoc, *FooRefDecl, Env), NotNull()); - const auto &FooPtrVal = *cast( getFieldValue(&BarPointeeLoc, *FooPtrDecl, Env)); const auto &FooPtrPointeeLoc = cast(FooPtrVal.getPointeeLoc()); - EXPECT_THAT(Env.getValue(FooPtrPointeeLoc), IsNull()); - - EXPECT_THAT(getFieldValue(&BarPointeeLoc, *BazRefDecl, Env), NotNull()); + EXPECT_EQ(Env.getValue(*FooPtrPointeeLoc.getChild(*BarDecl)), nullptr); - const auto &BazPtrVal = *cast( - getFieldValue(&BarPointeeLoc, *BazPtrDecl, Env)); - const StorageLocation &BazPtrPointeeLoc = BazPtrVal.getPointeeLoc(); - EXPECT_THAT(Env.getValue(BazPtrPointeeLoc), NotNull()); + EXPECT_TRUE( + isa(getFieldValue(&BarPointeeLoc, *BazPtrDecl, Env))); }); } @@ -1165,9 +1150,6 @@ TEST(TransferTest, ReferenceParamDecl) { const StorageLocation *FooLoc = Env.getStorageLocation(*FooDecl); ASSERT_TRUE(isa_and_nonnull(FooLoc)); - - const Value *FooReferentVal = Env.getValue(*FooLoc); - EXPECT_TRUE(isa_and_nonnull(FooReferentVal)); }); } @@ -1196,9 +1178,6 @@ TEST(TransferTest, PointerParamDecl) { const PointerValue *FooVal = cast(Env.getValue(*FooLoc)); const StorageLocation &FooPointeeLoc = FooVal->getPointeeLoc(); EXPECT_TRUE(isa(&FooPointeeLoc)); - - const Value *FooPointeeVal = Env.getValue(FooPointeeLoc); - EXPECT_TRUE(isa_and_nonnull(FooPointeeVal)); }); } @@ -1400,8 +1379,7 @@ static void derivedBaseMemberExpectations( const auto &FooLoc = *cast(Env.getStorageLocation(*FooDecl)); - const auto &FooVal = *cast(Env.getValue(FooLoc)); - EXPECT_EQ(&FooVal.getLoc(), &FooLoc); + EXPECT_NE(Env.getValue(*FooLoc.getChild(*BarDecl)), nullptr); } TEST(TransferTest, DerivedBaseMemberStructDefault) { @@ -1850,7 +1828,6 @@ TEST(TransferTest, StructThisMember) { const auto *QuxLoc = cast(ThisLoc->getChild(*QuxDecl)); - EXPECT_THAT(dyn_cast(Env.getValue(*QuxLoc)), NotNull()); const auto *BazVal = cast(getFieldValue(QuxLoc, *BazDecl, Env)); @@ -1921,7 +1898,6 @@ TEST(TransferTest, ClassThisMember) { const auto *QuxLoc = cast(ThisLoc->getChild(*QuxDecl)); - EXPECT_THAT(dyn_cast(Env.getValue(*QuxLoc)), NotNull()); const auto *BazVal = cast(getFieldValue(QuxLoc, *BazDecl, Env)); @@ -2297,10 +2273,6 @@ TEST(TransferTest, AssignmentOperator) { const auto *BarLoc2 = cast(Env2.getStorageLocation(*BarDecl)); - const auto *FooVal2 = cast(Env2.getValue(*FooLoc2)); - const auto *BarVal2 = cast(Env2.getValue(*BarLoc2)); - EXPECT_NE(FooVal2, BarVal2); - EXPECT_TRUE(recordsEqual(*FooLoc2, *BarLoc2, Env2)); const auto *FooBazVal2 = @@ -2652,12 +2624,7 @@ TEST(TransferTest, CopyConstructor) { const auto *BarLoc = cast(Env.getStorageLocation(*BarDecl)); - // `Foo` and `Bar` have different `RecordValue`s associated with them. - const auto *FooVal = cast(Env.getValue(*FooLoc)); - const auto *BarVal = cast(Env.getValue(*BarLoc)); - EXPECT_NE(FooVal, BarVal); - - // But the records compare equal. + // The records compare equal. EXPECT_TRUE(recordsEqual(*FooLoc, *BarLoc, Env)); // In particular, the value of `Baz` in both records is the same. @@ -2878,10 +2845,6 @@ TEST(TransferTest, MoveConstructor) { EXPECT_FALSE(recordsEqual(*FooLoc1, *BarLoc1, Env1)); - const auto *FooVal1 = cast(Env1.getValue(*FooLoc1)); - const auto *BarVal1 = cast(Env1.getValue(*BarLoc1)); - EXPECT_NE(FooVal1, BarVal1); - const auto *FooBazVal1 = cast(getFieldValue(FooLoc1, *BazDecl, Env1)); const auto *BarBazVal1 = @@ -2890,8 +2853,6 @@ TEST(TransferTest, MoveConstructor) { const auto *FooLoc2 = cast(Env2.getStorageLocation(*FooDecl)); - const auto *FooVal2 = cast(Env2.getValue(*FooLoc2)); - EXPECT_NE(FooVal2, BarVal1); EXPECT_TRUE(recordsEqual(*FooLoc2, Env2, *BarLoc1, Env1)); const auto *FooBazVal2 = @@ -3098,6 +3059,79 @@ TEST(TransferTest, ResultObjectLocationForCXXOperatorCallExpr) { }); } +TEST(TransferTest, ResultObjectLocationForInitListExpr) { + std::string Code = R"cc( + struct Inner {}; + + struct Outer { Inner I; }; + + void target() { + Outer O = { Inner() }; + // [[p]] + } + )cc"; + using ast_matchers::asString; + using ast_matchers::cxxConstructExpr; + using ast_matchers::hasType; + using ast_matchers::match; + using ast_matchers::selectFirst; + using ast_matchers::traverse; + runDataflow( + Code, + [](const llvm::StringMap> &Results, + ASTContext &ASTCtx) { + const Environment &Env = getEnvironmentAtAnnotation(Results, "p"); + + auto *Construct = selectFirst( + "construct", + match( + cxxConstructExpr(hasType(asString("Inner"))).bind("construct"), + ASTCtx)); + + EXPECT_EQ( + &Env.getResultObjectLocation(*Construct), + &getFieldLoc(getLocForDecl(ASTCtx, Env, "O"), + "I", ASTCtx)); + }); +} + +TEST(TransferTest, ResultObjectLocationForParenInitListExpr) { + std::string Code = R"cc( + struct Inner {}; + + struct Outer { Inner I; }; + + void target() { + Outer O((Inner())); + // [[p]] + } + )cc"; + using ast_matchers::asString; + using ast_matchers::cxxConstructExpr; + using ast_matchers::hasType; + using ast_matchers::match; + using ast_matchers::selectFirst; + using ast_matchers::traverse; + runDataflow( + Code, + [](const llvm::StringMap> &Results, + ASTContext &ASTCtx) { + const Environment &Env = getEnvironmentAtAnnotation(Results, "p"); + + auto *Construct = selectFirst( + "construct", + match( + cxxConstructExpr(hasType(asString("Inner"))).bind("construct"), + ASTCtx)); + + EXPECT_EQ( + &Env.getResultObjectLocation(*Construct), + &getFieldLoc(getLocForDecl(ASTCtx, Env, "O"), + "I", ASTCtx)); + }, + LangStandard::lang_cxx20); +} + // Check that the `std::strong_ordering` object returned by builtin `<=>` has a // correctly modeled result object location. TEST(TransferTest, ResultObjectLocationForBuiltinSpaceshipOperator) { @@ -3443,7 +3477,8 @@ TEST(TransferTest, NullToPointerCast) { const StorageLocation &BazPointeeLoc = BazVal->getPointeeLoc(); EXPECT_TRUE(isa(BazPointeeLoc)); - EXPECT_THAT(Env.getValue(BazPointeeLoc), IsNull()); + EXPECT_EQ(BazVal, &Env.fork().getOrCreateNullPointerValue( + BazPointeeLoc.getType())); const StorageLocation &NullPointeeLoc = NullVal->getPointeeLoc(); EXPECT_TRUE(isa(NullPointeeLoc)); @@ -3597,10 +3632,14 @@ TEST(TransferTest, CannotAnalyzeMethodOfClassTemplate) { TEST(TransferTest, VarDeclInitAssignConditionalOperator) { std::string Code = R"( - struct A {}; + struct A { + int i; + }; void target(A Foo, A Bar, bool Cond) { A Baz = Cond ? Foo : Bar; + // Make sure A::i is modeled. + Baz.i; /*[[p]]*/ } )"; @@ -3608,26 +3647,20 @@ TEST(TransferTest, VarDeclInitAssignConditionalOperator) { Code, [](const llvm::StringMap> &Results, ASTContext &ASTCtx) { - ASSERT_THAT(Results.keys(), UnorderedElementsAre("p")); const Environment &Env = getEnvironmentAtAnnotation(Results, "p"); - const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo"); - ASSERT_THAT(FooDecl, NotNull()); + auto *FooIVal = cast(getFieldValue( + &getLocForDecl(ASTCtx, Env, "Foo"), "i", + ASTCtx, Env)); + auto *BarIVal = cast(getFieldValue( + &getLocForDecl(ASTCtx, Env, "Bar"), "i", + ASTCtx, Env)); + auto *BazIVal = cast(getFieldValue( + &getLocForDecl(ASTCtx, Env, "Baz"), "i", + ASTCtx, Env)); - const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar"); - ASSERT_THAT(BarDecl, NotNull()); - - const ValueDecl *BazDecl = findValueDecl(ASTCtx, "Baz"); - ASSERT_THAT(BazDecl, NotNull()); - - const auto *FooVal = cast(Env.getValue(*FooDecl)); - const auto *BarVal = cast(Env.getValue(*BarDecl)); - - const auto *BazVal = dyn_cast(Env.getValue(*BazDecl)); - ASSERT_THAT(BazVal, NotNull()); - - EXPECT_NE(BazVal, FooVal); - EXPECT_NE(BazVal, BarVal); + EXPECT_NE(BazIVal, FooIVal); + EXPECT_NE(BazIVal, BarIVal); }); } @@ -3894,7 +3927,6 @@ TEST(TransferTest, AssignToUnionMember) { const auto *BazLoc = dyn_cast_or_null( Env.getStorageLocation(*BazDecl)); ASSERT_THAT(BazLoc, NotNull()); - ASSERT_THAT(Env.getValue(*BazLoc), NotNull()); const auto *FooVal = cast(getFieldValue(BazLoc, *FooDecl, Env)); @@ -5485,17 +5517,15 @@ TEST(TransferTest, ContextSensitiveReturnReferenceWithConditionalOperator) { ASSERT_THAT(SDecl, NotNull()); auto *SLoc = Env.getStorageLocation(*SDecl); - ASSERT_THAT(SLoc, NotNull()); - EXPECT_THAT(Env.getValue(*SLoc), NotNull()); + EXPECT_THAT(SLoc, NotNull()); auto *Loc = Env.getReturnStorageLocation(); - ASSERT_THAT(Loc, NotNull()); - EXPECT_THAT(Env.getValue(*Loc), NotNull()); + EXPECT_THAT(Loc, NotNull()); // TODO: We would really like to make this stronger assertion, but that // doesn't work because we don't propagate values correctly through // the conditional operator yet. - // ASSERT_THAT(Loc, Eq(SLoc)); + // EXPECT_EQ(Loc, SLoc); }, {BuiltinOptions{ContextSensitiveOptions{}}}); } @@ -6561,7 +6591,7 @@ TEST(TransferTest, NewExpressions_Structs) { void target() { Outer *p = new Outer; // Access the fields to make sure the analysis actually generates children - // for them in the `RecordStorageLocation` and `RecordValue`. + // for them in the `RecordStorageLocation`. p->OuterField.InnerField; // [[after_new]] } @@ -6583,9 +6613,6 @@ TEST(TransferTest, NewExpressions_Structs) { *cast(OuterLoc.getChild(*OuterField)); auto &InnerFieldLoc = *OuterFieldLoc.getChild(*InnerField); - // Values for the struct and all fields exist after the new. - EXPECT_THAT(Env.getValue(OuterLoc), NotNull()); - EXPECT_THAT(Env.getValue(OuterFieldLoc), NotNull()); EXPECT_THAT(Env.getValue(InnerFieldLoc), NotNull()); }); } diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 4f445c64ab303a2d050630307d58f9e86025d95c..34999b7376397b62c74f239f18da88544fa0308d 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -599,6 +599,12 @@ TEST_F(TokenAnnotatorTest, UnderstandsCasts) { ASSERT_EQ(Tokens.size(), 6u) << Tokens; EXPECT_TOKEN(Tokens[2], tok::r_paren, TT_CastRParen); + Tokens = annotate("(uint32_t)&&label;"); + ASSERT_EQ(Tokens.size(), 7u) << Tokens; + EXPECT_TOKEN(Tokens[2], tok::r_paren, TT_CastRParen); + EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_UnaryOperator); + EXPECT_TOKEN(Tokens[4], tok::identifier, TT_Unknown); + Tokens = annotate("auto x = (Foo)p;"); ASSERT_EQ(Tokens.size(), 9u) << Tokens; EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_CastRParen); diff --git a/clang/utils/TableGen/MveEmitter.cpp b/clang/utils/TableGen/MveEmitter.cpp index 88e7b6e8546595b9ff50ef777736c498a80907c1..c455071ed9da7ca92d07267b124ca03fff1f7bf9 100644 --- a/clang/utils/TableGen/MveEmitter.cpp +++ b/clang/utils/TableGen/MveEmitter.cpp @@ -658,9 +658,9 @@ public: std::vector Args; std::set AddressArgs; std::map IntegerArgs; - IRBuilderResult(StringRef CallPrefix, std::vector Args, - std::set AddressArgs, - std::map IntegerArgs) + IRBuilderResult(StringRef CallPrefix, const std::vector &Args, + const std::set &AddressArgs, + const std::map &IntegerArgs) : CallPrefix(CallPrefix), Args(Args), AddressArgs(AddressArgs), IntegerArgs(IntegerArgs) {} void genCode(raw_ostream &OS, @@ -727,8 +727,9 @@ public: std::string IntrinsicID; std::vector ParamTypes; std::vector Args; - IRIntrinsicResult(StringRef IntrinsicID, std::vector ParamTypes, - std::vector Args) + IRIntrinsicResult(StringRef IntrinsicID, + const std::vector &ParamTypes, + const std::vector &Args) : IntrinsicID(std::string(IntrinsicID)), ParamTypes(ParamTypes), Args(Args) {} void genCode(raw_ostream &OS, diff --git a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake index e8e5f612d5b03c3bc9fb64edad84d71702c763f6..a6c6ef93500d53b8fb90508d5e1a727863deba4d 100644 --- a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake +++ b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake @@ -368,6 +368,12 @@ macro(construct_compiler_rt_default_triple) "Default triple for which compiler-rt runtimes will be built.") endif() + if ("${CMAKE_C_COMPILER_ID}" MATCHES "Clang") + execute_process(COMMAND ${CMAKE_C_COMPILER} --target=${COMPILER_RT_DEFAULT_TARGET_TRIPLE} -print-target-triple + OUTPUT_VARIABLE COMPILER_RT_DEFAULT_TARGET_TRIPLE + OUTPUT_STRIP_TRAILING_WHITESPACE) + endif() + string(REPLACE "-" ";" LLVM_TARGET_TRIPLE_LIST ${COMPILER_RT_DEFAULT_TARGET_TRIPLE}) list(GET LLVM_TARGET_TRIPLE_LIST 0 COMPILER_RT_DEFAULT_TARGET_ARCH) diff --git a/compiler-rt/lib/scudo/standalone/allocator_config.h b/compiler-rt/lib/scudo/standalone/allocator_config.h index 1e0cf1015ba67e8d9a40be609b21efdccbe22949..60f59bdd2f4c3e5ca95a64ba326903fa74433d54 100644 --- a/compiler-rt/lib/scudo/standalone/allocator_config.h +++ b/compiler-rt/lib/scudo/standalone/allocator_config.h @@ -146,6 +146,7 @@ struct FuchsiaConfig { // Support 39-bit VMA for riscv-64 static const uptr RegionSizeLog = 28U; static const uptr GroupSizeLog = 19U; + static const bool EnableContiguousRegions = false; #else static const uptr RegionSizeLog = 30U; static const uptr GroupSizeLog = 21U; diff --git a/flang/CMakeLists.txt b/flang/CMakeLists.txt index 71141e5efac4888cb03b32f2aa0bcc891f892f66..c8e75024823f2cc98f4dacc0bc9125f588e216fe 100644 --- a/flang/CMakeLists.txt +++ b/flang/CMakeLists.txt @@ -81,12 +81,13 @@ if (FLANG_STANDALONE_BUILD) mark_as_advanced(LLVM_ENABLE_ASSERTIONS) endif() - # We need a pre-built/installed version of LLVM. - find_package(LLVM REQUIRED HINTS "${LLVM_CMAKE_DIR}") # If the user specifies a relative path to LLVM_DIR, the calls to include # LLVM modules fail. Append the absolute path to LLVM_DIR instead. - get_filename_component(LLVM_DIR_ABSOLUTE ${LLVM_DIR} REALPATH) + get_filename_component(LLVM_DIR_ABSOLUTE ${LLVM_DIR} + REALPATH BASE_DIR ${CMAKE_CURRENT_BINARY_DIR}) list(APPEND CMAKE_MODULE_PATH ${LLVM_DIR_ABSOLUTE}) + # We need a pre-built/installed version of LLVM. + find_package(LLVM REQUIRED HINTS "${LLVM_DIR_ABSOLUTE}") # Users might specify a path to CLANG_DIR that's: # * a full path, or @@ -97,7 +98,7 @@ if (FLANG_STANDALONE_BUILD) CLANG_DIR_ABSOLUTE ${CLANG_DIR} REALPATH - ${CMAKE_CURRENT_SOURCE_DIR}) + BASE_DIR ${CMAKE_CURRENT_BINARY_DIR}) list(APPEND CMAKE_MODULE_PATH ${CLANG_DIR_ABSOLUTE}) # TODO: Remove when libclangDriver is lifted out of Clang @@ -124,13 +125,14 @@ if (FLANG_STANDALONE_BUILD) include(AddClang) include(TableGen) - find_package(MLIR REQUIRED CONFIG) - # Use SYSTEM for the same reasons as for LLVM includes - include_directories(SYSTEM ${MLIR_INCLUDE_DIRS}) # If the user specifies a relative path to MLIR_DIR, the calls to include # MLIR modules fail. Append the absolute path to MLIR_DIR instead. - get_filename_component(MLIR_DIR_ABSOLUTE ${MLIR_DIR} REALPATH) + get_filename_component(MLIR_DIR_ABSOLUTE ${MLIR_DIR} + REALPATH BASE_DIR ${CMAKE_CURRENT_BINARY_DIR}) list(APPEND CMAKE_MODULE_PATH ${MLIR_DIR_ABSOLUTE}) + find_package(MLIR REQUIRED CONFIG HINTS ${MLIR_DIR_ABSOLUTE}) + # Use SYSTEM for the same reasons as for LLVM includes + include_directories(SYSTEM ${MLIR_INCLUDE_DIRS}) include(AddMLIR) find_program(MLIR_TABLEGEN_EXE "mlir-tblgen" ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH) diff --git a/flang/docs/FlangDriver.md b/flang/docs/FlangDriver.md index 814f3eb12cfcbc5fe2f4557c8f4b139164b8b04f..ac120b4ff09b6d0b9e9aa07b43293813ca1082eb 100644 --- a/flang/docs/FlangDriver.md +++ b/flang/docs/FlangDriver.md @@ -266,26 +266,6 @@ is `ParseSyntaxOnlyAction`, which corresponds to `-fsyntax-only`. In other words, `flang-new -fc1 ` is equivalent to `flang-new -fc1 -fsyntax-only `. -## The `flang-to-external-fc` script -The `flang-to-external-fc` wrapper script for `flang-new` was introduced as a -development tool and to facilitate testing. The `flang-to-external-fc` wrapper -script will: -* use `flang-new` to unparse the input source file (i.e. it will run `flang-new - -fc1 -fdebug-unparse `), and then -* call a host Fortran compiler, e.g. `gfortran`, to compile the unparsed file. - -Here's a basic breakdown of what happens inside `flang-to-external-fc` when you -run `flang-to-external-fc file.f90`: -```bash -flang-new -fc1 -fdebug-unparse file.f90 -o file-unparsed.f90 -gfortran file-unparsed.f90 -``` -This is a simplified version for illustration purposes only. In practice, -`flang-to-external-fc` adds a few more frontend options and it also supports -various other use cases (e.g. compiling C files, linking existing object -files). `gfortran` is the default host compiler used by `flang-to-external-fc`. -You can change it by setting the `FLANG_FC` environment variable. - ## Adding new Compiler Options Adding a new compiler option in Flang consists of two steps: * define the new option in a dedicated TableGen file, diff --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h index d8840d9e967b48c25f34ded21b33508fae2b75a9..4d290d87d4cc9576459177468ed4f19c5f46e568 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.h +++ b/flang/include/flang/Optimizer/Transforms/Passes.h @@ -31,8 +31,7 @@ namespace fir { // Passes defined in Passes.td //===----------------------------------------------------------------------===// -#define GEN_PASS_DECL_ABSTRACTRESULTONFUNCOPT -#define GEN_PASS_DECL_ABSTRACTRESULTONGLOBALOPT +#define GEN_PASS_DECL_ABSTRACTRESULTOPT #define GEN_PASS_DECL_AFFINEDIALECTPROMOTION #define GEN_PASS_DECL_AFFINEDIALECTDEMOTION #define GEN_PASS_DECL_ANNOTATECONSTANTOPERANDS @@ -50,8 +49,6 @@ namespace fir { #define GEN_PASS_DECL_OPENACCDATAOPERANDCONVERSION #include "flang/Optimizer/Transforms/Passes.h.inc" -std::unique_ptr createAbstractResultOnFuncOptPass(); -std::unique_ptr createAbstractResultOnGlobalOptPass(); std::unique_ptr createAffineDemotionPass(); std::unique_ptr createArrayValueCopyPass(fir::ArrayValueCopyOptions options = {}); diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index bfc0db8124af21cd42e42c5b6539c2892fecc5b8..467b7e1c472ec02d3e5a5c5c4a46f227ee00c719 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -16,8 +16,8 @@ include "mlir/Pass/PassBase.td" -class AbstractResultOptBase - : Pass<"abstract-result-on-" # optExt # "-opt", operation> { +def AbstractResultOpt + : Pass<"abstract-result"> { let summary = "Convert fir.array, fir.box and fir.rec function result to " "function argument"; let description = [{ @@ -35,14 +35,6 @@ class AbstractResultOptBase ]; } -def AbstractResultOnFuncOpt : AbstractResultOptBase<"func", "mlir::func::FuncOp"> { - let constructor = "::fir::createAbstractResultOnFuncOptPass()"; -} - -def AbstractResultOnGlobalOpt : AbstractResultOptBase<"global", "fir::GlobalOp"> { - let constructor = "::fir::createAbstractResultOnGlobalOptPass()"; -} - def AffineDialectPromotion : Pass<"promote-to-affine", "::mlir::func::FuncOp"> { let summary = "Promotes `fir.{do_loop,if}` to `affine.{for,if}`."; let description = [{ diff --git a/flang/include/flang/Tools/CLOptions.inc b/flang/include/flang/Tools/CLOptions.inc index ea297fb337a2c84f86680d79510806f2eff60ea3..44ff2b3f70ff688bbd851e8a01afef7bf66baa4a 100644 --- a/flang/include/flang/Tools/CLOptions.inc +++ b/flang/include/flang/Tools/CLOptions.inc @@ -19,6 +19,7 @@ #include "flang/Optimizer/Transforms/Passes.h" #include "llvm/Passes/OptimizationLevel.h" #include "llvm/Support/CommandLine.h" +#include #define DisableOption(DOName, DOOption, DODescription) \ static llvm::cl::opt disable##DOName("disable-" DOOption, \ @@ -86,6 +87,29 @@ DisableOption(BoxedProcedureRewrite, "boxed-procedure-rewrite", DisableOption(ExternalNameConversion, "external-name-interop", "convert names with external convention"); +// TODO: remove once these are used for non-codegen passes +#if !defined(FLANG_EXCLUDE_CODEGEN) +using PassConstructor = std::unique_ptr(); + +template +void addNestedPassToOps(mlir::PassManager &pm, PassConstructor ctor) { + pm.addNestedPass(ctor()); +} + +template > +void addNestedPassToOps(mlir::PassManager &pm, PassConstructor ctor) { + addNestedPassToOps(pm, ctor); + addNestedPassToOps(pm, ctor); +} + +void addNestedPassToAllTopLevelOperations( + mlir::PassManager &pm, PassConstructor ctor) { + addNestedPassToOps(pm, ctor); +} +#endif + /// Generic for adding a pass to the pass manager if it is not disabled. template void addPassConditionally( @@ -304,9 +328,7 @@ inline void createDebugPasses( inline void createDefaultFIRCodeGenPassPipeline( mlir::PassManager &pm, MLIRToLLVMPassPipelineConfig config) { fir::addBoxedProcedurePass(pm); - pm.addNestedPass( - fir::createAbstractResultOnFuncOptPass()); - pm.addNestedPass(fir::createAbstractResultOnGlobalOptPass()); + addNestedPassToAllTopLevelOperations(pm, fir::createAbstractResultOpt); fir::addCodeGenRewritePass(pm); fir::addTargetRewritePass(pm); fir::addExternalNameConversionPass(pm, config.Underscoring); diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index e432c5a302754c3aea542b315d14854ff489b3e7..f1b7b53975398e31cf529fd53f169afa097a63fd 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -145,6 +145,7 @@ static bool parseDebugArgs(Fortran::frontend::CodeGenOptions &opts, } opts.setDebugInfo(val.value()); if (val != llvm::codegenoptions::DebugLineTablesOnly && + val != llvm::codegenoptions::FullDebugInfo && val != llvm::codegenoptions::NoDebugInfo) { const auto debugWarning = diags.getCustomDiagID( clang::DiagnosticsEngine::Warning, "Unsupported debug option: %0"); diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp index 5a42e6a6aa4175b45d76e261af9fc8b703636406..8bb2f83282b5565fd651f439f42f55b84443cd34 100644 --- a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp +++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp @@ -136,7 +136,7 @@ void DataSharingProcessor::insertBarrier() { void DataSharingProcessor::insertLastPrivateCompare(mlir::Operation *op) { bool cmpCreated = false; - mlir::OpBuilder::InsertPoint localInsPt = firOpBuilder.saveInsertionPoint(); + mlir::OpBuilder::InsertionGuard guard(firOpBuilder); for (const omp::Clause &clause : clauses) { if (clause.id != llvm::omp::OMPC_lastprivate) continue; @@ -203,12 +203,11 @@ void DataSharingProcessor::insertLastPrivateCompare(mlir::Operation *op) { // Lastprivate operation is inserted at the end // of the lexically last section in the sections // construct - mlir::OpBuilder::InsertPoint unstructuredSectionsIP = - firOpBuilder.saveInsertionPoint(); + mlir::OpBuilder::InsertionGuard unstructuredSectionsGuard( + firOpBuilder); mlir::Operation *lastOper = op->getRegion(0).back().getTerminator(); firOpBuilder.setInsertionPoint(lastOper); lastPrivIP = firOpBuilder.saveInsertionPoint(); - firOpBuilder.restoreInsertionPoint(unstructuredSectionsIP); } } } else if (mlir::isa(op)) { @@ -268,7 +267,6 @@ void DataSharingProcessor::insertLastPrivateCompare(mlir::Operation *op) { "simd/worksharing-loop"); } } - firOpBuilder.restoreInsertionPoint(localInsPt); } void DataSharingProcessor::collectSymbols( @@ -372,7 +370,7 @@ void DataSharingProcessor::doPrivatize( uniquePrivatizerName)) return existingPrivatizer; - auto ip = firOpBuilder.saveInsertionPoint(); + mlir::OpBuilder::InsertionGuard guard(firOpBuilder); firOpBuilder.setInsertionPoint(&moduleOp.getBodyRegion().front(), moduleOp.getBodyRegion().front().begin()); auto result = firOpBuilder.create( @@ -424,7 +422,6 @@ void DataSharingProcessor::doPrivatize( } symTable->popScope(); - firOpBuilder.restoreInsertionPoint(ip); return result; }(); diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index 4424788e0132e28424cff3bf5cd8d8ca6ff19dc4..e932f7c284bca89fc60cc6ab0115ef687a8e5807 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -134,7 +134,7 @@ static void threadPrivatizeVars(Fortran::lower::AbstractConverter &converter, Fortran::lower::pft::Evaluation &eval) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); mlir::Location currentLocation = converter.getCurrentLocation(); - mlir::OpBuilder::InsertPoint insPt = firOpBuilder.saveInsertionPoint(); + mlir::OpBuilder::InsertionGuard guard(firOpBuilder); firOpBuilder.setInsertionPointToStart(firOpBuilder.getAllocaBlock()); // If the symbol corresponds to the original ThreadprivateOp, use the symbol @@ -197,8 +197,6 @@ static void threadPrivatizeVars(Fortran::lower::AbstractConverter &converter, getExtendedValue(sexv, symThreadprivateValue); converter.bindSymbol(*sym, symThreadprivateExv); } - - firOpBuilder.restoreInsertionPoint(insPt); } static mlir::Operation * @@ -1091,16 +1089,12 @@ static void genParallelClauses( static void genSectionsClauses(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, const List &clauses, mlir::Location loc, - bool clausesFromBeginSections, mlir::omp::SectionsClauseOps &clauseOps) { ClauseProcessor cp(converter, semaCtx, clauses); - if (clausesFromBeginSections) { - cp.processAllocate(clauseOps); - cp.processSectionsReduction(loc, clauseOps); - // TODO Support delayed privatization. - } else { - cp.processNowait(clauseOps); - } + cp.processAllocate(clauseOps); + cp.processSectionsReduction(loc, clauseOps); + cp.processNowait(clauseOps); + // TODO Support delayed privatization. } static void genSimdClauses(Fortran::lower::AbstractConverter &converter, @@ -1121,16 +1115,13 @@ static void genSimdClauses(Fortran::lower::AbstractConverter &converter, static void genSingleClauses(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, - const List &beginClauses, - const List &endClauses, mlir::Location loc, + const List &clauses, mlir::Location loc, mlir::omp::SingleClauseOps &clauseOps) { - ClauseProcessor bcp(converter, semaCtx, beginClauses); - bcp.processAllocate(clauseOps); + ClauseProcessor cp(converter, semaCtx, clauses); + cp.processAllocate(clauseOps); + cp.processCopyprivate(loc, clauseOps); + cp.processNowait(clauseOps); // TODO Support delayed privatization. - - ClauseProcessor ecp(converter, semaCtx, endClauses); - ecp.processCopyprivate(loc, clauseOps); - ecp.processNowait(clauseOps); } static void genTargetClauses( @@ -1280,30 +1271,25 @@ static void genWsloopClauses( Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, Fortran::lower::StatementContext &stmtCtx, - Fortran::lower::pft::Evaluation &eval, const List &beginClauses, - const List &endClauses, mlir::Location loc, - mlir::omp::WsloopClauseOps &clauseOps, + Fortran::lower::pft::Evaluation &eval, const List &clauses, + mlir::Location loc, mlir::omp::WsloopClauseOps &clauseOps, llvm::SmallVectorImpl &iv, llvm::SmallVectorImpl &reductionTypes, llvm::SmallVectorImpl &reductionSyms) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - ClauseProcessor bcp(converter, semaCtx, beginClauses); - bcp.processCollapse(loc, eval, clauseOps, iv); - bcp.processOrdered(clauseOps); - bcp.processReduction(loc, clauseOps, &reductionTypes, &reductionSyms); - bcp.processSchedule(stmtCtx, clauseOps); + ClauseProcessor cp(converter, semaCtx, clauses); + cp.processCollapse(loc, eval, clauseOps, iv); + cp.processNowait(clauseOps); + cp.processOrdered(clauseOps); + cp.processReduction(loc, clauseOps, &reductionTypes, &reductionSyms); + cp.processSchedule(stmtCtx, clauseOps); clauseOps.loopInclusiveAttr = firOpBuilder.getUnitAttr(); // TODO Support delayed privatization. if (ReductionProcessor::doReductionByRef(clauseOps.reductionVars)) clauseOps.reductionByRefAttr = firOpBuilder.getUnitAttr(); - if (!endClauses.empty()) { - ClauseProcessor ecp(converter, semaCtx, endClauses); - ecp.processNowait(clauseOps); - } - - bcp.processTODO( + cp.processTODO( loc, llvm::omp::Directive::OMPD_do); } @@ -1557,17 +1543,15 @@ static mlir::omp::SingleOp genSingleOp(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, Fortran::lower::pft::Evaluation &eval, bool genNested, - mlir::Location loc, const List &beginClauses, - const List &endClauses) { + mlir::Location loc, const List &clauses) { mlir::omp::SingleClauseOps clauseOps; - genSingleClauses(converter, semaCtx, beginClauses, endClauses, loc, - clauseOps); + genSingleClauses(converter, semaCtx, clauses, loc, clauseOps); return genOpWithBody( OpWithBodyGenInfo(converter, semaCtx, loc, eval, llvm::omp::Directive::OMPD_single) .setGenNested(genNested) - .setClauses(&beginClauses), + .setClauses(&clauses), clauseOps); } @@ -1816,8 +1800,8 @@ static mlir::omp::WsloopOp genWsloopOp(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, Fortran::lower::pft::Evaluation &eval, mlir::Location loc, - const List &beginClauses, const List &endClauses) { - DataSharingProcessor dsp(converter, semaCtx, beginClauses, eval); + const List &clauses) { + DataSharingProcessor dsp(converter, semaCtx, clauses, eval); dsp.processStep1(); Fortran::lower::StatementContext stmtCtx; @@ -1825,10 +1809,10 @@ genWsloopOp(Fortran::lower::AbstractConverter &converter, llvm::SmallVector iv; llvm::SmallVector reductionTypes; llvm::SmallVector reductionSyms; - genWsloopClauses(converter, semaCtx, stmtCtx, eval, beginClauses, endClauses, - loc, clauseOps, iv, reductionTypes, reductionSyms); + genWsloopClauses(converter, semaCtx, stmtCtx, eval, clauses, loc, clauseOps, + iv, reductionTypes, reductionSyms); - auto *nestedEval = getCollapsedLoopEval(eval, getCollapseValue(beginClauses)); + auto *nestedEval = getCollapsedLoopEval(eval, getCollapseValue(clauses)); auto ivCallback = [&](mlir::Operation *op) { return genLoopAndReductionVars(op, converter, loc, iv, reductionSyms, @@ -1838,7 +1822,7 @@ genWsloopOp(Fortran::lower::AbstractConverter &converter, return genOpWithBody( OpWithBodyGenInfo(converter, semaCtx, loc, *nestedEval, llvm::omp::Directive::OMPD_do) - .setClauses(&beginClauses) + .setClauses(&clauses) .setDataSharingProcessor(&dsp) .setReductions(&reductionSyms, &reductionTypes) .setGenRegionEntryCb(ivCallback), @@ -1849,19 +1833,20 @@ genWsloopOp(Fortran::lower::AbstractConverter &converter, // Code generation functions for composite constructs //===----------------------------------------------------------------------===// -static void genCompositeDistributeParallelDo( - Fortran::lower::AbstractConverter &converter, - Fortran::semantics::SemanticsContext &semaCtx, - Fortran::lower::pft::Evaluation &eval, const List &beginClauses, - const List &endClauses, mlir::Location loc) { +static void +genCompositeDistributeParallelDo(Fortran::lower::AbstractConverter &converter, + Fortran::semantics::SemanticsContext &semaCtx, + Fortran::lower::pft::Evaluation &eval, + const List &clauses, + mlir::Location loc) { TODO(loc, "Composite DISTRIBUTE PARALLEL DO"); } static void genCompositeDistributeParallelDoSimd( Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, - Fortran::lower::pft::Evaluation &eval, const List &beginClauses, - const List &endClauses, mlir::Location loc) { + Fortran::lower::pft::Evaluation &eval, const List &clauses, + mlir::Location loc) { TODO(loc, "Composite DISTRIBUTE PARALLEL DO SIMD"); } @@ -1869,18 +1854,16 @@ static void genCompositeDistributeSimd(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, Fortran::lower::pft::Evaluation &eval, - const List &beginClauses, - const List &endClauses, mlir::Location loc) { + const List &clauses, mlir::Location loc) { TODO(loc, "Composite DISTRIBUTE SIMD"); } static void genCompositeDoSimd(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, Fortran::lower::pft::Evaluation &eval, - const List &beginClauses, - const List &endClauses, + const List &clauses, mlir::Location loc) { - ClauseProcessor cp(converter, semaCtx, beginClauses); + ClauseProcessor cp(converter, semaCtx, clauses); cp.processTODO( loc, llvm::omp::OMPD_do_simd); @@ -1892,15 +1875,14 @@ static void genCompositeDoSimd(Fortran::lower::AbstractConverter &converter, // When support for vectorization is enabled, then we need to add handling of // if clause. Currently if clause can be skipped because we always assume // SIMD length = 1. - genWsloopOp(converter, semaCtx, eval, loc, beginClauses, endClauses); + genWsloopOp(converter, semaCtx, eval, loc, clauses); } static void genCompositeTaskloopSimd(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, Fortran::lower::pft::Evaluation &eval, - const List &beginClauses, - const List &endClauses, mlir::Location loc) { + const List &clauses, mlir::Location loc) { TODO(loc, "Composite TASKLOOP SIMD"); } @@ -2172,49 +2154,44 @@ genOMP(Fortran::lower::AbstractConverter &converter, converter.genLocation(beginBlockDirective.source); const auto origDirective = std::get(beginBlockDirective.t).v; - List beginClauses = makeClauses( + List clauses = makeClauses( std::get(beginBlockDirective.t), semaCtx); - List endClauses = makeClauses( - std::get(endBlockDirective.t), semaCtx); + clauses.append(makeClauses( + std::get(endBlockDirective.t), semaCtx)); assert(llvm::omp::blockConstructSet.test(origDirective) && "Expected block construct"); - for (const Clause &clause : beginClauses) { + for (const Clause &clause : clauses) { mlir::Location clauseLocation = converter.genLocation(clause.source); - if (!std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u)) { + if (!std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u)) { TODO(clauseLocation, "OpenMP Block construct clause"); } } - for (const Clause &clause : endClauses) { - mlir::Location clauseLocation = converter.genLocation(clause.source); - if (!std::get_if(&clause.u) && - !std::get_if(&clause.u)) - TODO(clauseLocation, "OpenMP Block construct clause"); - } - std::optional nextDir = origDirective; bool outermostLeafConstruct = true; while (nextDir) { @@ -2230,44 +2207,42 @@ genOMP(Fortran::lower::AbstractConverter &converter, case llvm::omp::Directive::OMPD_ordered: // 2.17.9 ORDERED construct. genOrderedRegionOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses); + clauses); break; case llvm::omp::Directive::OMPD_parallel: // 2.6 PARALLEL construct. genParallelOp(converter, symTable, semaCtx, eval, genNested, - currentLocation, beginClauses, outerCombined); + currentLocation, clauses, outerCombined); break; case llvm::omp::Directive::OMPD_single: // 2.8.2 SINGLE construct. genSingleOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses, endClauses); + clauses); break; case llvm::omp::Directive::OMPD_target: // 2.12.5 TARGET construct. - genTargetOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses, outerCombined); + genTargetOp(converter, semaCtx, eval, genNested, currentLocation, clauses, + outerCombined); break; case llvm::omp::Directive::OMPD_target_data: // 2.12.2 TARGET DATA construct. genTargetDataOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses); + clauses); break; case llvm::omp::Directive::OMPD_task: // 2.10.1 TASK construct. - genTaskOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses); + genTaskOp(converter, semaCtx, eval, genNested, currentLocation, clauses); break; case llvm::omp::Directive::OMPD_taskgroup: // 2.17.6 TASKGROUP construct. genTaskgroupOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses); + clauses); break; case llvm::omp::Directive::OMPD_teams: // 2.7 TEAMS construct. // FIXME Pass the outerCombined argument or rename it to better describe // what it represents if it must always be `false` in this context. - genTeamsOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses); + genTeamsOp(converter, semaCtx, eval, genNested, currentLocation, clauses); break; case llvm::omp::Directive::OMPD_workshare: // 2.8.3 WORKSHARE construct. @@ -2275,7 +2250,7 @@ genOMP(Fortran::lower::AbstractConverter &converter, // implementation for this feature will come later. For the codes // that use this construct, add a single construct for now. genSingleOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses, endClauses); + clauses); break; default: llvm_unreachable("Unexpected block construct"); @@ -2317,7 +2292,7 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, const Fortran::parser::OpenMPLoopConstruct &loopConstruct) { const auto &beginLoopDirective = std::get(loopConstruct.t); - List beginClauses = makeClauses( + List clauses = makeClauses( std::get(beginLoopDirective.t), semaCtx); mlir::Location currentLocation = converter.genLocation(beginLoopDirective.source); @@ -2327,16 +2302,13 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, assert(llvm::omp::loopConstructSet.test(origDirective) && "Expected loop construct"); - List endClauses = [&]() { - if (auto &endLoopDirective = - std::get>( - loopConstruct.t)) { - return makeClauses( - std::get(endLoopDirective->t), - semaCtx); - } - return List{}; - }(); + if (auto &endLoopDirective = + std::get>( + loopConstruct.t)) { + clauses.append(makeClauses( + std::get(endLoopDirective->t), + semaCtx)); + } std::optional nextDir = origDirective; while (nextDir) { @@ -2347,29 +2319,27 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, switch (leafDir) { case llvm::omp::Directive::OMPD_distribute_parallel_do: // 2.9.4.3 DISTRIBUTE PARALLEL Worksharing-Loop construct. - genCompositeDistributeParallelDo(converter, semaCtx, eval, beginClauses, - endClauses, currentLocation); + genCompositeDistributeParallelDo(converter, semaCtx, eval, clauses, + currentLocation); break; case llvm::omp::Directive::OMPD_distribute_parallel_do_simd: // 2.9.4.4 DISTRIBUTE PARALLEL Worksharing-Loop SIMD construct. - genCompositeDistributeParallelDoSimd(converter, semaCtx, eval, - beginClauses, endClauses, + genCompositeDistributeParallelDoSimd(converter, semaCtx, eval, clauses, currentLocation); break; case llvm::omp::Directive::OMPD_distribute_simd: // 2.9.4.2 DISTRIBUTE SIMD construct. - genCompositeDistributeSimd(converter, semaCtx, eval, beginClauses, - endClauses, currentLocation); + genCompositeDistributeSimd(converter, semaCtx, eval, clauses, + currentLocation); break; case llvm::omp::Directive::OMPD_do_simd: // 2.9.3.2 Worksharing-Loop SIMD construct. - genCompositeDoSimd(converter, semaCtx, eval, beginClauses, endClauses, - currentLocation); + genCompositeDoSimd(converter, semaCtx, eval, clauses, currentLocation); break; case llvm::omp::Directive::OMPD_taskloop_simd: // 2.10.3 TASKLOOP SIMD construct. - genCompositeTaskloopSimd(converter, semaCtx, eval, beginClauses, - endClauses, currentLocation); + genCompositeTaskloopSimd(converter, semaCtx, eval, clauses, + currentLocation); break; default: llvm_unreachable("Unexpected composite construct"); @@ -2380,12 +2350,11 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, case llvm::omp::Directive::OMPD_distribute: // 2.9.4.1 DISTRIBUTE construct. genDistributeOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses); + clauses); break; case llvm::omp::Directive::OMPD_do: // 2.9.2 Worksharing-Loop construct. - genWsloopOp(converter, semaCtx, eval, currentLocation, beginClauses, - endClauses); + genWsloopOp(converter, semaCtx, eval, currentLocation, clauses); break; case llvm::omp::Directive::OMPD_parallel: // 2.6 PARALLEL construct. @@ -2394,21 +2363,21 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, // Maybe rename the argument if it represents something else or // initialize it properly. genParallelOp(converter, symTable, semaCtx, eval, genNested, - currentLocation, beginClauses, + currentLocation, clauses, /*outerCombined=*/true); break; case llvm::omp::Directive::OMPD_simd: // 2.9.3.1 SIMD construct. - genSimdOp(converter, semaCtx, eval, currentLocation, beginClauses); + genSimdOp(converter, semaCtx, eval, currentLocation, clauses); break; case llvm::omp::Directive::OMPD_target: // 2.12.5 TARGET construct. genTargetOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses, /*outerCombined=*/true); + clauses, /*outerCombined=*/true); break; case llvm::omp::Directive::OMPD_taskloop: // 2.10.2 TASKLOOP construct. - genTaskloopOp(converter, semaCtx, eval, currentLocation, beginClauses); + genTaskloopOp(converter, semaCtx, eval, currentLocation, clauses); break; case llvm::omp::Directive::OMPD_teams: // 2.7 TEAMS construct. @@ -2417,7 +2386,7 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, // Maybe rename the argument if it represents something else or // initialize it properly. genTeamsOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses, /*outerCombined=*/true); + clauses, /*outerCombined=*/true); break; case llvm::omp::Directive::OMPD_loop: case llvm::omp::Directive::OMPD_masked: @@ -2453,16 +2422,20 @@ genOMP(Fortran::lower::AbstractConverter &converter, const Fortran::parser::OpenMPSectionsConstruct §ionsConstruct) { const auto &beginSectionsDirective = std::get(sectionsConstruct.t); - List beginClauses = makeClauses( + List clauses = makeClauses( std::get(beginSectionsDirective.t), semaCtx); + const auto &endSectionsDirective = + std::get(sectionsConstruct.t); + clauses.append(makeClauses( + std::get(endSectionsDirective.t), + semaCtx)); // Process clauses before optional omp.parallel, so that new variables are // allocated outside of the parallel region mlir::Location currentLocation = converter.getCurrentLocation(); mlir::omp::SectionsClauseOps clauseOps; - genSectionsClauses(converter, semaCtx, beginClauses, currentLocation, - /*clausesFromBeginSections=*/true, clauseOps); + genSectionsClauses(converter, semaCtx, clauses, currentLocation, clauseOps); // Parallel wrapper of PARALLEL SECTIONS construct llvm::omp::Directive dir = @@ -2470,16 +2443,8 @@ genOMP(Fortran::lower::AbstractConverter &converter, .v; if (dir == llvm::omp::Directive::OMPD_parallel_sections) { genParallelOp(converter, symTable, semaCtx, eval, - /*genNested=*/false, currentLocation, beginClauses, + /*genNested=*/false, currentLocation, clauses, /*outerCombined=*/true); - } else { - const auto &endSectionsDirective = - std::get(sectionsConstruct.t); - List endClauses = makeClauses( - std::get(endSectionsDirective.t), - semaCtx); - genSectionsClauses(converter, semaCtx, endClauses, currentLocation, - /*clausesFromBeginSections=*/false, clauseOps); } // SECTIONS construct. @@ -2494,7 +2459,7 @@ genOMP(Fortran::lower::AbstractConverter &converter, llvm::zip(sectionBlocks.v, eval.getNestedEvaluations())) { symTable.pushScope(); genSectionOp(converter, semaCtx, neval, /*genNested=*/true, currentLocation, - beginClauses); + clauses); symTable.popScope(); firOpBuilder.restoreInsertionPoint(ip); } diff --git a/flang/lib/Lower/OpenMP/ReductionProcessor.cpp b/flang/lib/Lower/OpenMP/ReductionProcessor.cpp index f42386fe2736ddc927b48a2f66a34255f62a06ed..9f8352a8025cee2955dcf7ec830960e7f06a34f5 100644 --- a/flang/lib/Lower/OpenMP/ReductionProcessor.cpp +++ b/flang/lib/Lower/OpenMP/ReductionProcessor.cpp @@ -220,12 +220,12 @@ mlir::Value ReductionProcessor::createScalarCombiner( switch (redId) { case ReductionIdentifier::MAX: reductionOp = - getReductionOperation( + getReductionOperation( builder, type, loc, op1, op2); break; case ReductionIdentifier::MIN: reductionOp = - getReductionOperation( + getReductionOperation( builder, type, loc, op1, op2); break; case ReductionIdentifier::IOR: @@ -486,9 +486,8 @@ createReductionInitRegion(fir::FirOpBuilder &builder, mlir::Location loc, assert(cstNeedsDealloc.has_value() && "createTempFromMold decides this statically"); if (cstNeedsDealloc.has_value() && *cstNeedsDealloc != false) { - auto insPt = builder.saveInsertionPoint(); + mlir::OpBuilder::InsertionGuard guard(builder); createReductionCleanupRegion(builder, loc, reductionDecl); - builder.restoreInsertionPoint(insPt); } // Put the temporary inside of a box: diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp index e144640081cbf33649243e7a3cbac3b3d9fc614e..c403b9effbfac6432553e8320c22df8e63937f24 100644 --- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp +++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp @@ -29,7 +29,7 @@ using namespace mlir; //===----------------------------------------------------------------------===// static bool isDummyArgument(mlir::Value v) { - auto blockArg{v.dyn_cast()}; + auto blockArg{mlir::dyn_cast(v)}; if (!blockArg) return false; diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp index d909bda89cdeb40c1b342ecfdd73305750ac550c..921eac2f8f4b60bda5ed6e8ab8762d449526e000 100644 --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -2110,9 +2110,8 @@ struct XArrayCoorOpConversion const bool baseIsBoxed = coor.getMemref().getType().isa(); TypePair baseBoxTyPair = baseIsBoxed ? getBoxTypePair(coor.getMemref().getType()) : TypePair{}; - mlir::LLVM::IntegerOverflowFlagsAttr nsw = - mlir::LLVM::IntegerOverflowFlagsAttr::get( - rewriter.getContext(), mlir::LLVM::IntegerOverflowFlags::nsw); + mlir::LLVM::IntegerOverflowFlags nsw = + mlir::LLVM::IntegerOverflowFlags::nsw; // For each dimension of the array, generate the offset calculation. for (unsigned i = 0; i < rank; ++i, ++indexOffset, ++shapeOffset, @@ -2396,9 +2395,8 @@ private: auto cpnTy = fir::dyn_cast_ptrOrBoxEleTy(boxObjTy); mlir::Type llvmPtrTy = ::getLlvmPtrType(coor.getContext()); mlir::Type byteTy = ::getI8Type(coor.getContext()); - mlir::LLVM::IntegerOverflowFlagsAttr nsw = - mlir::LLVM::IntegerOverflowFlagsAttr::get( - rewriter.getContext(), mlir::LLVM::IntegerOverflowFlags::nsw); + mlir::LLVM::IntegerOverflowFlags nsw = + mlir::LLVM::IntegerOverflowFlags::nsw; for (unsigned i = 1, last = operands.size(); i < last; ++i) { if (auto arrTy = cpnTy.dyn_cast()) { diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp index 5c24c95db427aa9e2a325a0112547da53f42f0a6..24af94f9b90a1dfd5bf59e0261264e6856c5b3eb 100644 --- a/flang/lib/Optimizer/Dialect/FIROps.cpp +++ b/flang/lib/Optimizer/Dialect/FIROps.cpp @@ -2165,7 +2165,7 @@ mlir::ParseResult fir::DoLoopOp::parse(mlir::OpAsmParser &parser, } fir::DoLoopOp fir::getForInductionVarOwner(mlir::Value val) { - auto ivArg = val.dyn_cast(); + auto ivArg = mlir::dyn_cast(val); if (!ivArg) return {}; assert(ivArg.getOwner() && "unlinked block argument"); @@ -3777,7 +3777,7 @@ valueCheckFirAttributes(mlir::Value value, if (auto loadOp = mlir::dyn_cast(definingOp)) value = loadOp.getMemref(); // If this is a function argument, look in the argument attributes. - if (auto blockArg = value.dyn_cast()) { + if (auto blockArg = mlir::dyn_cast(value)) { if (blockArg.getOwner() && blockArg.getOwner()->isEntryBlock()) if (auto funcOp = mlir::dyn_cast( blockArg.getOwner()->getParentOp())) @@ -3907,7 +3907,7 @@ mlir::ParseResult parseCUFKernelValues( if (mlir::succeeded(parser.parseOptionalStar())) return mlir::success(); - if (parser.parseOptionalLParen()) { + if (mlir::succeeded(parser.parseOptionalLParen())) { if (mlir::failed(parser.parseCommaSeparatedList( mlir::AsmParser::Delimiter::None, [&]() { if (parser.parseOperand(values.emplace_back())) @@ -3915,11 +3915,17 @@ mlir::ParseResult parseCUFKernelValues( return mlir::success(); }))) return mlir::failure(); + auto builder = parser.getBuilder(); + for (size_t i = 0; i < values.size(); i++) { + types.emplace_back(builder.getI32Type()); + } if (parser.parseRParen()) return mlir::failure(); } else { if (parser.parseOperand(values.emplace_back())) return mlir::failure(); + auto builder = parser.getBuilder(); + types.emplace_back(builder.getI32Type()); return mlir::success(); } return mlir::success(); diff --git a/flang/lib/Optimizer/Transforms/AbstractResult.cpp b/flang/lib/Optimizer/Transforms/AbstractResult.cpp index dd1ddd16f2ded5a5c8a6473339d306a0ccf8133b..eb4dd637bb167e88b44320cb211139d1e609c320 100644 --- a/flang/lib/Optimizer/Transforms/AbstractResult.cpp +++ b/flang/lib/Optimizer/Transforms/AbstractResult.cpp @@ -16,13 +16,12 @@ #include "mlir/Dialect/Func/IR/FuncOps.h" #include "mlir/IR/Diagnostics.h" #include "mlir/Pass/Pass.h" +#include "mlir/Pass/PassManager.h" #include "mlir/Transforms/DialectConversion.h" -#include "mlir/Transforms/Passes.h" #include "llvm/ADT/TypeSwitch.h" namespace fir { -#define GEN_PASS_DEF_ABSTRACTRESULTONFUNCOPT -#define GEN_PASS_DEF_ABSTRACTRESULTONGLOBALOPT +#define GEN_PASS_DEF_ABSTRACTRESULTOPT #include "flang/Optimizer/Transforms/Passes.h.inc" } // namespace fir @@ -285,59 +284,12 @@ private: bool shouldBoxResult; }; -/// @brief Base CRTP class for AbstractResult pass family. -/// Contains common logic for abstract result conversion in a reusable fashion. -/// @tparam Pass target class that implements operation-specific logic. -/// @tparam PassBase base class template for the pass generated by TableGen. -/// The `Pass` class must define runOnSpecificOperation(OpTy, bool, -/// mlir::RewritePatternSet&, mlir::ConversionTarget&) member function. -/// This function should implement operation-specific functionality. -template class PassBase> -class AbstractResultOptTemplate : public PassBase { +class AbstractResultOpt + : public fir::impl::AbstractResultOptBase { public: - void runOnOperation() override { - auto *context = &this->getContext(); - auto op = this->getOperation(); - - mlir::RewritePatternSet patterns(context); - mlir::ConversionTarget target = *context; - const bool shouldBoxResult = this->passResultAsBox.getValue(); - - auto &self = static_cast(*this); - self.runOnSpecificOperation(op, shouldBoxResult, patterns, target); - - // Convert the calls and, if needed, the ReturnOp in the function body. - target.addLegalDialect(); - target.addIllegalOp(); - target.addDynamicallyLegalOp([](fir::CallOp call) { - return !hasAbstractResult(call.getFunctionType()); - }); - target.addDynamicallyLegalOp([](fir::AddrOfOp addrOf) { - if (auto funTy = addrOf.getType().dyn_cast()) - return !hasAbstractResult(funTy); - return true; - }); - target.addDynamicallyLegalOp([](fir::DispatchOp dispatch) { - return !hasAbstractResult(dispatch.getFunctionType()); - }); - - patterns.insert>(context, shouldBoxResult); - patterns.insert>(context, shouldBoxResult); - patterns.insert(context); - patterns.insert(context, shouldBoxResult); - if (mlir::failed( - mlir::applyPartialConversion(op, target, std::move(patterns)))) { - mlir::emitError(op.getLoc(), "error in converting abstract results\n"); - this->signalPassFailure(); - } - } -}; + using fir::impl::AbstractResultOptBase< + AbstractResultOpt>::AbstractResultOptBase; -class AbstractResultOnFuncOpt - : public AbstractResultOptTemplate { -public: void runOnSpecificOperation(mlir::func::FuncOp func, bool shouldBoxResult, mlir::RewritePatternSet &patterns, mlir::ConversionTarget &target) { @@ -386,25 +338,20 @@ public: } } } -}; -inline static bool containsFunctionTypeWithAbstractResult(mlir::Type type) { - return mlir::TypeSwitch(type) - .Case([](fir::BoxProcType boxProc) { - return fir::hasAbstractResult( - boxProc.getEleTy().cast()); - }) - .Case([](fir::PointerType pointer) { - return fir::hasAbstractResult( - pointer.getEleTy().cast()); - }) - .Default([](auto &&) { return false; }); -} + inline static bool containsFunctionTypeWithAbstractResult(mlir::Type type) { + return mlir::TypeSwitch(type) + .Case([](fir::BoxProcType boxProc) { + return fir::hasAbstractResult( + boxProc.getEleTy().cast()); + }) + .Case([](fir::PointerType pointer) { + return fir::hasAbstractResult( + pointer.getEleTy().cast()); + }) + .Default([](auto &&) { return false; }); + } -class AbstractResultOnGlobalOpt - : public AbstractResultOptTemplate< - AbstractResultOnGlobalOpt, fir::impl::AbstractResultOnGlobalOptBase> { -public: void runOnSpecificOperation(fir::GlobalOp global, bool, mlir::RewritePatternSet &, mlir::ConversionTarget &) { @@ -412,14 +359,77 @@ public: TODO(global->getLoc(), "support for procedure pointers"); } } -}; -} // end anonymous namespace -} // namespace fir -std::unique_ptr fir::createAbstractResultOnFuncOptPass() { - return std::make_unique(); -} + /// Run the pass on a ModuleOp. This makes fir-opt --abstract-result work. + void runOnModule() { + mlir::ModuleOp mod = mlir::cast(getOperation()); + + auto pass = std::make_unique(); + pass->copyOptionValuesFrom(this); + mlir::OpPassManager pipeline; + pipeline.addPass(std::unique_ptr{pass.release()}); + + // Run the pass on all operations directly nested inside of the ModuleOp + // we can't just call runOnSpecificOperation here because the pass + // implementation only works when scoped to a particular func.func or + // fir.global + for (mlir::Region ®ion : mod->getRegions()) { + for (mlir::Block &block : region.getBlocks()) { + for (mlir::Operation &op : block.getOperations()) { + if (mlir::failed(runPipeline(pipeline, &op))) { + mlir::emitError(op.getLoc(), "Failed to run abstract result pass"); + signalPassFailure(); + return; + } + } + } + } + } -std::unique_ptr fir::createAbstractResultOnGlobalOptPass() { - return std::make_unique(); -} + void runOnOperation() override { + auto *context = &this->getContext(); + mlir::Operation *op = this->getOperation(); + if (mlir::isa(op)) { + runOnModule(); + return; + } + + mlir::RewritePatternSet patterns(context); + mlir::ConversionTarget target = *context; + const bool shouldBoxResult = this->passResultAsBox.getValue(); + + mlir::TypeSwitch(op) + .Case([&](auto op) { + runOnSpecificOperation(op, shouldBoxResult, patterns, target); + }); + + // Convert the calls and, if needed, the ReturnOp in the function body. + target.addLegalDialect(); + target.addIllegalOp(); + target.addDynamicallyLegalOp([](fir::CallOp call) { + return !hasAbstractResult(call.getFunctionType()); + }); + target.addDynamicallyLegalOp([](fir::AddrOfOp addrOf) { + if (auto funTy = addrOf.getType().dyn_cast()) + return !hasAbstractResult(funTy); + return true; + }); + target.addDynamicallyLegalOp([](fir::DispatchOp dispatch) { + return !hasAbstractResult(dispatch.getFunctionType()); + }); + + patterns.insert>(context, shouldBoxResult); + patterns.insert>(context, shouldBoxResult); + patterns.insert(context); + patterns.insert(context, shouldBoxResult); + if (mlir::failed( + mlir::applyPartialConversion(op, target, std::move(patterns)))) { + mlir::emitError(op->getLoc(), "error in converting abstract results\n"); + this->signalPassFailure(); + } + } +}; + +} // end anonymous namespace +} // namespace fir \ No newline at end of file diff --git a/flang/lib/Optimizer/Transforms/AffinePromotion.cpp b/flang/lib/Optimizer/Transforms/AffinePromotion.cpp index d1831cf1c200cc20a027e960d939aaff260fab95..64531cb1868efe940c30faa35d8d232affd0c503 100644 --- a/flang/lib/Optimizer/Transforms/AffinePromotion.cpp +++ b/flang/lib/Optimizer/Transforms/AffinePromotion.cpp @@ -63,7 +63,7 @@ struct AffineFunctionAnalysis { } // namespace static bool analyzeCoordinate(mlir::Value coordinate, mlir::Operation *op) { - if (auto blockArg = coordinate.dyn_cast()) { + if (auto blockArg = mlir::dyn_cast(coordinate)) { if (isa(blockArg.getOwner()->getParentOp())) return true; LLVM_DEBUG(llvm::dbgs() << "AffineLoopAnalysis: array coordinate is not a " @@ -224,7 +224,7 @@ private: if (auto op = value.getDefiningOp()) if (auto intConstant = op.getValue().dyn_cast()) return toAffineExpr(intConstant.getInt()); - if (auto blockArg = value.dyn_cast()) { + if (auto blockArg = mlir::dyn_cast(value)) { affineArgs.push_back(value); if (isa(blockArg.getOwner()->getParentOp()) || isa(blockArg.getOwner()->getParentOp())) diff --git a/flang/lib/Optimizer/Transforms/ArrayValueCopy.cpp b/flang/lib/Optimizer/Transforms/ArrayValueCopy.cpp index 18ca5711bfea8965eadf1c6dfc36d49e5d1e4206..a08d58383d3a91a7a7e59b7e295d37a17d038c39 100644 --- a/flang/lib/Optimizer/Transforms/ArrayValueCopy.cpp +++ b/flang/lib/Optimizer/Transforms/ArrayValueCopy.cpp @@ -187,7 +187,7 @@ public: LLVM_DEBUG(llvm::dbgs() << "popset: " << *op << '\n'); auto popFn = [&](auto rop) { assert(val && "op must have a result value"); - auto resNum = val.cast().getResultNumber(); + auto resNum = mlir::cast(val).getResultNumber(); llvm::SmallVector results; rop.resultToSourceOps(results, resNum); for (auto u : results) @@ -296,7 +296,7 @@ public: visited.insert(val); // Process a block argument. - if (auto ba = val.dyn_cast()) { + if (auto ba = mlir::dyn_cast(val)) { collectArrayMentionFrom(ba); return; } diff --git a/flang/lib/Semantics/check-allocate.cpp b/flang/lib/Semantics/check-allocate.cpp index a7244e1c58330a5b59f93ea98a2c7227a8ae84eb..b4c5660670579d51b184df1eec5adbf116234acd 100644 --- a/flang/lib/Semantics/check-allocate.cpp +++ b/flang/lib/Semantics/check-allocate.cpp @@ -611,6 +611,20 @@ bool AllocationCheckerHelper::RunChecks(SemanticsContext &context) { return false; } } + if (allocateInfo_.gotPinned) { + std::optional cudaAttr{GetCUDADataAttr(ultimate_)}; + if (!cudaAttr || *cudaAttr != common::CUDADataAttr::Pinned) { + context.Say(name_.source, + "Object in ALLOCATE must have PINNED attribute when PINNED option is specified"_err_en_US); + } + } + if (allocateInfo_.gotStream) { + std::optional cudaAttr{GetCUDADataAttr(ultimate_)}; + if (!cudaAttr || *cudaAttr != common::CUDADataAttr::Device) { + context.Say(name_.source, + "Object in ALLOCATE must have DEVICE attribute when STREAM option is specified"_err_en_US); + } + } return RunCoarrayRelatedChecks(context); } diff --git a/flang/lib/Semantics/check-cuda.cpp b/flang/lib/Semantics/check-cuda.cpp index fb1ebadd3785864acb8c4b3d77023d49f8763220..a9e57de7e2f2b5834255d93b53bb1a671a29c6f9 100644 --- a/flang/lib/Semantics/check-cuda.cpp +++ b/flang/lib/Semantics/check-cuda.cpp @@ -344,6 +344,9 @@ private: [&](const common::Indirection &x) { WarnOnIoStmt(source); }, + [&](const common::Indirection &x) { + Check(x.value()); + }, [&](const auto &x) { if (auto msg{ActionStmtChecker::WhyNotOk(x)}) { context_.Say(source, std::move(*msg)); @@ -369,6 +372,13 @@ private: Check(std::get(eb->t)); } } + void Check(const parser::IfStmt &is) { + const auto &uS{ + std::get>(is.t)}; + CheckUnwrappedExpr( + context_, uS.source, std::get(is.t)); + Check(uS.statement, uS.source); + } void Check(const parser::LoopControl::Bounds &bounds) { Check(bounds.lower); Check(bounds.upper); diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp index 824f1b6053ca392c622186ede62d885789b3759c..6fcee96dd690594206e47de08f85eeaffa2533b0 100644 --- a/flang/lib/Semantics/check-declarations.cpp +++ b/flang/lib/Semantics/check-declarations.cpp @@ -948,17 +948,12 @@ void CheckHelper::CheckObjectEntity( "Component '%s' with ATTRIBUTES(DEVICE) must also be allocatable"_err_en_US, symbol.name()); } - if (IsAssumedSizeArray(symbol)) { - messages_.Say( - "Object '%s' with ATTRIBUTES(DEVICE) may not be assumed size"_err_en_US, - symbol.name()); - } break; case common::CUDADataAttr::Managed: if (!IsAutomatic(symbol) && !IsAllocatable(symbol) && - !details.isDummy()) { + !details.isDummy() && !evaluate::IsExplicitShape(symbol)) { messages_.Say( - "Object '%s' with ATTRIBUTES(MANAGED) must also be allocatable, automatic, or a dummy argument"_err_en_US, + "Object '%s' with ATTRIBUTES(MANAGED) must also be allocatable, automatic, explicit shape, or a dummy argument"_err_en_US, symbol.name()); } break; @@ -1042,9 +1037,10 @@ void CheckHelper::CheckObjectEntity( parser::ToUpperCaseLetters(common::EnumToString(attr))); } } else if (!subpDetails && symbol.owner().kind() != Scope::Kind::Module && - symbol.owner().kind() != Scope::Kind::MainProgram) { + symbol.owner().kind() != Scope::Kind::MainProgram && + symbol.owner().kind() != Scope::Kind::BlockConstruct) { messages_.Say( - "ATTRIBUTES(%s) may apply only to module, host subprogram, or device subprogram data"_err_en_US, + "ATTRIBUTES(%s) may apply only to module, host subprogram, block, or device subprogram data"_err_en_US, parser::ToUpperCaseLetters(common::EnumToString(attr))); } } diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index bafa242a79302a388ba94a8099c92ed11d208298..56653aa74f0cc55552b86319ade416ccb2748cf4 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -2286,6 +2286,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Reduction &x) { CheckReductionTypeList(x); } } + bool OmpStructureChecker::CheckReductionOperators( const parser::OmpClause::Reduction &x) { @@ -2356,6 +2357,16 @@ void OmpStructureChecker::CheckReductionTypeList( if (llvm::omp::nestedReduceWorkshareAllowedSet.test(GetContext().directive)) { CheckSharedBindingInOuterContext(ompObjectList); } + + SymbolSourceMap symbols; + GetSymbolsInObjectList(ompObjectList, symbols); + for (auto &[symbol, source] : symbols) { + if (IsProcedurePointer(*symbol)) { + context_.Say(source, + "A procedure pointer '%s' must not appear in a REDUCTION clause."_err_en_US, + symbol->name()); + } + } } void OmpStructureChecker::CheckIntentInPointerAndDefinable( diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index f4ac7f198d854e4b0664162c21645427ce95ecd9..318687508ff1f5c72846476a6b7cdcd84031fdb8 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -2096,15 +2096,10 @@ Symbol *OmpAttributeVisitor::ResolveOmpCommonBlockName( if (!name) { return nullptr; } - // First check if the Common Block is declared in the current scope - if (auto *cur{GetContext().scope.FindCommonBlock(name->source)}) { - name->symbol = cur; - return cur; - } - // Then check parent scope - if (auto *prev{GetContext().scope.parent().FindCommonBlock(name->source)}) { - name->symbol = prev; - return prev; + if (auto *cb{GetProgramUnitOrBlockConstructContaining(GetContext().scope) + .FindCommonBlock(name->source)}) { + name->symbol = cb; + return cb; } return nullptr; } diff --git a/flang/test/Driver/debug-level.f90 b/flang/test/Driver/debug-level.f90 new file mode 100644 index 0000000000000000000000000000000000000000..bc0aee166e6a3736c7c94c430322ec38aa607fa0 --- /dev/null +++ b/flang/test/Driver/debug-level.f90 @@ -0,0 +1,7 @@ +! RUN: %flang %s -g -c -### 2>&1 | FileCheck %s --check-prefix=FULL +! RUN: %flang %s -g1 -c -### 2>&1 | FileCheck %s --check-prefix=LINE +! RUN: %flang %s -gline-tables-only -c -### 2>&1 | FileCheck %s --check-prefix=LINE + +! LINE: -debug-info-kind=line-tables-only +! FULL: -debug-info-kind=standalone + diff --git a/flang/test/Driver/driver-help-hidden.f90 b/flang/test/Driver/driver-help-hidden.f90 index de2fe3048f993ce3a5e1e45d6ffde6d53cd3c2b9..b5bb0f1c1b25604180097d7d44ddf4299c64257b 100644 --- a/flang/test/Driver/driver-help-hidden.f90 +++ b/flang/test/Driver/driver-help-hidden.f90 @@ -109,7 +109,7 @@ ! CHECK-NEXT: -fxor-operator Enable .XOR. as a synonym of .NEQV. ! CHECK-NEXT: --gcc-install-dir= ! CHECK-NEXT: Use GCC installation in the specified directory. The directory ends with path components like 'lib{,32,64}/gcc{,-cross}/$triple/$version'. Note: executables (e.g. ld) used by the compiler are not overridden by the selected GCC installation -! CHECK-NEXT: --gcc-toolchain= Specify a directory where Clang can find 'include' and 'lib{,32,64}/gcc{,-cross}/$triple/$version'. Clang will use the GCC installation with the largest version +! CHECK-NEXT: --gcc-toolchain= Specify a directory where Flang can find 'lib{,32,64}/gcc{,-cross}/$triple/$version'. Flang will use the GCC installation with the largest version ! CHECK-NEXT: -gline-directives-only Emit debug line info directives only ! CHECK-NEXT: -gline-tables-only Emit debug line number tables only ! CHECK-NEXT: -gpulibc Link the LLVM C Library for GPUs diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90 index b258eb59c1862919baf578fd2987d043660c997e..0b0a493baf07f7e63f291f97ee979c63fd365dbc 100644 --- a/flang/test/Driver/driver-help.f90 +++ b/flang/test/Driver/driver-help.f90 @@ -97,7 +97,7 @@ ! HELP-NEXT: -fxor-operator Enable .XOR. as a synonym of .NEQV. ! HELP-NEXT: --gcc-install-dir= ! HELP-NEXT: Use GCC installation in the specified directory. The directory ends with path components like 'lib{,32,64}/gcc{,-cross}/$triple/$version'. Note: executables (e.g. ld) used by the compiler are not overridden by the selected GCC installation -! HELP-NEXT: --gcc-toolchain= Specify a directory where Clang can find 'include' and 'lib{,32,64}/gcc{,-cross}/$triple/$version'. Clang will use the GCC installation with the largest version +! HELP-NEXT: --gcc-toolchain= Specify a directory where Flang can find 'lib{,32,64}/gcc{,-cross}/$triple/$version'. Flang will use the GCC installation with the largest version ! HELP-NEXT: -gline-directives-only Emit debug line info directives only ! HELP-NEXT: -gline-tables-only Emit debug line number tables only ! HELP-NEXT: -gpulibc Link the LLVM C Library for GPUs diff --git a/flang/test/Driver/mlir-debug-pass-pipeline.f90 b/flang/test/Driver/mlir-debug-pass-pipeline.f90 index 04d432f854ca35b7fe000da10bafd950c8248cc4..ef84cb80ecf1db05d3daae41414ad4bc0f00c640 100644 --- a/flang/test/Driver/mlir-debug-pass-pipeline.f90 +++ b/flang/test/Driver/mlir-debug-pass-pipeline.f90 @@ -72,11 +72,13 @@ end program ! ALL-NEXT: (S) 0 num-dce'd - Number of operations DCE'd ! ALL-NEXT: BoxedProcedurePass -! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func'] +! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction'] ! ALL-NEXT: 'fir.global' Pipeline -! ALL-NEXT: AbstractResultOnGlobalOpt +! ALL-NEXT: AbstractResultOpt ! ALL-NEXT: 'func.func' Pipeline -! ALL-NEXT: AbstractResultOnFuncOpt +! ALL-NEXT: AbstractResultOpt +! ALL-NEXT: 'omp.declare_reduction' Pipeline +! ALL-NEXT: AbstractResultOpt ! ALL-NEXT: CodeGenRewrite ! ALL-NEXT: (S) 0 num-dce'd - Number of operations eliminated diff --git a/flang/test/Driver/mlir-pass-pipeline.f90 b/flang/test/Driver/mlir-pass-pipeline.f90 index cfa0de63cde5e819f8303a6319d03859680133a9..d1ff2869b0a6a94d79ab88276197dc7306ae23ff 100644 --- a/flang/test/Driver/mlir-pass-pipeline.f90 +++ b/flang/test/Driver/mlir-pass-pipeline.f90 @@ -67,11 +67,13 @@ end program ! ALL-NEXT: (S) 0 num-dce'd - Number of operations DCE'd ! ALL-NEXT: BoxedProcedurePass -! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func'] +! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction'] ! ALL-NEXT: 'fir.global' Pipeline -! ALL-NEXT: AbstractResultOnGlobalOpt +! ALL-NEXT: AbstractResultOpt ! ALL-NEXT: 'func.func' Pipeline -! ALL-NEXT: AbstractResultOnFuncOpt +! ALL-NEXT: AbstractResultOpt +! ALL-NEXT: 'omp.declare_reduction' Pipeline +! ALL-NEXT: AbstractResultOpt ! ALL-NEXT: CodeGenRewrite ! ALL-NEXT: (S) 0 num-dce'd - Number of operations eliminated diff --git a/flang/test/Fir/abstract-result-2.fir b/flang/test/Fir/abstract-result-2.fir index 08b723b83059369191f0028c6f110284ea27a080..af13d57476e8c0722efb382f376a75219251194f 100644 --- a/flang/test/Fir/abstract-result-2.fir +++ b/flang/test/Fir/abstract-result-2.fir @@ -1,4 +1,4 @@ -// RUN: fir-opt %s --abstract-result-on-func-opt | FileCheck %s +// RUN: fir-opt %s --abstract-result | FileCheck %s // Check that the attributes are shifted along with their corresponding arguments diff --git a/flang/test/Fir/abstract-results.fir b/flang/test/Fir/abstract-results.fir index 42ff2a5c8eb2a87c8dee3024bfa2861e23c95057..82f1cd33073fd3a6d88e641228aa36bfcaafc578 100644 --- a/flang/test/Fir/abstract-results.fir +++ b/flang/test/Fir/abstract-results.fir @@ -1,10 +1,10 @@ // Test rewrite of functions that return fir.array<>, fir.type<>, fir.box<> to // functions that take an additional argument for the result. -// RUN: fir-opt %s --abstract-result-on-func-opt | FileCheck %s --check-prefix=FUNC-REF -// RUN: fir-opt %s --abstract-result-on-func-opt=abstract-result-as-box | FileCheck %s --check-prefix=FUNC-BOX -// RUN: fir-opt %s --abstract-result-on-global-opt | FileCheck %s --check-prefix=GLOBAL-REF -// RUN: fir-opt %s --abstract-result-on-global-opt=abstract-result-as-box | FileCheck %s --check-prefix=GLOBAL-BOX +// RUN: fir-opt %s --abstract-result | FileCheck %s --check-prefix=FUNC-REF +// RUN: fir-opt %s --abstract-result=abstract-result-as-box | FileCheck %s --check-prefix=FUNC-BOX +// RUN: fir-opt %s --abstract-result | FileCheck %s --check-prefix=GLOBAL-REF +// RUN: fir-opt %s --abstract-result=abstract-result-as-box | FileCheck %s --check-prefix=GLOBAL-BOX // ----------------------- Test declaration rewrite ---------------------------- diff --git a/flang/test/Fir/basic-program.fir b/flang/test/Fir/basic-program.fir index 80d3520bc7f7d401bb3657bed82a4ec38848a3e0..28c597fc918cd7a2c5ea05e04f9dc9917d1dea6e 100644 --- a/flang/test/Fir/basic-program.fir +++ b/flang/test/Fir/basic-program.fir @@ -74,11 +74,13 @@ func.func @_QQmain() { // PASSES-NEXT: (S) 0 num-dce'd - Number of operations DCE'd // PASSES-NEXT: BoxedProcedurePass -// PASSES-NEXT: Pipeline Collection : ['fir.global', 'func.func'] +// PASSES-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction'] // PASSES-NEXT: 'fir.global' Pipeline -// PASSES-NEXT: AbstractResultOnGlobalOpt +// PASSES-NEXT: AbstractResultOpt // PASSES-NEXT: 'func.func' Pipeline -// PASSES-NEXT: AbstractResultOnFuncOpt +// PASSES-NEXT: AbstractResultOpt +// PASSES-NEXT: 'omp.declare_reduction' Pipeline +// PASSES-NEXT: AbstractResultOpt // PASSES-NEXT: CodeGenRewrite // PASSES-NEXT: (S) 0 num-dce'd - Number of operations eliminated diff --git a/flang/test/Fir/non-trivial-procedure-binding-description.f90 b/flang/test/Fir/non-trivial-procedure-binding-description.f90 index 695d7fdfe232d30a49a655d8da2a1188f740a5e2..668928600157b1510c2e0d635bed533d70d03c5a 100644 --- a/flang/test/Fir/non-trivial-procedure-binding-description.f90 +++ b/flang/test/Fir/non-trivial-procedure-binding-description.f90 @@ -1,5 +1,5 @@ ! RUN: %flang_fc1 -emit-mlir %s -o - | FileCheck %s --check-prefix=BEFORE -! RUN: %flang_fc1 -emit-mlir %s -o - | fir-opt --abstract-result-on-global-opt | FileCheck %s --check-prefix=AFTER +! RUN: %flang_fc1 -emit-mlir %s -o - | fir-opt --abstract-result | FileCheck %s --check-prefix=AFTER module a type f contains diff --git a/flang/test/Lower/CUDA/cuda-allocatable.cuf b/flang/test/Lower/CUDA/cuda-allocatable.cuf index 5b10334ecdbc14c7cb79a5918b7d8879daa412a8..251ff16a56c797cf02c38e29bdccc2ad62dfa79e 100644 --- a/flang/test/Lower/CUDA/cuda-allocatable.cuf +++ b/flang/test/Lower/CUDA/cuda-allocatable.cuf @@ -52,19 +52,19 @@ end subroutine ! CHECK: %{{.*}} = fir.cuda_allocate %[[BOX_DECL]]#1 : !fir.ref>>> pinned(%[[PLOG_DECL]]#1 : !fir.ref>) {cuda_attr = #fir.cuda} -> i32 subroutine sub4() - real, allocatable, unified :: a(:) + real, allocatable, device :: a(:) integer :: istream allocate(a(10), stream=istream) end subroutine ! CHECK-LABEL: func.func @_QPsub4() ! CHECK: %[[BOX:.*]] = fir.alloca !fir.box>> {bindc_name = "a", uniq_name = "_QFsub4Ea"} -! CHECK: %[[BOX_DECL:.*]]:2 = hlfir.declare %0 {cuda_attr = #fir.cuda, fortran_attrs = #fir.var_attrs, uniq_name = "_QFsub4Ea"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) +! CHECK: %[[BOX_DECL:.*]]:2 = hlfir.declare %0 {cuda_attr = #fir.cuda, fortran_attrs = #fir.var_attrs, uniq_name = "_QFsub4Ea"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) ! CHECK: %[[ISTREAM:.*]] = fir.alloca i32 {bindc_name = "istream", uniq_name = "_QFsub4Eistream"} ! CHECK: %[[ISTREAM_DECL:.*]]:2 = hlfir.declare %[[ISTREAM]] {uniq_name = "_QFsub4Eistream"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: fir.call @_FortranAAllocatableSetBounds ! CHECK: %[[STREAM:.*]] = fir.load %[[ISTREAM_DECL]]#0 : !fir.ref -! CHECK: %{{.*}} = fir.cuda_allocate %[[BOX_DECL]]#1 : !fir.ref>>> stream(%[[STREAM]] : i32) {cuda_attr = #fir.cuda} -> i32 +! CHECK: %{{.*}} = fir.cuda_allocate %[[BOX_DECL]]#1 : !fir.ref>>> stream(%[[STREAM]] : i32) {cuda_attr = #fir.cuda} -> i32 subroutine sub5() real, allocatable, device :: a(:) diff --git a/flang/test/Lower/CUDA/cuda-kernel-loop-directive.cuf b/flang/test/Lower/CUDA/cuda-kernel-loop-directive.cuf index 6179e609db383c6b6c1037e4d9435baf2f81f0d5..9b728cd19eb552b50d7bb689a34214543cbfa675 100644 --- a/flang/test/Lower/CUDA/cuda-kernel-loop-directive.cuf +++ b/flang/test/Lower/CUDA/cuda-kernel-loop-directive.cuf @@ -1,4 +1,5 @@ ! RUN: bbc -emit-hlfir -fcuda %s -o - | FileCheck %s +! RUN: bbc -emit-hlfir -fcuda %s -o - | fir-opt | FileCheck %s ! Test lowering of CUDA kernel loop directive. diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-max-byref.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-max-byref.f90 index f0979ab95f568ad49bd20b216586e03e9e70996e..80b720e3aac1d10ffefedc61394561d4b14c9eb4 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-max-byref.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-max-byref.f90 @@ -11,7 +11,7 @@ !CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref, %[[ARG1:.*]]: !fir.ref): !CHECK: %[[LD0:.*]] = fir.load %[[ARG0]] : !fir.ref !CHECK: %[[LD1:.*]] = fir.load %[[ARG1]] : !fir.ref -!CHECK: %[[RES:.*]] = arith.maximumf %[[LD0]], %[[LD1]] {{.*}}: f32 +!CHECK: %[[RES:.*]] = arith.maxnumf %[[LD0]], %[[LD1]] {{.*}}: f32 !CHECK: fir.store %[[RES]] to %[[ARG0]] : !fir.ref !CHECK: omp.yield(%[[ARG0]] : !fir.ref) diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-max.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-max.f90 index 996296c2adc2b5b0e389d5e4ecc2841a6dec6b91..c3b821ea5912468c2c10767bca5e5dddf63e3bd2 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-max.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-max.f90 @@ -6,7 +6,7 @@ !CHECK: omp.yield(%[[MINIMUM_VAL_F]] : f32) !CHECK: combiner !CHECK: ^bb0(%[[ARG0_F:.*]]: f32, %[[ARG1_F:.*]]: f32): -!CHECK: %[[COMB_VAL_F:.*]] = arith.maximumf %[[ARG0_F]], %[[ARG1_F]] {{.*}}: f32 +!CHECK: %[[COMB_VAL_F:.*]] = arith.maxnumf %[[ARG0_F]], %[[ARG1_F]] {{.*}}: f32 !CHECK: omp.yield(%[[COMB_VAL_F]] : f32) !CHECK: omp.declare_reduction @[[MAX_DECLARE_I:.*]] : i32 init { diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-min-byref.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-min-byref.f90 index 24aa8e46e5bbbd91a62fa54ec2e8a6ba42cd6dd7..b284f8e5d96721345b20349f869f7caa12947e29 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-min-byref.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-min-byref.f90 @@ -11,7 +11,7 @@ !CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref, %[[ARG1:.*]]: !fir.ref): !CHECK: %[[LD0:.*]] = fir.load %[[ARG0]] : !fir.ref !CHECK: %[[LD1:.*]] = fir.load %[[ARG1]] : !fir.ref -!CHECK: %[[RES:.*]] = arith.minimumf %[[LD0]], %[[LD1]] {{.*}}: f32 +!CHECK: %[[RES:.*]] = arith.minnumf %[[LD0]], %[[LD1]] {{.*}}: f32 !CHECK: fir.store %[[RES]] to %[[ARG0]] : !fir.ref !CHECK: omp.yield(%[[ARG0]] : !fir.ref) diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-min.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-min.f90 index 268f51c9dc9330c360014dad37a7a42bf2d73fb0..ab33e180ed883dee446720b2175f3a9d40cb1f4e 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-min.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-min.f90 @@ -6,7 +6,7 @@ !CHECK: omp.yield(%[[MAXIMUM_VAL_F]] : f32) !CHECK: combiner !CHECK: ^bb0(%[[ARG0_F:.*]]: f32, %[[ARG1_F:.*]]: f32): -!CHECK: %[[COMB_VAL_F:.*]] = arith.minimumf %[[ARG0_F]], %[[ARG1_F]] {{.*}}: f32 +!CHECK: %[[COMB_VAL_F:.*]] = arith.minnumf %[[ARG0_F]], %[[ARG1_F]] {{.*}}: f32 !CHECK: omp.yield(%[[COMB_VAL_F]] : f32) !CHECK: omp.declare_reduction @[[MIN_DECLARE_I:.*]] : i32 init { diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-max-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-max-byref.f90 index ee562bbe15863e0476da7e20bb418516c3a28d9f..2f6921edcb42a5225893915e7663362e94f53f52 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-max-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-max-byref.f90 @@ -13,7 +13,7 @@ !CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref, %[[ARG1:.*]]: !fir.ref): !CHECK: %[[LD0:.*]] = fir.load %[[ARG0]] : !fir.ref !CHECK: %[[LD1:.*]] = fir.load %[[ARG1]] : !fir.ref -!CHECK: %[[RES:.*]] = arith.maximumf %[[LD0]], %[[LD1]] {{.*}}: f32 +!CHECK: %[[RES:.*]] = arith.maxnumf %[[LD0]], %[[LD1]] {{.*}}: f32 !CHECK: fir.store %[[RES]] to %[[ARG0]] : !fir.ref !CHECK: omp.yield(%[[ARG0]] : !fir.ref) diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-max.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-max.f90 index 6f11f0ec96a7d3536ebff20ee90401c61d03cb7d..c9cf5cbf4f8c02d367de1b397b37ac8c6df5742b 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-max.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-max.f90 @@ -10,7 +10,7 @@ ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: f32, %[[VAL_1:.*]]: f32): -! CHECK: %[[VAL_2:.*]] = arith.maximumf %[[VAL_0]], %[[VAL_1]] fastmath : f32 +! CHECK: %[[VAL_2:.*]] = arith.maxnumf %[[VAL_0]], %[[VAL_1]] fastmath : f32 ! CHECK: omp.yield(%[[VAL_2]] : f32) ! CHECK: } diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-min-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-min-byref.f90 index c0372117a03b9db5d93dd22bafbeb1323dc10a5c..84a376b46b8fbe607a650d7a0127fb7c6bc2306b 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-min-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-min-byref.f90 @@ -13,7 +13,7 @@ !CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref, %[[ARG1:.*]]: !fir.ref): !CHECK: %[[LD0:.*]] = fir.load %[[ARG0]] : !fir.ref !CHECK: %[[LD1:.*]] = fir.load %[[ARG1]] : !fir.ref -!CHECK: %[[RES:.*]] = arith.minimumf %[[LD0]], %[[LD1]] {{.*}}: f32 +!CHECK: %[[RES:.*]] = arith.minnumf %[[LD0]], %[[LD1]] {{.*}}: f32 !CHECK: fir.store %[[RES]] to %[[ARG0]] : !fir.ref !CHECK: omp.yield(%[[ARG0]] : !fir.ref) diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-min.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-min.f90 index 2c694f82e279a42689dcb3cfdd82952cfc9db19a..3ba279acd14c41f8d821ea62520a14a8483e70a7 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-min.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-min.f90 @@ -10,7 +10,7 @@ ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: f32, %[[VAL_1:.*]]: f32): -! CHECK: %[[VAL_2:.*]] = arith.minimumf %[[VAL_0]], %[[VAL_1]] fastmath : f32 +! CHECK: %[[VAL_2:.*]] = arith.minnumf %[[VAL_0]], %[[VAL_1]] fastmath : f32 ! CHECK: omp.yield(%[[VAL_2]] : f32) ! CHECK: } diff --git a/flang/test/Parser/cuf-sanity-common b/flang/test/Parser/cuf-sanity-common index 7f4217fb58355d8242acf10be08a035651a349b6..b097a6aa300458d09a7e0f3cc5f5cc2147dd4835 100644 --- a/flang/test/Parser/cuf-sanity-common +++ b/flang/test/Parser/cuf-sanity-common @@ -32,6 +32,6 @@ module m call globalsub<<<1, 2>>> call globalsub<<<1, 2, 3>>> call globalsub<<<1, 2, 3, 4>>> - allocate(pa(32), stream = 1, pinned = isPinned) + allocate(pa(32), pinned = isPinned) end subroutine end module diff --git a/flang/test/Parser/cuf-sanity-tree.CUF b/flang/test/Parser/cuf-sanity-tree.CUF index dc12759d3ce52fa05dfd538e2fc6f09482538f3d..2820441d5b5f0ae4c032a1bc7f64d5c0dfa82067 100644 --- a/flang/test/Parser/cuf-sanity-tree.CUF +++ b/flang/test/Parser/cuf-sanity-tree.CUF @@ -199,8 +199,6 @@ include "cuf-sanity-common" !CHECK: | | | | | | AllocateShapeSpec !CHECK: | | | | | | | Scalar -> Integer -> Expr = '32_4' !CHECK: | | | | | | | | LiteralConstant -> IntLiteralConstant = '32' -!CHECK: | | | | | AllocOpt -> Stream -> Scalar -> Integer -> Expr = '1_4' -!CHECK: | | | | | | LiteralConstant -> IntLiteralConstant = '1' !CHECK: | | | | | AllocOpt -> Pinned -> Scalar -> Logical -> Variable = 'ispinned' !CHECK: | | | | | | Designator -> DataRef -> Name = 'ispinned' !CHECK: | | | EndSubroutineStmt -> diff --git a/flang/test/Parser/cuf-sanity-unparse.CUF b/flang/test/Parser/cuf-sanity-unparse.CUF index 7ac39448d7bd454d3ae826973e38b7bcb6a39ada..b6921e74fc05ae9ab8b17bb74e569162501f81eb 100644 --- a/flang/test/Parser/cuf-sanity-unparse.CUF +++ b/flang/test/Parser/cuf-sanity-unparse.CUF @@ -37,6 +37,6 @@ include "cuf-sanity-common" !CHECK: CALL globalsub<<<1_4,2_4>>>() !CHECK: CALL globalsub<<<1_4,2_4,3_4>>>() !CHECK: CALL globalsub<<<1_4,2_4,3_4,4_4>>>() -!CHECK: ALLOCATE(pa(32_4), STREAM=1_4, PINNED=ispinned) +!CHECK: ALLOCATE(pa(32_4), PINNED=ispinned) !CHECK: END SUBROUTINE !CHECK: END MODULE diff --git a/flang/test/Semantics/OpenMP/reduction12.f90 b/flang/test/Semantics/OpenMP/reduction12.f90 new file mode 100644 index 0000000000000000000000000000000000000000..f896ca4aa60b678437737c78f15caaf3c9017459 --- /dev/null +++ b/flang/test/Semantics/OpenMP/reduction12.f90 @@ -0,0 +1,16 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp + +! OpenMP 5.2: Section 5.5.5 : A procedure pointer must not appear in a +! reduction clause. + + procedure(foo), pointer :: ptr + integer :: i + ptr => foo +!ERROR: A procedure pointer 'ptr' must not appear in a REDUCTION clause. +!$omp do reduction (+ : ptr) + do i = 1, 10 + end do +contains + subroutine foo + end subroutine +end diff --git a/flang/test/Semantics/OpenMP/resolve03.f90 b/flang/test/Semantics/OpenMP/resolve03.f90 index b9306c4fe9cb4dff532dfcaf1f3e51c2a283b4a5..ebc66ca12ebf445ee4c0d1f005fb3d60b36e84d3 100644 --- a/flang/test/Semantics/OpenMP/resolve03.f90 +++ b/flang/test/Semantics/OpenMP/resolve03.f90 @@ -8,6 +8,9 @@ common /c/ a, b integer a(3), b + common /tc/ x + integer x + !$omp threadprivate(/tc/) A = 1 B = 2 @@ -19,4 +22,26 @@ !$omp end parallel end block print *, a, b + + !$omp parallel + block + !$omp single + x = 18 + !ERROR: COMMON block must be declared in the same scoping unit in which the OpenMP directive or clause appears + !$omp end single copyprivate(/tc/) + end block + !$omp end parallel + + ! Common block names may be used inside nested OpenMP directives. + !$omp parallel + !$omp parallel copyin(/tc/) + x = x + 10 + !$omp end parallel + !$omp end parallel + + !$omp parallel + !$omp single + x = 18 + !$omp end single copyprivate(/tc/) + !$omp end parallel end diff --git a/flang/test/Semantics/cuf03.cuf b/flang/test/Semantics/cuf03.cuf index 574add9faaade729b7e39d33bf94f18ba65eee7c..472d53db7462aec119dc594f6e5ced42bec08c3b 100644 --- a/flang/test/Semantics/cuf03.cuf +++ b/flang/test/Semantics/cuf03.cuf @@ -32,14 +32,11 @@ module m real, shared, target :: mst !ERROR: Object 'msa' with ATTRIBUTES(SHARED) must be declared in a device subprogram real, shared :: msa(*) - !ERROR: Object 'mm' with ATTRIBUTES(MANAGED) must also be allocatable, automatic, or a dummy argument - real, managed :: mm - !ERROR: Object 'mmi' with ATTRIBUTES(MANAGED) must also be allocatable, automatic, or a dummy argument - real, managed :: mmi = 1. + real, managed :: mm ! ok + real, managed :: mmi = 1. ! ok real, managed, allocatable :: mml ! ok - !ERROR: Object 'mmp' with ATTRIBUTES(MANAGED) must also be allocatable, automatic, or a dummy argument - real, managed, pointer :: mmp ! ok - !ERROR: Object 'mmt' with ATTRIBUTES(MANAGED) must also be allocatable, automatic, or a dummy argument + !ERROR: Object 'mmp' with ATTRIBUTES(MANAGED) must also be allocatable, automatic, explicit shape, or a dummy argument + real, managed, pointer :: mmp(:) real, managed, target :: mmt !WARNING: Object 'mp' with ATTRIBUTES(PINNED) should also be allocatable real, pinned :: mp @@ -60,8 +57,7 @@ module m contains attributes(device) subroutine devsubr(n,da) integer, intent(in) :: n - !ERROR: Object 'da' with ATTRIBUTES(DEVICE) may not be assumed size - real, device :: da(*) + real, device :: da(*) ! ok real, managed :: ma(n) ! ok !WARNING: Pointer 'dp' may not be associated in a device subprogram real, device, pointer :: dp @@ -85,6 +81,11 @@ module m real, unified :: ru ! ok type(t1), unified :: tu ! ok type(t2) :: t ! ok + + block + real, device :: a(100) ! ok + end block end subroutine + end module diff --git a/flang/test/Semantics/cuf07.cuf b/flang/test/Semantics/cuf07.cuf index b520b5da51264b4e63e746b3b6658cfafa351c6f..c48abb5adf0d41970db447cc0f846a1f986e4661 100644 --- a/flang/test/Semantics/cuf07.cuf +++ b/flang/test/Semantics/cuf07.cuf @@ -23,4 +23,20 @@ module m !BECAUSE: 'ma' is a host-associated allocatable and is not definable in a device subprogram deallocate(ma) end subroutine + + subroutine hostsub() + integer, allocatable, device :: ia(:) + logical :: plog + + !ERROR: Object in ALLOCATE must have PINNED attribute when PINNED option is specified + allocate(ia(100), pinned = plog) + end subroutine + + subroutine host2() + integer, allocatable, pinned :: ia(:) + integer :: istream + + !ERROR: Object in ALLOCATE must have DEVICE attribute when STREAM option is specified + allocate(ia(100), stream = istream) + end subroutine end module diff --git a/flang/test/Semantics/cuf11.cuf b/flang/test/Semantics/cuf11.cuf index de7ff29743242b6cbc4b7c015a152116115a96e0..554ac258e5510189e2cf0bb86227f89c76c5cf69 100644 --- a/flang/test/Semantics/cuf11.cuf +++ b/flang/test/Semantics/cuf11.cuf @@ -30,3 +30,7 @@ logical function compare_h(a,b) !ERROR: 'b' is not an object of derived type; it is implicitly typed compare_h = (a%h .eq. b%h) end + +attributes(global) subroutine sub2() + if (threadIdx%x == 1) print *, "I'm number one" +end subroutine diff --git a/flang/test/Semantics/cuf12.cuf b/flang/test/Semantics/cuf12.cuf new file mode 100644 index 0000000000000000000000000000000000000000..1b79c9889dfeaf0c642843082f120c81972a0f90 --- /dev/null +++ b/flang/test/Semantics/cuf12.cuf @@ -0,0 +1,8 @@ +! RUN: %python %S/test_errors.py %s %flang_fc1 + +program test + real, device :: b(100) ! ok + block + real, device :: a(100) ! ok + end block +end program diff --git a/flang/tools/f18/CMakeLists.txt b/flang/tools/f18/CMakeLists.txt index dda3b6887be89a86271b4c83f90cb06d3af21ea9..64815a1f5da6224714a3f76064258cd836c4cf83 100644 --- a/flang/tools/f18/CMakeLists.txt +++ b/flang/tools/f18/CMakeLists.txt @@ -93,17 +93,6 @@ endif() add_custom_target(module_files ALL DEPENDS ${MODULE_FILES}) -# This flang shell script will only work in a POSIX shell. -if (NOT WIN32) - configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/flang-to-external-fc.in - ${CMAKE_BINARY_DIR}/bin/flang-to-external-fc - @ONLY - ) - add_custom_target(flang-to-external-fc ALL DEPENDS ${CMAKE_BINARY_DIR}/bin/flang-to-external-fc) - install(PROGRAMS ${CMAKE_BINARY_DIR}/bin/flang-to-external-fc DESTINATION "${CMAKE_INSTALL_BINDIR}") -endif() - # TODO Move this to a more suitable location # Copy the generated omp_lib.h header file, if OpenMP support has been configured. if (LLVM_TOOL_OPENMP_BUILD) diff --git a/flang/tools/f18/flang-to-external-fc.in b/flang/tools/f18/flang-to-external-fc.in deleted file mode 100755 index bd16c030121cbb904fcda71d0f5abd0265315f11..0000000000000000000000000000000000000000 --- a/flang/tools/f18/flang-to-external-fc.in +++ /dev/null @@ -1,497 +0,0 @@ -#! /usr/bin/env bash -#===-- tools/f18/flang-to-external-fc.sh --------------------------*- sh -*-===# -# -# 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 -# -#===------------------------------------------------------------------------===# -# A wrapper script for Flang's compiler driver that was developed for testing and -# experimenting. You should be able to use it as a regular compiler driver. It -# will: -# * run Flang's compiler driver to unparse the input source files -# * use the external compiler (defined via FLANG_FC environment variable) to -# compile the unparsed source files -# -# Tested with Bash 4.4. This script will exit immediately if you use an -# older version of Bash. -#===------------------------------------------------------------------------===# -set -euo pipefail - -# Global variables to make the parsing of input arguments a bit easier -INPUT_FILES=() -OPTIONS=() -OUTPUT_FILE="" -MODULE_DIR="" -INTRINSICS_MOD_DIR="" -COMPILE_ONLY="False" -PREPROCESS_ONLY="False" -PRINT_VERSION="False" - -# === check_bash_version ====================================================== -# -# Checks the Bash version that's used to run this script. Exits immediately -# with a non-zero return code if it's lower than 4.4. Otherwise returns 0 -# (success). -# ============================================================================= -check_bash_version() { - message="Error: Your Bash is too old. Please use Bash >= 4.4" - # Major version - [[ "${BASH_VERSINFO[0]:-0}" -lt 4 ]] && echo $message && exit 1 - - # Minor version - if [[ "${BASH_VERSINFO[0]}" == 4 ]]; then - [[ "${BASH_VERSINFO[1]:-0}" -lt 4 ]] && echo $message && exit 1 - fi - - return 0 -} - -# === parse_args ============================================================== -# -# Parse the input arguments passed to this script. Sets the global variables -# declared at the top. -# -# INPUTS: -# $1 - all input arguments -# OUTPUTS: -# Saved in the global variables for this script -# ============================================================================= -parse_args() -{ - while [ "${1:-}" != "" ]; do - # CASE 1: Compiler option - if [[ "${1:0:1}" == "-" ]] ; then - # Output file - extract it into a global variable - if [[ "$1" == "-o" ]] ; then - shift - OUTPUT_FILE="$1" - shift - continue - fi - - # Module directory - extract it into a global variable - if [[ "$1" == "-module-dir" ]]; then - shift - MODULE_DIR="$1" - shift - continue - fi - - # Intrinsics module dir - extract it into a global var - if [[ "$1" == "-intrinsics-module-directory" ]]; then shift - INTRINSICS_MOD_DIR=$1 - shift - continue - fi - - # Module suffix cannot be modified - this script defines it before - # calling the driver. - if [[ "$1" == "-module-suffix" ]]; then - echo "ERROR: \'-module-suffix\' is not available when using the \'flang\' script" - exit 1 - fi - - # Special treatment for `J ` and `-I `. We translate these - # into `J` and `-I` respectively. - if [[ "$1" == "-J" ]] || [[ "$1" == "-I" ]]; then - opt=$1 - shift - OPTIONS+=("$opt$1") - shift - continue - fi - - # This is a regular option - just add it to the list. - OPTIONS+=($1) - if [[ $1 == "-c" ]]; then - COMPILE_ONLY="True" - fi - - if [[ $1 == "-S" ]]; then - COMPILE_ONLY="True" - fi - - if [[ $1 == "-E" ]]; then - PREPROCESS_ONLY="True" - fi - - if [[ $1 == "-v" || $1 == "--version" ]]; then - PRINT_VERSION="True" - fi - - shift - continue - - # CASE 2: A regular file (either source or a library file) - elif [[ -f "$1" ]]; then - INPUT_FILES+=($1) - shift - continue - - else - # CASE 3: Unsupported - echo "ERROR: unrecognised option format: \`$1\`. Perhaps non-existent file?" - exit 1 - fi - done -} - -# === categorise_files ======================================================== -# -# Categorises input files into: -# * Fortran source files (to be compiled) -# * library files (to be linked into the final executable) -# -# INPUTS: -# $1 - all input files to be categorised (array, name reference) -# OUTPUTS: -# $2 - Fortran source files extracted from $1 (array, name reference) -# $3 - other source files extracted from $1 (array, name reference) -# $4 - object files extracted from $1 (array, name reference) -# $5 - lib files extracted from $1 (array, name reference) -# ============================================================================= -categorise_files() -{ - local -n -r all_files=$1 - local -n fortran_sources=$2 - local -n other_sources=$3 - local -n objects=$4 - local -n libs=$5 - - for current_file in "${all_files[@]}"; do - file_ext=${current_file##*.} - if [[ $file_ext == "f" ]] || [[ $file_ext == "f90" ]] || - [[ $file_ext == "f" ]] || [[ $file_ext == "F" ]] || [[ $file_ext == "ff" ]] || - [[ $file_ext == "f90" ]] || [[ $file_ext == "F90" ]] || [[ $file_ext == "ff90" ]] || - [[ $file_ext == "f95" ]] || [[ $file_ext == "F95" ]] || [[ $file_ext == "ff95" ]] || - [[ $file_ext == "cuf" ]] || [[ $file_ext == "CUF" ]] || [[ $file_ext == "f18" ]] || - [[ $file_ext == "F18" ]] || [[ $file_ext == "ff18" ]]; then - fortran_sources+=($current_file) - elif [[ $file_ext == "a" ]] || [[ $file_ext == "so" ]]; then - libs+=($current_file) - elif [[ $file_ext == "o" ]]; then - objects+=($current_file) - else - other_sources+=($current_file) - fi - done -} - -# === categorise_opts ========================================================== -# -# Categorises compiler options into options for: -# * the Flang driver (either new or the "throwaway" driver) -# * the external Fortran driver that will generate the code -# Most options accepted by Flang will be claimed by it. The only exceptions are -# `-I` and `-J`. -# -# INPUTS: -# $1 - all compiler options (array, name reference) -# OUTPUTS: -# $2 - compiler options for the Flang driver (array, name reference) -# $3 - compiler options for the external driver (array, name reference) -# ============================================================================= -categorise_opts() -{ - local -n all_opts=$1 - local -n flang_opts=$2 - local -n fc_opts=$3 - - for opt in "${all_opts[@]}"; do - # These options are claimed by Flang, but should've been dealt with in parse_args. - if [[ $opt == "-module-dir" ]] || - [[ $opt == "-o" ]] || - [[ $opt == "-fintrinsic-modules-path" ]] ; then - echo "ERROR: $opt should've been fully processed by \`parse_args\`" - exit 1 - fi - - if - # The options claimed by Flang. This list needs to be compatible with - # what's supported by Flang's compiler driver (i.e. `flang-new`). - [[ $opt == "-cpp" ]] || - [[ $opt =~ ^-D.* ]] || - [[ $opt == "-E" ]] || - [[ $opt == "-falternative-parameter-statement" ]] || - [[ $opt == "-fbackslash" ]] || - [[ $opt == "-fcolor-diagnostics" ]] || - [[ $opt == "-fdefault-double-8" ]] || - [[ $opt == "-fdefault-integer-8" ]] || - [[ $opt == "-fdefault-real-8" ]] || - [[ $opt == "-ffixed-form" ]] || - [[ $opt =~ ^-ffixed-line-length=.* ]] || - [[ $opt == "-ffree-form" ]] || - [[ $opt == "-fimplicit-none" ]] || - [[ $opt =~ ^-finput-charset=.* ]] || - [[ $opt == "-flarge-sizes" ]] || - [[ $opt == "-flogical-abbreviations" ]] || - [[ $opt == "-fno-color-diagnostics" ]] || - [[ $opt == "-fxor-operator" ]] || - [[ $opt == "-help" ]] || - [[ $opt == "-nocpp" ]] || - [[ $opt == "-pedantic" ]] || - [[ $opt =~ ^-std=.* ]] || - [[ $opt =~ ^-U.* ]] || - [[ $opt == "-Werror" ]]; then - flang_opts+=($opt) - elif - # We translate the following into equivalents understood by `flang-new` - [[ $opt == "-Mfixed" ]] || [[ $opt == "-Mfree" ]]; then - case $opt in - -Mfixed) - flang_opts+=("-ffixed-form") - ;; - - -Mfree) - flang_opts+=("-ffree-form") - ;; - - *) - echo "ERROR: $opt has no equivalent in 'flang-new'" - exit 1 - ;; - esac - elif - # Options that are needed for both Flang and the external driver. - [[ $opt =~ -I.* ]] || - [[ $opt =~ -J.* ]] || - [[ $opt == "-fopenmp" ]] || - [[ $opt == "-fopenacc" ]]; then - flang_opts+=($opt) - fc_opts+=($opt) - else - # All other options are claimed for the external driver. - fc_opts+=($opt) - fi - done -} - -# === get_external_fc_name ==================================================== -# -# Returns the name of external Fortran compiler based on values of -# environment variables. -# ============================================================================= -get_external_fc_name() { - if [[ -v FLANG_FC ]]; then - echo ${FLANG_FC} - elif [[ -v F18_FC ]]; then - # We support F18_FC for backwards compatibility. - echo ${F18_FC} - else - echo gfortran - fi -} - -# === preprocess ============================================================== -# -# Runs the preprocessing. Fortran files are preprocessed using Flang. Other -# files are preprocessed using the external Fortran compiler. -# -# INPUTS: -# $1 - Fortran source files (array, name reference) -# $2 - other source files (array, name reference) -# $3 - compiler flags (array, name reference) -# ============================================================================= -preprocess() { - local -n fortran_srcs=$1 - local -n other_srcs=$2 - local -n opts=$3 - - local ext_fc="$(get_external_fc_name)" - - local -r wd=$(cd "$(dirname "$0")/.." && pwd) - - # Use the provided output file name. - if [[ ! -z ${OUTPUT_FILE:+x} ]]; then - output_definition="-o $OUTPUT_FILE" - fi - - # Preprocess fortran sources using Flang - for idx in "${!fortran_srcs[@]}"; do - if ! "$wd/bin/flang-new" -E "${opts[@]}" "${fortran_srcs[$idx]}" ${output_definition:+$output_definition} - then status=$? - echo flang: in "$PWD", flang-new failed with exit status $status: "$wd/bin/flang-new" "${opts[@]}" "$@" >&2 - exit $status - fi - done - - # Preprocess other sources using Flang - for idx in "${!other_srcs[@]}"; do - if ! $ext_fc -E "${opts[@]}" "${other_srcs[$idx]}" ${output_definition:+$output_definition} - then status=$? - echo flang: in "$PWD", flang-new failed with exit status $status: "$wd/bin/flang-new" "${opts[@]}" "$@" >&2 - exit $status - fi - done -} - -# === get_relocatable_name ====================================================== -# This method generates the name of the output file for the compilation phase -# (triggered with `-c`). If the user of this script is only interested in -# compilation (`flang -c`), use $OUTPUT_FILE provided that it was defined. -# Otherwise, use the usual heuristics: -# * file.f --> file.o -# * file.c --> file.o -# -# INPUTS: -# $1 - input source file for which to generate the output name -# ============================================================================= -get_relocatable_name() { - local -r src_file=$1 - - if [[ $COMPILE_ONLY == "True" ]] && [[ ! -z ${OUTPUT_FILE:+x} ]]; then - out_file="$OUTPUT_FILE" - else - current_ext=${src_file##*.} - new_ext="o" - - out_file=$(basename "${src_file}" "$current_ext")${new_ext} - fi - - echo "$out_file" -} - -# === main ==================================================================== -# Main entry point for this script -# ============================================================================= -main() { - check_bash_version - parse_args "$@" - - if [[ $PRINT_VERSION == "True" ]]; then - echo "flang version @FLANG_VERSION@" - exit 0 - fi - - # Source, object and library files provided by the user - local fortran_source_files=() - local other_source_files=() - local object_files=() - local lib_files=() - categorise_files INPUT_FILES fortran_source_files other_source_files object_files lib_files - - if [[ $PREPROCESS_ONLY == "True" ]]; then - preprocess fortran_source_files other_source_files OPTIONS - exit 0 - fi - - # Options for the Flang driver. - # NOTE: We need `-fc1` to make sure that the frontend driver rather than - # compiler driver is used. We also need to make sure that that's the first - # flag that the driver will see (otherwise it assumes compiler/toolchain - # driver mode). - local flang_options=("-fc1") - # Options for the external Fortran Compiler - local ext_fc_options=() - categorise_opts OPTIONS flang_options ext_fc_options - - local -r wd=$(cd "$(dirname "$0")/.." && pwd) - - # uuidgen is common but not installed by default on some distros - if ! command -v uuidgen &> /dev/null - then - echo "uuidgen is required for generating unparsed file names." - exit 1 - fi - - # STEP 1: Unparse - # Base-name for the unparsed files. These are just temporary files that are - # first generated and then deleted by this script. - # NOTE: We need to make sure that the base-name is unique to every - # invocation. Otherwise we can't use this script in parallel. - local -r unique_id=$(uuidgen | cut -b25-36) - local -r unparsed_file_base="flang_unparsed_file_$unique_id" - - flang_options+=("-module-suffix") - flang_options+=(".f18.mod") - flang_options+=("-fdebug-unparse") - flang_options+=("-fno-analyzed-objects-for-unparse") - - [[ ! -z ${MODULE_DIR} ]] && flang_options+=("-module-dir ${MODULE_DIR}") - [[ ! -z ${INTRINSICS_MOD_DIR} ]] && flang_options+=("-intrinsics-module-directory ${INTRINSICS_MOD_DIR}") - for idx in "${!fortran_source_files[@]}"; do - set +e - "$wd/bin/flang-new" "${flang_options[@]}" "${fortran_source_files[$idx]}" -o "${unparsed_file_base}_${idx}.f90" - ret_status=$? - set -e - if [[ $ret_status != 0 ]]; then - echo flang: in "$PWD", flang-new failed with exit status "$ret_status": "$wd/bin/flang-new" "${flang_options[@]}" "$@" >&2 - exit "$ret_status" - fi - done - - # STEP 2: Compile Fortran Source Files - local ext_fc="$(get_external_fc_name)" - # Temporary object files generated by this script. To be deleted at the end. - local temp_object_files=() - for idx in "${!fortran_source_files[@]}"; do - # We always have to specify the output name with `-o `. This - # is because we are using the unparsed rather than the original source file - # below. As a result, we cannot rely on the compiler-generated output name. - out_obj_file=$(get_relocatable_name "${fortran_source_files[$idx]}") - - set +e - $ext_fc "-c" "${ext_fc_options[@]}" "${unparsed_file_base}_${idx}.f90" "-o" "${out_obj_file}" - ret_status=$? - set -e - if [[ $ret_status != 0 ]]; then - echo flang: in "$PWD", "$ext_fc" failed with exit status "$ret_status": "$ext_fc" "${ext_fc_options[@]}" "$@" >&2 - exit "$ret_status" - fi - temp_object_files+=(${out_obj_file}) - done - - # Delete the unparsed files - for idx in "${!fortran_source_files[@]}"; do - rm "${unparsed_file_base}_${idx}.f90" - done - - # STEP 3: Compile Other Source Files - for idx in "${!other_source_files[@]}"; do - # We always specify the output name with `-o `. The user - # might have used `-o`, but we never add it to $OPTIONS (or - # $ext_fc_options). Hence we need to use `get_relocatable_name`. - out_obj_file=$(get_relocatable_name "${other_source_files[$idx]}") - - set +e - $ext_fc "-c" "${ext_fc_options[@]}" "${other_source_files[${idx}]}" "-o" "${out_obj_file}" - ret_status=$? - set -e - if [[ $ret_status != 0 ]]; then - echo flang: in "$PWD", "$ext_fc" failed with exit status "$ret_status": "$ext_fc" "${ext_fc_options[@]}" "$@" >&2 - exit "$ret_status" - fi - temp_object_files+=(${out_obj_file}) - done - - # STEP 4: Link - if [[ $COMPILE_ONLY == "True" ]]; then - exit 0; - fi - - if [[ ${#temp_object_files[@]} -ge 1 ]] || [[ ${#object_files[@]} -ge 1 ]] ; then - # If $OUTPUT_FILE was specified, use it for the output name. - if [[ ! -z ${OUTPUT_FILE:+x} ]]; then - output_definition="-o $OUTPUT_FILE" - else - output_definition="" - fi - - set +e - $ext_fc "${ext_fc_options[@]}" "${object_files[@]}" "${temp_object_files[@]}" "${lib_files[@]}" ${output_definition:+$output_definition} - ret_status=$? - set -e - if [[ $ret_status != 0 ]]; then - echo flang: in "$PWD", "$ext_fc" failed with exit status "$ret_status": "$ext_fc" "${ext_fc_options[@]}" "$@" >&2 - exit "$ret_status" - fi - fi - - # Delete intermediate object files - for idx in "${!fortran_source_files[@]}"; do - rm "${temp_object_files[$idx]}" - done -} - -main "${@}" diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td index 5fb92a9c299cc3537acd92e953fdcc31e5a968f7..7843513c4d27bb5ba24a4c1081075d4ba56da4e5 100644 --- a/libc/config/linux/api.td +++ b/libc/config/linux/api.td @@ -176,11 +176,12 @@ def PThreadAPI : PublicAPI<"pthread.h"> { "__pthread_tss_dtor_t", "pthread_attr_t", "pthread_condattr_t", + "pthread_key_t", "pthread_mutex_t", "pthread_mutexattr_t", - "pthread_t", - "pthread_key_t", "pthread_once_t", + "pthread_rwlockattr_t", + "pthread_t", ]; } @@ -259,6 +260,7 @@ def SysTypesAPI : PublicAPI<"sys/types.h"> { "pthread_mutex_t", "pthread_mutexattr_t", "pthread_once_t", + "pthread_rwlockattr_t", "pthread_t", "size_t", "ssize_t", diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 2d8136536b218b145e7cf5325e9ec61c983044b2..a8e289927667121045a32150cf53b9faa8702cfc 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -669,6 +669,10 @@ if(LLVM_LIBC_FULL_BUILD) libc.src.pthread.pthread_mutexattr_setrobust libc.src.pthread.pthread_mutexattr_settype libc.src.pthread.pthread_once + libc.src.pthread.pthread_rwlockattr_destroy + libc.src.pthread.pthread_rwlockattr_getpshared + libc.src.pthread.pthread_rwlockattr_init + libc.src.pthread.pthread_rwlockattr_setpshared libc.src.pthread.pthread_setspecific # sched.h entrypoints diff --git a/libc/docs/contributing.rst b/libc/docs/contributing.rst index b92575ed4108f57a3ff49d5a9af65f6475f04100..bd7d9d79be57d72594f5110de124366ca9544ec8 100644 --- a/libc/docs/contributing.rst +++ b/libc/docs/contributing.rst @@ -9,6 +9,14 @@ to the libc project should also follow the general LLVM `contribution guidelines `_. Below is a list of open projects that one can start with: +#. **Beginner Bugs** - Help us tackle + `good first issues `__. + These bugs have been tagged with the github labels "libc" and "good first + issue" by the team as potentially easier places to get started. Please do + first check if the bug has an assignee; if so please find another unless + there's been no movement on the issue from the assignee, in which place do + ask if you can help take over. + #. **Cleanup code-style** - The libc project follows the general `LLVM style `_ but differs in a few aspects: We use ``snake_case`` for non-constant variable and function diff --git a/libc/docs/dev/code_style.rst b/libc/docs/dev/code_style.rst index ee4e4257c9fa8880068119ca293a363b93df6c2e..170ef6598a9d8e4661317c240df78d679c608079 100644 --- a/libc/docs/dev/code_style.rst +++ b/libc/docs/dev/code_style.rst @@ -219,3 +219,44 @@ defines. Code under ``libc/src/`` should ``#include`` a proxy header from ``hdr/``, which contains a guard on ``LLVM_LIBC_FULL_BUILD`` to either include our header from ``libc/include/`` (fullbuild) or the corresponding underlying system header (overlay). + +Policy on Assembly sources +========================== + +Coding in high level languages such as C++ provides benefits relative to low +level languages like Assembly, such as: + +* Improved safety +* Compile time diagnostics +* Instrumentation + + * Code coverage + * Profile collection +* Sanitization +* Automatic generation of debug info + +While it's not impossible to have Assembly code that correctly provides all of +the above, we do not wish to maintain such Assembly sources in llvm-libc. + +That said, there are a few functions provided by llvm-libc that are impossible +to reliably implement in C++ for all compilers supported for building +llvm-libc. + +We do use inline or out-of-line Assembly in an intentionally minimal set of +places; typically places where the stack or individual register state must be +manipulated very carefully for correctness, or instances where a specific +instruction sequence does not have a corresponding compiler builtin function +today. + +Contributions adding functions implemented purely in Assembly for performance +are not welcome. + +Contributors should strive to stick with C++ for as long as it remains +reasonable to do so. Ideally, bugs should be filed against compiler vendors, +and links to those bug reports should appear in commit messages or comments +that seek to add Assembly to llvm-libc. + +Patches containing any amount of Assembly ideally should be approved by 2 +maintainers. llvm-libc maintainers reserve the right to reject Assembly +contributions that they feel could be better maintained if rewritten in C++, +and to revisit this policy in the future. diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt index f5ba2791af3fb8fb4b0fdb4e6e339f33bf89c911..aeef46aabfce5cfb8ee715911461ddb2a1e86ebf 100644 --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -322,11 +322,12 @@ add_gen_header( .llvm-libc-types.__pthread_tss_dtor_t .llvm-libc-types.pthread_attr_t .llvm-libc-types.pthread_condattr_t + .llvm-libc-types.pthread_key_t .llvm-libc-types.pthread_mutex_t .llvm-libc-types.pthread_mutexattr_t - .llvm-libc-types.pthread_t - .llvm-libc-types.pthread_key_t .llvm-libc-types.pthread_once_t + .llvm-libc-types.pthread_rwlockattr_t + .llvm-libc-types.pthread_t ) add_gen_header( diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt index f26fc0729dc94cbca0c3c70cacd370a3e90878a5..310374fb62ffe05748c9fd2f29efda5d478ecca8 100644 --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -54,6 +54,7 @@ add_header(pthread_key_t HDR pthread_key_t.h) add_header(pthread_mutex_t HDR pthread_mutex_t.h DEPENDS .__futex_word .__mutex_type) add_header(pthread_mutexattr_t HDR pthread_mutexattr_t.h) add_header(pthread_once_t HDR pthread_once_t.h DEPENDS .__futex_word) +add_header(pthread_rwlockattr_t HDR pthread_rwlockattr_t.h) add_header(pthread_t HDR pthread_t.h DEPENDS .__thread_type) add_header(rlim_t HDR rlim_t.h) add_header(time_t HDR time_t.h) diff --git a/libc/include/llvm-libc-types/pthread_rwlockattr_t.h b/libc/include/llvm-libc-types/pthread_rwlockattr_t.h new file mode 100644 index 0000000000000000000000000000000000000000..a63de4f7b438c11d13737768ca492694282001e3 --- /dev/null +++ b/libc/include/llvm-libc-types/pthread_rwlockattr_t.h @@ -0,0 +1,15 @@ +//===-- Definition of pthread_rwlockattr_t type ---------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_LIBC_TYPES_PTHREAD_RWLOCKATTR_T_H +#define LLVM_LIBC_TYPES_PTHREAD_RWLOCKATTR_T_H + +typedef struct { + int pshared; +} pthread_rwlockattr_t; + +#endif // LLVM_LIBC_TYPES_PTHREAD_RWLOCKATTR_T_H diff --git a/libc/spec/posix.td b/libc/spec/posix.td index 0c88dbd848a3fb99e03b07d03450621114a66bbd..d428d54e32a331deceb6d9eaa0ee63699e3f3973 100644 --- a/libc/spec/posix.td +++ b/libc/spec/posix.td @@ -110,6 +110,10 @@ def POSIX : StandardSpec<"POSIX"> { PtrType PThreadCondAttrTPtr = PtrType; ConstType ConstRestrictedPThreadCondAttrTPtr = ConstType>; + NamedType PThreadRWLockAttrTType = NamedType<"pthread_rwlockattr_t">; + PtrType PThreadRWLockAttrTPtr = PtrType; + ConstType ConstPThreadRWLockAttrTPtr = ConstType; + NamedType PThreadMutexAttrTType = NamedType<"pthread_mutexattr_t">; PtrType PThreadMutexAttrTPtr = PtrType; RestrictedPtrType RestrictedPThreadMutexAttrTPtr = RestrictedPtrType; @@ -993,6 +997,7 @@ def POSIX : StandardSpec<"POSIX"> { PThreadMutexTType, PThreadOnceCallback, PThreadOnceT, + PThreadRWLockAttrTType, PThreadStartT, PThreadTSSDtorT, PThreadTType, @@ -1219,6 +1224,26 @@ def POSIX : StandardSpec<"POSIX"> { RetValSpec, [ArgSpec, ArgSpec] >, + FunctionSpec< + "pthread_rwlockattr_destroy", + RetValSpec, + [ArgSpec] + >, + FunctionSpec< + "pthread_rwlockattr_getpshared", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "pthread_rwlockattr_init", + RetValSpec, + [ArgSpec] + >, + FunctionSpec< + "pthread_rwlockattr_setpshared", + RetValSpec, + [ArgSpec, ArgSpec] + >, ] >; @@ -1575,6 +1600,7 @@ def POSIX : StandardSpec<"POSIX"> { PThreadMutexAttrTType, PThreadMutexTType, PThreadOnceT, + PThreadRWLockAttrTType, PThreadTType, PidT, SSizeTType, diff --git a/libc/src/__support/FPUtil/FEnvImpl.h b/libc/src/__support/FPUtil/FEnvImpl.h index 4be1a57f0f4b38f61f0f3d124635546074638ff0..13e668becc651a57c39da566940fcc9cf52c8263 100644 --- a/libc/src/__support/FPUtil/FEnvImpl.h +++ b/libc/src/__support/FPUtil/FEnvImpl.h @@ -9,11 +9,12 @@ #ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FENVIMPL_H #define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FENVIMPL_H +#include "hdr/fenv_macros.h" #include "hdr/math_macros.h" +#include "hdr/types/fenv_t.h" #include "src/__support/macros/attributes.h" // LIBC_INLINE #include "src/__support/macros/properties/architectures.h" #include "src/errno/libc_errno.h" -#include #if defined(LIBC_TARGET_ARCH_IS_AARCH64) #if defined(__APPLE__) diff --git a/libc/src/__support/FPUtil/riscv/FEnvImpl.h b/libc/src/__support/FPUtil/riscv/FEnvImpl.h index 6e940453f7a94dbfd5c6a30fd216ab66b6f8d5c9..e7aee3ba4b910993289aef4a3e5eaaf0f8c9c267 100644 --- a/libc/src/__support/FPUtil/riscv/FEnvImpl.h +++ b/libc/src/__support/FPUtil/riscv/FEnvImpl.h @@ -15,7 +15,6 @@ #include "src/__support/macros/attributes.h" // For LIBC_INLINE_ASM #include "src/__support/macros/config.h" // For LIBC_INLINE -#include #include namespace LIBC_NAMESPACE { diff --git a/libc/src/pthread/CMakeLists.txt b/libc/src/pthread/CMakeLists.txt index 3d6cf6dde010b1d776e9278a9dc769812b7d7ad5..c57475c9114fa61182453471160d35b0434b2b92 100644 --- a/libc/src/pthread/CMakeLists.txt +++ b/libc/src/pthread/CMakeLists.txt @@ -460,6 +460,47 @@ add_entrypoint_object( libc.src.__support.threads.thread ) +add_entrypoint_object( + pthread_rwlockattr_destroy + SRCS + pthread_rwlockattr_destroy.cpp + HDRS + pthread_rwlockattr_destroy.h + DEPENDS + libc.include.pthread +) + +add_entrypoint_object( + pthread_rwlockattr_getpshared + SRCS + pthread_rwlockattr_getpshared.cpp + HDRS + pthread_rwlockattr_getpshared.h + DEPENDS + libc.include.pthread +) + +add_entrypoint_object( + pthread_rwlockattr_init + SRCS + pthread_rwlockattr_init.cpp + HDRS + pthread_rwlockattr_init.h + DEPENDS + libc.include.pthread +) + +add_entrypoint_object( + pthread_rwlockattr_setpshared + SRCS + pthread_rwlockattr_setpshared.cpp + HDRS + pthread_rwlockattr_setpshared.h + DEPENDS + libc.include.pthread + libc.include.errno +) + add_entrypoint_object( pthread_once SRCS diff --git a/libc/src/pthread/pthread_rwlockattr_destroy.cpp b/libc/src/pthread/pthread_rwlockattr_destroy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e3ca75112f0ef474cebc103f89dd9870cdb8cd54 --- /dev/null +++ b/libc/src/pthread/pthread_rwlockattr_destroy.cpp @@ -0,0 +1,24 @@ +//===-- Implementation of the pthread_rwlockattr_destroy ------------------===// +// +// 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 "pthread_rwlockattr_destroy.h" + +#include "src/__support/common.h" + +#include // pthread_rwlockattr_t + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(int, pthread_rwlockattr_destroy, + (pthread_rwlockattr_t * attr [[gnu::unused]])) { + // Initializing a pthread_rwlockattr_t acquires no resources, so this is a + // no-op. + return 0; +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/pthread/pthread_rwlockattr_destroy.h b/libc/src/pthread/pthread_rwlockattr_destroy.h new file mode 100644 index 0000000000000000000000000000000000000000..5904d6b0041873db7b1d5796d7c90811a73b291b --- /dev/null +++ b/libc/src/pthread/pthread_rwlockattr_destroy.h @@ -0,0 +1,20 @@ +//===-- Implementation header for pthread_rwlockattr_destroy ----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_DESTROY_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_DESTROY_H + +#include + +namespace LIBC_NAMESPACE { + +int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_DESTROY_H diff --git a/libc/src/pthread/pthread_rwlockattr_getpshared.cpp b/libc/src/pthread/pthread_rwlockattr_getpshared.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0dad230a2bde26308c3c24379a9f17d710b43795 --- /dev/null +++ b/libc/src/pthread/pthread_rwlockattr_getpshared.cpp @@ -0,0 +1,23 @@ +//===-- Implementation of the pthread_rwlockattr_getpshared ---------------===// +// +// 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 "pthread_rwlockattr_getpshared.h" + +#include "src/__support/common.h" + +#include // pthread_rwlockattr_t + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(int, pthread_rwlockattr_getpshared, + (const pthread_rwlockattr_t *attr, int *pshared)) { + *pshared = attr->pshared; + return 0; +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/pthread/pthread_rwlockattr_getpshared.h b/libc/src/pthread/pthread_rwlockattr_getpshared.h new file mode 100644 index 0000000000000000000000000000000000000000..64843e59aae6973767e79ce7578ed4544337aef3 --- /dev/null +++ b/libc/src/pthread/pthread_rwlockattr_getpshared.h @@ -0,0 +1,21 @@ +//===-- Implementation header for pthread_rwlockattr_getpshared -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_GETPSHARED_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_GETPSHARED_H + +#include + +namespace LIBC_NAMESPACE { + +int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, + int *pshared); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_GETPSHARED_H diff --git a/libc/src/pthread/pthread_rwlockattr_init.cpp b/libc/src/pthread/pthread_rwlockattr_init.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7971f1714db48455d61fac0fa322160d6f933100 --- /dev/null +++ b/libc/src/pthread/pthread_rwlockattr_init.cpp @@ -0,0 +1,23 @@ +//===-- Implementation of the pthread_rwlockattr_init ---------------------===// +// +// 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 "pthread_rwlockattr_init.h" + +#include "src/__support/common.h" + +#include // pthread_rwlockattr_t, PTHREAD_PROCESS_PRIVATE + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(int, pthread_rwlockattr_init, + (pthread_rwlockattr_t * attr)) { + attr->pshared = PTHREAD_PROCESS_PRIVATE; + return 0; +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/pthread/pthread_rwlockattr_init.h b/libc/src/pthread/pthread_rwlockattr_init.h new file mode 100644 index 0000000000000000000000000000000000000000..30ae499fb65dc50c1e3d1ead2979471ec39f1c01 --- /dev/null +++ b/libc/src/pthread/pthread_rwlockattr_init.h @@ -0,0 +1,20 @@ +//===-- Implementation header for pthread_rwlockattr_init ----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_INIT_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_INIT_H + +#include + +namespace LIBC_NAMESPACE { + +int pthread_rwlockattr_init(pthread_rwlockattr_t *attr); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_INIT_H diff --git a/libc/src/pthread/pthread_rwlockattr_setpshared.cpp b/libc/src/pthread/pthread_rwlockattr_setpshared.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6bcba7c1b493556a5101ac55c863fd496404b8df --- /dev/null +++ b/libc/src/pthread/pthread_rwlockattr_setpshared.cpp @@ -0,0 +1,27 @@ +//===-- Implementation of the pthread_rwlockattr_setpshared ---------------===// +// +// 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 "pthread_rwlockattr_setpshared.h" + +#include "src/__support/common.h" + +#include // EINVAL +#include // pthread_rwlockattr_t, PTHREAD_PROCESS_SHARED, PTHREAD_PROCESS_PRIVATE + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(int, pthread_rwlockattr_setpshared, + (pthread_rwlockattr_t * attr, int pshared)) { + if (pshared != PTHREAD_PROCESS_SHARED && pshared != PTHREAD_PROCESS_PRIVATE) + return EINVAL; + + attr->pshared = pshared; + return 0; +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/pthread/pthread_rwlockattr_setpshared.h b/libc/src/pthread/pthread_rwlockattr_setpshared.h new file mode 100644 index 0000000000000000000000000000000000000000..393c07d1eecbc5ad92fc663faef8d6302a689a44 --- /dev/null +++ b/libc/src/pthread/pthread_rwlockattr_setpshared.h @@ -0,0 +1,20 @@ +//===-- Implementation header for pthread_rwlockattr_setpshared -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_SETPSHARED_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_SETPSHARED_H + +#include + +namespace LIBC_NAMESPACE { + +int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_SETPSHARED_H diff --git a/libc/src/stdlib/bsearch.h b/libc/src/stdlib/bsearch.h index 1de7e051ff6c41abb73541e4fe73bbf08e4a3696..3590198ba55704f804651bd0823529b15de1f24b 100644 --- a/libc/src/stdlib/bsearch.h +++ b/libc/src/stdlib/bsearch.h @@ -9,7 +9,7 @@ #ifndef LLVM_LIBC_SRC_STDLIB_BSEARCH_H #define LLVM_LIBC_SRC_STDLIB_BSEARCH_H -#include +#include // size_t namespace LIBC_NAMESPACE { diff --git a/libc/test/src/pthread/CMakeLists.txt b/libc/test/src/pthread/CMakeLists.txt index 51954a5babd2c589747647a9fdfe1996c086f224..ea75e65f57c9eb8a0ecd1b02284ea57b9c6fb180 100644 --- a/libc/test/src/pthread/CMakeLists.txt +++ b/libc/test/src/pthread/CMakeLists.txt @@ -47,13 +47,28 @@ add_libc_unittest( SRCS pthread_condattr_test.cpp DEPENDS - libc.include.errno + libc.include.llvm-libc-macros.generic_error_number_macros + libc.include.llvm-libc-macros.time_macros libc.include.pthread - libc.include.time libc.src.pthread.pthread_condattr_destroy libc.src.pthread.pthread_condattr_getclock libc.src.pthread.pthread_condattr_getpshared libc.src.pthread.pthread_condattr_init libc.src.pthread.pthread_condattr_setclock libc.src.pthread.pthread_condattr_setpshared - ) +) + +add_libc_unittest( + pthread_rwlockattr_test + SUITE + libc_pthread_unittests + SRCS + pthread_rwlockattr_test.cpp + DEPENDS + libc.include.errno + libc.include.pthread + libc.src.pthread.pthread_rwlockattr_destroy + libc.src.pthread.pthread_rwlockattr_getpshared + libc.src.pthread.pthread_rwlockattr_init + libc.src.pthread.pthread_rwlockattr_setpshared +) diff --git a/libc/test/src/pthread/pthread_condattr_test.cpp b/libc/test/src/pthread/pthread_condattr_test.cpp index accb62de92e45ff9a802089a8374d8603bac6106..5fcdbd99cb0e203d8074ddb09b1f4fcf37b12e37 100644 --- a/libc/test/src/pthread/pthread_condattr_test.cpp +++ b/libc/test/src/pthread/pthread_condattr_test.cpp @@ -6,16 +6,23 @@ // //===----------------------------------------------------------------------===// +#include "include/llvm-libc-macros/generic-error-number-macros.h" // EINVAL +#include "include/llvm-libc-macros/time-macros.h" // CLOCK_REALTIME, CLOCK_MONOTONIC +#include "src/pthread/pthread_condattr_destroy.h" +#include "src/pthread/pthread_condattr_getclock.h" +#include "src/pthread/pthread_condattr_getpshared.h" +#include "src/pthread/pthread_condattr_init.h" +#include "src/pthread/pthread_condattr_setclock.h" +#include "src/pthread/pthread_condattr_setpshared.h" #include "test/UnitTest/Test.h" -#include -#include -#include +// TODO: https://github.com/llvm/llvm-project/issues/88997 +#include // PTHREAD_PROCESS_PRIVATE, PTHREAD_PROCESS_SHARED TEST(LlvmLibcPThreadCondAttrTest, InitAndDestroy) { pthread_condattr_t cond; - ASSERT_EQ(pthread_condattr_init(&cond), 0); - ASSERT_EQ(pthread_condattr_destroy(&cond), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_condattr_init(&cond), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_condattr_destroy(&cond), 0); } TEST(LlvmLibcPThreadCondAttrTest, GetDefaultValues) { @@ -26,12 +33,12 @@ TEST(LlvmLibcPThreadCondAttrTest, GetDefaultValues) { // Invalid value. int pshared = 42; - ASSERT_EQ(pthread_condattr_init(&cond), 0); - ASSERT_EQ(pthread_condattr_getclock(&cond, &clock), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_condattr_init(&cond), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_condattr_getclock(&cond, &clock), 0); ASSERT_EQ(clock, CLOCK_REALTIME); - ASSERT_EQ(pthread_condattr_getpshared(&cond, &pshared), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_condattr_getpshared(&cond, &pshared), 0); ASSERT_EQ(pshared, PTHREAD_PROCESS_PRIVATE); - ASSERT_EQ(pthread_condattr_destroy(&cond), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_condattr_destroy(&cond), 0); } TEST(LlvmLibcPThreadCondAttrTest, SetGoodValues) { @@ -42,14 +49,17 @@ TEST(LlvmLibcPThreadCondAttrTest, SetGoodValues) { // Invalid value. int pshared = 42; - ASSERT_EQ(pthread_condattr_init(&cond), 0); - ASSERT_EQ(pthread_condattr_setclock(&cond, CLOCK_MONOTONIC), 0); - ASSERT_EQ(pthread_condattr_getclock(&cond, &clock), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_condattr_init(&cond), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_condattr_setclock(&cond, CLOCK_MONOTONIC), + 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_condattr_getclock(&cond, &clock), 0); ASSERT_EQ(clock, CLOCK_MONOTONIC); - ASSERT_EQ(pthread_condattr_setpshared(&cond, PTHREAD_PROCESS_SHARED), 0); - ASSERT_EQ(pthread_condattr_getpshared(&cond, &pshared), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_condattr_setpshared(&cond, + PTHREAD_PROCESS_SHARED), + 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_condattr_getpshared(&cond, &pshared), 0); ASSERT_EQ(pshared, PTHREAD_PROCESS_SHARED); - ASSERT_EQ(pthread_condattr_destroy(&cond), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_condattr_destroy(&cond), 0); } TEST(LlvmLibcPThreadCondAttrTest, SetBadValues) { @@ -60,12 +70,13 @@ TEST(LlvmLibcPThreadCondAttrTest, SetBadValues) { // Invalid value. int pshared = 42; - ASSERT_EQ(pthread_condattr_init(&cond), 0); - ASSERT_EQ(pthread_condattr_setclock(&cond, clock), EINVAL); - ASSERT_EQ(pthread_condattr_getclock(&cond, &clock), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_condattr_init(&cond), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_condattr_setclock(&cond, clock), EINVAL); + ASSERT_EQ(LIBC_NAMESPACE::pthread_condattr_getclock(&cond, &clock), 0); ASSERT_EQ(clock, CLOCK_REALTIME); - ASSERT_EQ(pthread_condattr_setpshared(&cond, pshared), EINVAL); - ASSERT_EQ(pthread_condattr_getpshared(&cond, &pshared), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_condattr_setpshared(&cond, pshared), + EINVAL); + ASSERT_EQ(LIBC_NAMESPACE::pthread_condattr_getpshared(&cond, &pshared), 0); ASSERT_EQ(pshared, PTHREAD_PROCESS_PRIVATE); - ASSERT_EQ(pthread_condattr_destroy(&cond), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_condattr_destroy(&cond), 0); } diff --git a/libc/test/src/pthread/pthread_rwlockattr_test.cpp b/libc/test/src/pthread/pthread_rwlockattr_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6e5ae70df7343f1ffc799c3ab66b24a8086cfc5e --- /dev/null +++ b/libc/test/src/pthread/pthread_rwlockattr_test.cpp @@ -0,0 +1,64 @@ +//===-- Unittests for pthread_rwlockattr_t --------------------------------===// +// +// 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 "include/llvm-libc-macros/generic-error-number-macros.h" // EINVAL +#include "src/pthread/pthread_rwlockattr_destroy.h" +#include "src/pthread/pthread_rwlockattr_getpshared.h" +#include "src/pthread/pthread_rwlockattr_init.h" +#include "src/pthread/pthread_rwlockattr_setpshared.h" +#include "test/UnitTest/Test.h" + +// TODO: https://github.com/llvm/llvm-project/issues/88997 +#include // PTHREAD_PROCESS_PRIVATE, PTHREAD_PROCESS_SHARED + +TEST(LlvmLibcPThreadRWLockAttrTest, InitAndDestroy) { + pthread_rwlockattr_t attr; + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_init(&attr), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_destroy(&attr), 0); +} + +TEST(LlvmLibcPThreadRWLockAttrTest, GetDefaultValues) { + pthread_rwlockattr_t attr; + + // Invalid value. + int pshared = 42; + + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_init(&attr), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_getpshared(&attr, &pshared), 0); + ASSERT_EQ(pshared, PTHREAD_PROCESS_PRIVATE); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_destroy(&attr), 0); +} + +TEST(LlvmLibcPThreadRWLockAttrTest, SetGoodValues) { + pthread_rwlockattr_t attr; + + // Invalid value. + int pshared = 42; + + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_init(&attr), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_setpshared( + &attr, PTHREAD_PROCESS_SHARED), + 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_getpshared(&attr, &pshared), 0); + ASSERT_EQ(pshared, PTHREAD_PROCESS_SHARED); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_destroy(&attr), 0); +} + +TEST(LlvmLibcPThreadRWLockAttrTest, SetBadValues) { + pthread_rwlockattr_t attr; + + // Invalid value. + int pshared = 42; + + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_init(&attr), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_setpshared(&attr, pshared), + EINVAL); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_getpshared(&attr, &pshared), 0); + ASSERT_EQ(pshared, PTHREAD_PROCESS_PRIVATE); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_destroy(&attr), 0); +} diff --git a/libclc/cmake/modules/AddLibclc.cmake b/libclc/cmake/modules/AddLibclc.cmake index 5e09cde8035c2700be61e9b23b537c64c5028710..bbedc244a72899534a3e08b4592b3c30e5e5bd4d 100644 --- a/libclc/cmake/modules/AddLibclc.cmake +++ b/libclc/cmake/modules/AddLibclc.cmake @@ -39,6 +39,10 @@ function(compile_to_bc) set( TARGET_ARG "-target" ${ARG_TRIPLE} ) endif() + # Ensure the directory we are told to output to exists + get_filename_component( ARG_OUTPUT_DIR ${ARG_OUTPUT} DIRECTORY ) + file( MAKE_DIRECTORY ${ARG_OUTPUT_DIR} ) + add_custom_command( OUTPUT ${ARG_OUTPUT}${TMP_SUFFIX} COMMAND libclc::clang diff --git a/libcxx/.clang-format b/libcxx/.clang-format index c37ab817bca906a8b1076aebd1753e7b2bc10371..871920f15b5bc9ca60895393f679926cdbab99ee 100644 --- a/libcxx/.clang-format +++ b/libcxx/.clang-format @@ -44,7 +44,6 @@ AttributeMacros: [ '_LIBCPP_NO_SANITIZE', '_LIBCPP_NO_UNIQUE_ADDRESS', '_LIBCPP_NOALIAS', - '_LIBCPP_NODISCARD_EXT', '_LIBCPP_NODISCARD', '_LIBCPP_NORETURN', '_LIBCPP_OVERRIDABLE_FUNC_VIS', diff --git a/libcxx/docs/ReleaseNotes/19.rst b/libcxx/docs/ReleaseNotes/19.rst index 53cc7a77d1af48675d0f07a4bcfdac24ff4eabbc..b466b4cd8140cb369cf5b91230356f3ba9372f8c 100644 --- a/libcxx/docs/ReleaseNotes/19.rst +++ b/libcxx/docs/ReleaseNotes/19.rst @@ -79,6 +79,10 @@ Deprecations and Removals in language modes prior to C++20. If you are using these features prior to C++20, please update to ``-std=c++20``. In LLVM 20, the C++20 synchronization library will be removed entirely in language modes prior to C++20. +- ``_LIBCPP_DISABLE_NODISCARD_EXT`` has been removed. ``[[nodiscard]]`` applications are now unconditional. + This decision is based on LEWGs discussion on `P3122 ` and `P3162 ` + to not use ``[[nodiscard]]`` in the standard. + - TODO: The ``LIBCXX_ENABLE_ASSERTIONS`` CMake variable that was used to enable the safe mode has been deprecated and setting it triggers an error; use the ``LIBCXX_HARDENING_MODE`` CMake variable with the value ``extensive`` instead. Similarly, the ``_LIBCPP_ENABLE_ASSERTIONS`` macro has been deprecated (setting it to ``1`` still enables the extensive mode in diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst index 8f945656de1ca658ada6ed6ed1e8fe8058ec3a9c..e7aaf4e1fbcf9cc23c567cd98d52a249896553e1 100644 --- a/libcxx/docs/UsingLibcxx.rst +++ b/libcxx/docs/UsingLibcxx.rst @@ -196,10 +196,6 @@ safety annotations. replacement scenarios from working, e.g. replacing `operator new` and expecting a non-replaced `operator new[]` to call the replaced `operator new`. -**_LIBCPP_DISABLE_NODISCARD_EXT**: - This macro disables library-extensions of ``[[nodiscard]]``. - See :ref:`Extended Applications of [[nodiscard]] ` for more information. - **_LIBCPP_DISABLE_DEPRECATION_WARNINGS**: This macro disables warnings when using deprecated components. For example, using `std::auto_ptr` when compiling in C++11 mode will normally trigger a @@ -279,29 +275,6 @@ Libc++ Extensions This section documents various extensions provided by libc++, how they're provided, and any information regarding how to use them. -.. _nodiscard extension: - -Extended applications of ``[[nodiscard]]`` ------------------------------------------- - -The ``[[nodiscard]]`` attribute is intended to help users find bugs where -function return values are ignored when they shouldn't be. After C++17 the -C++ standard has started to declared such library functions as ``[[nodiscard]]``. -However, this application is limited and applies only to dialects after C++17. -Users who want help diagnosing misuses of STL functions may desire a more -liberal application of ``[[nodiscard]]``. - -For this reason libc++ provides an extension that does just that! The -extension is enabled by default and can be disabled by defining ``_LIBCPP_DISABLE_NODISCARD_EXT``. -The extended applications of ``[[nodiscard]]`` takes two forms: - -1. Backporting ``[[nodiscard]]`` to entities declared as such by the - standard in newer dialects, but not in the present one. - -2. Extended applications of ``[[nodiscard]]``, at the library's discretion, - applied to entities never declared as such by the standard. You can find - all such applications by grepping for ``_LIBCPP_NODISCARD_EXT``. - Extended integral type support ------------------------------ diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 4ecd834c5382ae03335a533296e0e45609674f75..1296c536bc882c81d2b89a65656c5e4447bca140 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -957,7 +957,6 @@ set(files istream iterator latch - libcxx.imp limits list locale @@ -1036,6 +1035,15 @@ foreach(f ${files}) list(APPEND _all_includes "${dst}") endforeach() +# Generate the IWYU mapping. This depends on all header files but it's also considered as an +# "include" for dependency tracking. +add_custom_command(OUTPUT "${LIBCXX_GENERATED_INCLUDE_DIR}/libcxx.imp" + COMMAND "${Python3_EXECUTABLE}" "${LIBCXX_SOURCE_DIR}/utils/generate_iwyu_mapping.py" "-o" "${LIBCXX_GENERATED_INCLUDE_DIR}/libcxx.imp" + DEPENDS ${_all_includes} + COMMENT "Generate the mapping file for include-what-you-use" +) +list(APPEND _all_includes "${LIBCXX_GENERATED_INCLUDE_DIR}/libcxx.imp") + add_custom_target(generate-cxx-headers ALL DEPENDS ${_all_includes}) add_library(cxx-headers INTERFACE) @@ -1068,8 +1076,8 @@ if (LIBCXX_INSTALL_HEADERS) PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT cxx-headers) - # Install the generated modulemap file to the generic include dir. - install(FILES "${LIBCXX_GENERATED_INCLUDE_DIR}/module.modulemap" + # Install the generated IWYU file to the generic include dir. + install(FILES "${LIBCXX_GENERATED_INCLUDE_DIR}/libcxx.imp" DESTINATION "${LIBCXX_INSTALL_INCLUDE_DIR}" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT cxx-headers) diff --git a/libcxx/include/__algorithm/adjacent_find.h b/libcxx/include/__algorithm/adjacent_find.h index 7819e2cf49b9fa951948fe83aeaf150bdfc119e1..6f15456e3a4d074c2cf069b1a2cb46b22e184736 100644 --- a/libcxx/include/__algorithm/adjacent_find.h +++ b/libcxx/include/__algorithm/adjacent_find.h @@ -26,7 +26,7 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter __adjacent_find(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) { if (__first == __last) return __first; @@ -40,13 +40,13 @@ __adjacent_find(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) { } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { return std::__adjacent_find(std::move(__first), std::move(__last), __pred); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator adjacent_find(_ForwardIterator __first, _ForwardIterator __last) { return std::adjacent_find(std::move(__first), std::move(__last), __equal_to()); } diff --git a/libcxx/include/__algorithm/all_of.h b/libcxx/include/__algorithm/all_of.h index 237f8495c645f24fb3af37d5cab15d8885118e6f..ec84eea75929668ebbf84f06ff6a04ea8cf64d57 100644 --- a/libcxx/include/__algorithm/all_of.h +++ b/libcxx/include/__algorithm/all_of.h @@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (!__pred(*__first)) diff --git a/libcxx/include/__algorithm/any_of.h b/libcxx/include/__algorithm/any_of.h index 8ba7aae2b225e1712af63c8b4f4e53b677df83b5..b5ff778c4171dc81754bd14e0962fbd9b1277763 100644 --- a/libcxx/include/__algorithm/any_of.h +++ b/libcxx/include/__algorithm/any_of.h @@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (__pred(*__first)) diff --git a/libcxx/include/__algorithm/binary_search.h b/libcxx/include/__algorithm/binary_search.h index 7a77d7b5447bda7ce988e7534582d4c9b07919e2..6065fc37274dce1301006e83ac02e3abea1e6eac 100644 --- a/libcxx/include/__algorithm/binary_search.h +++ b/libcxx/include/__algorithm/binary_search.h @@ -22,14 +22,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { __first = std::lower_bound<_ForwardIterator, _Tp, __comp_ref_type<_Compare> >(__first, __last, __value, __comp); return __first != __last && !__comp(__value, *__first); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { return std::binary_search(__first, __last, __value, __less<>()); } diff --git a/libcxx/include/__algorithm/clamp.h b/libcxx/include/__algorithm/clamp.h index 003bf70dd4f01db714438aa13a012f7b9b77d32c..1a5a3d0744be9c35d8aa2222a87d0580b4d6b42a 100644 --- a/libcxx/include/__algorithm/clamp.h +++ b/libcxx/include/__algorithm/clamp.h @@ -21,7 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& clamp(_LIBCPP_LIFETIMEBOUND const _Tp& __v, _LIBCPP_LIFETIMEBOUND const _Tp& __lo, _LIBCPP_LIFETIMEBOUND const _Tp& __hi, @@ -31,7 +31,7 @@ clamp(_LIBCPP_LIFETIMEBOUND const _Tp& __v, } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& clamp(_LIBCPP_LIFETIMEBOUND const _Tp& __v, _LIBCPP_LIFETIMEBOUND const _Tp& __lo, _LIBCPP_LIFETIMEBOUND const _Tp& __hi) { diff --git a/libcxx/include/__algorithm/count.h b/libcxx/include/__algorithm/count.h index 23a7d3c4dcfed66e2a50eaa523364b416d460e1e..1cfe7f631ac1b79a435d1e1623fc15c02bf3b4fb 100644 --- a/libcxx/include/__algorithm/count.h +++ b/libcxx/include/__algorithm/count.h @@ -79,7 +79,7 @@ __count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __l } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __iter_diff_t<_InputIterator> +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __iter_diff_t<_InputIterator> count(_InputIterator __first, _InputIterator __last, const _Tp& __value) { __identity __proj; return std::__count<_ClassicAlgPolicy>(__first, __last, __value, __proj); diff --git a/libcxx/include/__algorithm/count_if.h b/libcxx/include/__algorithm/count_if.h index 04f52b894f8bd41e4ffd8cdea64ec97c6b62e5bc..25782069d03275dfac35754fca952dc5ccf2a8c5 100644 --- a/libcxx/include/__algorithm/count_if.h +++ b/libcxx/include/__algorithm/count_if.h @@ -20,9 +20,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - typename iterator_traits<_InputIterator>::difference_type - count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +typename iterator_traits<_InputIterator>::difference_type +count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { typename iterator_traits<_InputIterator>::difference_type __r(0); for (; __first != __last; ++__first) if (__pred(*__first)) diff --git a/libcxx/include/__algorithm/equal.h b/libcxx/include/__algorithm/equal.h index 1341d9e4159ba5874d3618a865dbe044ed87c1b7..bfc8f72f6eb1953efb8c01100068f0d976b8eab4 100644 --- a/libcxx/include/__algorithm/equal.h +++ b/libcxx/include/__algorithm/equal.h @@ -55,14 +55,14 @@ __equal_iter_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _BinaryPredicate&) } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { return std::__equal_iter_impl( std::__unwrap_iter(__first1), std::__unwrap_iter(__last1), std::__unwrap_iter(__first2), __pred); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { return std::equal(__first1, __last1, __first2, __equal_to()); } @@ -96,7 +96,7 @@ __equal_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _Up*, _Pred&, _Proj1&, } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, @@ -119,7 +119,7 @@ equal(_InputIterator1 __first1, } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { return std::equal(__first1, __last1, __first2, __last2, __equal_to()); } diff --git a/libcxx/include/__algorithm/equal_range.h b/libcxx/include/__algorithm/equal_range.h index 2b086abf1794fde469a65ef5bd584db620fc3fd3..09bbf8f006021a350cd4a2cd7216ff26f88aeb75 100644 --- a/libcxx/include/__algorithm/equal_range.h +++ b/libcxx/include/__algorithm/equal_range.h @@ -60,7 +60,7 @@ __equal_range(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, "The comparator has to be callable"); static_assert(is_copy_constructible<_ForwardIterator>::value, "Iterator has to be copy constructible"); @@ -73,7 +73,7 @@ equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { return std::equal_range(std::move(__first), std::move(__last), __value, __less<>()); } diff --git a/libcxx/include/__algorithm/find.h b/libcxx/include/__algorithm/find.h index 7d7631b6e98a96d1e3044b8a8fca8e727aa530df..d603568731322285af7d27c45626303644af7516 100644 --- a/libcxx/include/__algorithm/find.h +++ b/libcxx/include/__algorithm/find.h @@ -169,7 +169,7 @@ struct __find_segment { // public API template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator find(_InputIterator __first, _InputIterator __last, const _Tp& __value) { __identity __proj; return std::__rewrap_iter( diff --git a/libcxx/include/__algorithm/find_end.h b/libcxx/include/__algorithm/find_end.h index 4c26891666b2238d731fc8525f232ce0109109b6..7e08e7953534eb039476ab16505d1885f7286f5c 100644 --- a/libcxx/include/__algorithm/find_end.h +++ b/libcxx/include/__algorithm/find_end.h @@ -205,7 +205,7 @@ _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Fo } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_end( +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_end( _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, @@ -215,7 +215,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { return std::find_end(__first1, __last1, __first2, __last2, __equal_to()); } diff --git a/libcxx/include/__algorithm/find_first_of.h b/libcxx/include/__algorithm/find_first_of.h index 14271cccc42b14254568c86762c8d6d3643c1a17..6b99f562f8804e3780071a1870ee4388af74b9c6 100644 --- a/libcxx/include/__algorithm/find_first_of.h +++ b/libcxx/include/__algorithm/find_first_of.h @@ -35,7 +35,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_fir } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of( +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of( _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, @@ -45,7 +45,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of( +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of( _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { return std::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to()); } diff --git a/libcxx/include/__algorithm/find_if.h b/libcxx/include/__algorithm/find_if.h index 09a39f646351c37e06d78902379b6a00187fb5bb..22092d352b06e7f97319091c8f8e10cc6e1de5ed 100644 --- a/libcxx/include/__algorithm/find_if.h +++ b/libcxx/include/__algorithm/find_if.h @@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (__pred(*__first)) diff --git a/libcxx/include/__algorithm/find_if_not.h b/libcxx/include/__algorithm/find_if_not.h index bf29ebb7cdd93c7cba6a05c3d4f901b05361fff6..cc2001967f0c5a82ab91a4412824c1e0ef5806af 100644 --- a/libcxx/include/__algorithm/find_if_not.h +++ b/libcxx/include/__algorithm/find_if_not.h @@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (!__pred(*__first)) diff --git a/libcxx/include/__algorithm/fold.h b/libcxx/include/__algorithm/fold.h index 1a9d76b50d83c9618f4247eb27278220a389d43d..255658f52324991bdb4601abc87ab9424e8134f2 100644 --- a/libcxx/include/__algorithm/fold.h +++ b/libcxx/include/__algorithm/fold.h @@ -78,8 +78,7 @@ concept __indirectly_binary_left_foldable = struct __fold_left_with_iter { template _Sp, class _Tp, __indirectly_binary_left_foldable<_Tp, _Ip> _Fp> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr auto - operator()(_Ip __first, _Sp __last, _Tp __init, _Fp __f) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Ip __first, _Sp __last, _Tp __init, _Fp __f) { using _Up = decay_t>>; if (__first == __last) { @@ -95,7 +94,7 @@ struct __fold_left_with_iter { } template > _Fp> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Rp&& __r, _Tp __init, _Fp __f) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Rp&& __r, _Tp __init, _Fp __f) { auto __result = operator()(ranges::begin(__r), ranges::end(__r), std::move(__init), std::ref(__f)); using _Up = decay_t>>; @@ -107,13 +106,12 @@ inline constexpr auto fold_left_with_iter = __fold_left_with_iter(); struct __fold_left { template _Sp, class _Tp, __indirectly_binary_left_foldable<_Tp, _Ip> _Fp> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr auto - operator()(_Ip __first, _Sp __last, _Tp __init, _Fp __f) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Ip __first, _Sp __last, _Tp __init, _Fp __f) { return fold_left_with_iter(std::move(__first), std::move(__last), std::move(__init), std::ref(__f)).value; } template > _Fp> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Rp&& __r, _Tp __init, _Fp __f) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Rp&& __r, _Tp __init, _Fp __f) { return fold_left_with_iter(ranges::begin(__r), ranges::end(__r), std::move(__init), std::ref(__f)).value; } }; diff --git a/libcxx/include/__algorithm/includes.h b/libcxx/include/__algorithm/includes.h index 05d45365eb806ffcf21cc3ba5807668aac606a45..62af03c3742608eac2d3fda827f2c3d6be952b4c 100644 --- a/libcxx/include/__algorithm/includes.h +++ b/libcxx/include/__algorithm/includes.h @@ -47,7 +47,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __includes( } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, @@ -67,7 +67,7 @@ includes(_InputIterator1 __first1, } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { return std::includes(std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __less<>()); } diff --git a/libcxx/include/__algorithm/is_heap.h b/libcxx/include/__algorithm/is_heap.h index 0d2d43c2c3abd626edb194ca86a0a413dbe830f6..c589b804a5dc08f3c82fddb6e48be5ef5e7a7ebc 100644 --- a/libcxx/include/__algorithm/is_heap.h +++ b/libcxx/include/__algorithm/is_heap.h @@ -22,13 +22,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)) == __last; } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { return std::is_heap(__first, __last, __less<>()); } diff --git a/libcxx/include/__algorithm/is_heap_until.h b/libcxx/include/__algorithm/is_heap_until.h index 1eae3b86b90dfbd34521fc0f7c5bb86d1a34c89c..a174f2453cfcc0dc43ae0c3c82d29648fce8cf8f 100644 --- a/libcxx/include/__algorithm/is_heap_until.h +++ b/libcxx/include/__algorithm/is_heap_until.h @@ -46,13 +46,13 @@ __is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Co } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) { return std::__is_heap_until(__first, __last, __less<>()); } diff --git a/libcxx/include/__algorithm/is_partitioned.h b/libcxx/include/__algorithm/is_partitioned.h index 71feed33206058aff15294b2955e6a109ba7a093..1f7c8b0b267e75b72b00d6909089e2c127671b11 100644 --- a/libcxx/include/__algorithm/is_partitioned.h +++ b/libcxx/include/__algorithm/is_partitioned.h @@ -18,7 +18,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (!__pred(*__first)) diff --git a/libcxx/include/__algorithm/is_permutation.h b/libcxx/include/__algorithm/is_permutation.h index 4226151222bbde9efc007bbef86f870f9bac7d94..2ddfb32a212bbb458c89221a8fe484bb8952cb81 100644 --- a/libcxx/include/__algorithm/is_permutation.h +++ b/libcxx/include/__algorithm/is_permutation.h @@ -113,7 +113,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation_impl( // 2+1 iterators, predicate. Not used by range algorithms. template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation( +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation( _ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2, _BinaryPredicate&& __pred) { // Shorten sequences as much as possible by lopping of any equal prefix. for (; __first1 != __last1; ++__first1, (void)++__first2) { @@ -247,7 +247,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation( // 2+1 iterators, predicate template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _BinaryPredicate __pred) { static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value, "The predicate has to be callable"); @@ -257,7 +257,7 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool i // 2+1 iterators template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { return std::is_permutation(__first1, __last1, __first2, __equal_to()); } @@ -266,7 +266,7 @@ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIt // 2+2 iterators template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { return std::__is_permutation<_ClassicAlgPolicy>( std::move(__first1), @@ -280,7 +280,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 // 2+2 iterators, predicate template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, diff --git a/libcxx/include/__algorithm/is_sorted.h b/libcxx/include/__algorithm/is_sorted.h index 1874cace882c1edf368166c0099257d3a4b8806b..3befb1ac9c26a691f89aaa6143597e196fcf1882 100644 --- a/libcxx/include/__algorithm/is_sorted.h +++ b/libcxx/include/__algorithm/is_sorted.h @@ -22,13 +22,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { return std::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp) == __last; } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_sorted(_ForwardIterator __first, _ForwardIterator __last) { return std::is_sorted(__first, __last, __less<>()); } diff --git a/libcxx/include/__algorithm/is_sorted_until.h b/libcxx/include/__algorithm/is_sorted_until.h index 7450440df2d8b8c52b5d244c969bd782818509a6..53a49f00de31e8536a828fc1825c7c94effc2042 100644 --- a/libcxx/include/__algorithm/is_sorted_until.h +++ b/libcxx/include/__algorithm/is_sorted_until.h @@ -35,13 +35,13 @@ __is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __ } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { return std::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) { return std::is_sorted_until(__first, __last, __less<>()); } diff --git a/libcxx/include/__algorithm/lexicographical_compare.h b/libcxx/include/__algorithm/lexicographical_compare.h index 3efd8e24bf6c9c3df0711982b962525de70f3e8d..edc29e269c88cab309b97c2ef625948fca301eb5 100644 --- a/libcxx/include/__algorithm/lexicographical_compare.h +++ b/libcxx/include/__algorithm/lexicographical_compare.h @@ -37,7 +37,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __lexicographical_compa } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool lexicographical_compare( +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool lexicographical_compare( _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, @@ -47,7 +47,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool lexicographical_compare( +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool lexicographical_compare( _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { return std::lexicographical_compare(__first1, __last1, __first2, __last2, __less<>()); } diff --git a/libcxx/include/__algorithm/lexicographical_compare_three_way.h b/libcxx/include/__algorithm/lexicographical_compare_three_way.h index 50ebdc647a97abbe05a9df3bb888325f39e86812..a5872e90cf8d2960655c953fe486bcce16dc8ee2 100644 --- a/libcxx/include/__algorithm/lexicographical_compare_three_way.h +++ b/libcxx/include/__algorithm/lexicographical_compare_three_way.h @@ -90,7 +90,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto __lexicographical_compare_three_way_slow_pa } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way( +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way( _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp __comp) -> decltype(__comp(*__first1, *__first2)) { static_assert(__comparison_category, @@ -110,7 +110,7 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compa } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way( +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way( _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { return std::lexicographical_compare_three_way( std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::compare_three_way()); diff --git a/libcxx/include/__algorithm/lower_bound.h b/libcxx/include/__algorithm/lower_bound.h index 8f57f3592c4b24aa5601d451e7211d8a4ce73015..8fd355a7cfc4a0446edca72860f8f106e1be8d92 100644 --- a/libcxx/include/__algorithm/lower_bound.h +++ b/libcxx/include/__algorithm/lower_bound.h @@ -47,7 +47,7 @@ __lower_bound(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, "The comparator has to be callable"); auto __proj = std::__identity(); @@ -55,7 +55,7 @@ lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { return std::lower_bound(__first, __last, __value, __less<>()); } diff --git a/libcxx/include/__algorithm/max.h b/libcxx/include/__algorithm/max.h index 8171677f155c9ce765932d9af90bbb955da514fa..d4c99f6f364367410f83c8ca32f51d4ddb4cef63 100644 --- a/libcxx/include/__algorithm/max.h +++ b/libcxx/include/__algorithm/max.h @@ -25,13 +25,13 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) { return __comp(__a, __b) ? __b : __a; } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) { return std::max(__a, __b, __less<>()); } @@ -39,13 +39,13 @@ max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) #ifndef _LIBCPP_CXX03_LANG template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp max(initializer_list<_Tp> __t, _Compare __comp) { return *std::__max_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp max(initializer_list<_Tp> __t) { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp max(initializer_list<_Tp> __t) { return *std::max_element(__t.begin(), __t.end(), __less<>()); } diff --git a/libcxx/include/__algorithm/max_element.h b/libcxx/include/__algorithm/max_element.h index f1d4f1cd0938c11081fb978fe3534ef20be86b48..c036726cbccd8bca3337c0dfffcd69482b4106d3 100644 --- a/libcxx/include/__algorithm/max_element.h +++ b/libcxx/include/__algorithm/max_element.h @@ -35,13 +35,13 @@ __max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { return std::__max_element<__comp_ref_type<_Compare> >(__first, __last, __comp); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator max_element(_ForwardIterator __first, _ForwardIterator __last) { return std::max_element(__first, __last, __less<>()); } diff --git a/libcxx/include/__algorithm/min.h b/libcxx/include/__algorithm/min.h index 919508486fd5b39e2d4ea6ae356e4255ce878233..1bafad8a461eb93d1d6a2f2a493fe99019861715 100644 --- a/libcxx/include/__algorithm/min.h +++ b/libcxx/include/__algorithm/min.h @@ -25,13 +25,13 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) { return __comp(__b, __a) ? __b : __a; } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) { return std::min(__a, __b, __less<>()); } @@ -39,13 +39,13 @@ min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) #ifndef _LIBCPP_CXX03_LANG template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp min(initializer_list<_Tp> __t, _Compare __comp) { return *std::__min_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp min(initializer_list<_Tp> __t) { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp min(initializer_list<_Tp> __t) { return *std::min_element(__t.begin(), __t.end(), __less<>()); } diff --git a/libcxx/include/__algorithm/min_element.h b/libcxx/include/__algorithm/min_element.h index c576d665601db3bf9a198a2fca54ba1cd32e433c..65f3594d630cef822b3552d2a182e1de8aa471df 100644 --- a/libcxx/include/__algorithm/min_element.h +++ b/libcxx/include/__algorithm/min_element.h @@ -48,7 +48,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter __min_element(_Iter __ } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { static_assert( __has_forward_iterator_category<_ForwardIterator>::value, "std::min_element requires a ForwardIterator"); @@ -59,7 +59,7 @@ min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator min_element(_ForwardIterator __first, _ForwardIterator __last) { return std::min_element(__first, __last, __less<>()); } diff --git a/libcxx/include/__algorithm/minmax.h b/libcxx/include/__algorithm/minmax.h index 5227b885717542384dd36fdd3e6b517014898282..9feda2b4c0da90f16ac6ae86f208595158ae80d3 100644 --- a/libcxx/include/__algorithm/minmax.h +++ b/libcxx/include/__algorithm/minmax.h @@ -24,13 +24,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) { return __comp(__b, __a) ? pair(__b, __a) : pair(__a, __b); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) { return std::minmax(__a, __b, __less<>()); } @@ -38,7 +38,7 @@ minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __ #ifndef _LIBCPP_CXX03_LANG template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Tp, _Tp> +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Tp, _Tp> minmax(initializer_list<_Tp> __t, _Compare __comp) { static_assert(__is_callable<_Compare, _Tp, _Tp>::value, "The comparator has to be callable"); __identity __proj; @@ -47,7 +47,7 @@ minmax(initializer_list<_Tp> __t, _Compare __comp) { } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Tp, _Tp> +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Tp, _Tp> minmax(initializer_list<_Tp> __t) { return std::minmax(__t, __less<>()); } diff --git a/libcxx/include/__algorithm/minmax_element.h b/libcxx/include/__algorithm/minmax_element.h index ff8cda321cef47df7e3d467709d2a01f6aba9afb..43cb23347c3465955984f197da4065a2a03a57a2 100644 --- a/libcxx/include/__algorithm/minmax_element.h +++ b/libcxx/include/__algorithm/minmax_element.h @@ -79,7 +79,7 @@ __minmax_element_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_ForwardIterator, _ForwardIterator> +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { static_assert( __has_forward_iterator_category<_ForwardIterator>::value, "std::minmax_element requires a ForwardIterator"); @@ -90,9 +90,8 @@ minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __com } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 - pair<_ForwardIterator, _ForwardIterator> - minmax_element(_ForwardIterator __first, _ForwardIterator __last) { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_ForwardIterator, _ForwardIterator> +minmax_element(_ForwardIterator __first, _ForwardIterator __last) { return std::minmax_element(__first, __last, __less<>()); } diff --git a/libcxx/include/__algorithm/mismatch.h b/libcxx/include/__algorithm/mismatch.h index 4ada29eabc470c93115d00b06766abb546ec537a..c2b3f8938f71113a4b501699018f0465488e1daa 100644 --- a/libcxx/include/__algorithm/mismatch.h +++ b/libcxx/include/__algorithm/mismatch.h @@ -122,7 +122,7 @@ __mismatch(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Pred& __pred, _Proj1& __ #endif // _LIBCPP_VECTORIZE_ALGORITHMS template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { __identity __proj; auto __res = std::__mismatch( @@ -131,14 +131,14 @@ mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __fi } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { return std::mismatch(__first1, __last1, __first2, __equal_to()); } #if _LIBCPP_STD_VER >= 14 template -[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter1, _Iter2> __mismatch( +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter1, _Iter2> __mismatch( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { while (__first1 != __last1 && __first2 != __last2) { if (!std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) @@ -150,14 +150,14 @@ template -[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Tp*, _Tp*> +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Tp*, _Tp*> __mismatch(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Tp* __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { auto __len = std::min(__last1 - __first1, __last2 - __first2); return std::__mismatch(__first1, __first1 + __len, __first2, __pred, __proj1, __proj2); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, @@ -176,7 +176,7 @@ mismatch(_InputIterator1 __first1, } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { return std::mismatch(__first1, __last1, __first2, __last2, __equal_to()); } diff --git a/libcxx/include/__algorithm/none_of.h b/libcxx/include/__algorithm/none_of.h index ce59187a3a6504a064e4d72b599a0cf86815b474..50841ba17cc63ed69c914808cc5184158c466d1f 100644 --- a/libcxx/include/__algorithm/none_of.h +++ b/libcxx/include/__algorithm/none_of.h @@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (__pred(*__first)) diff --git a/libcxx/include/__algorithm/pstl_any_all_none_of.h b/libcxx/include/__algorithm/pstl_any_all_none_of.h index 911a7e42b3fa3f711cc9905913b572c387a18778..e27463dab8a3109e7d1fae3e330ee85184961c77 100644 --- a/libcxx/include/__algorithm/pstl_any_all_none_of.h +++ b/libcxx/include/__algorithm/pstl_any_all_none_of.h @@ -58,7 +58,7 @@ template , enable_if_t, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool any_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "any_of requires a ForwardIterator"); auto __res = std::__any_of(__policy, std::move(__first), std::move(__last), std::move(__pred)); @@ -97,7 +97,7 @@ template , enable_if_t, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool all_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) { _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "all_of requires a ForwardIterator"); auto __res = std::__all_of(__policy, std::move(__first), std::move(__last), std::move(__pred)); @@ -134,7 +134,7 @@ template , enable_if_t, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool none_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) { _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "none_of requires a ForwardIterator"); auto __res = std::__none_of(__policy, std::move(__first), std::move(__last), std::move(__pred)); diff --git a/libcxx/include/__algorithm/pstl_is_partitioned.h b/libcxx/include/__algorithm/pstl_is_partitioned.h index c016b388e3784a6aa660efd7722fe1fa03eb3c71..2dd5cf3ca2a21abc6b66b7a6cf617bd87ab89c9f 100644 --- a/libcxx/include/__algorithm/pstl_is_partitioned.h +++ b/libcxx/include/__algorithm/pstl_is_partitioned.h @@ -61,7 +61,7 @@ template , enable_if_t, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool is_partitioned(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "is_partitioned requires ForwardIterators"); auto __res = std::__is_partitioned(__policy, std::move(__first), std::move(__last), std::move(__pred)); diff --git a/libcxx/include/__algorithm/ranges_adjacent_find.h b/libcxx/include/__algorithm/ranges_adjacent_find.h index a10b04167ede697868f6f2386e5e0868f1c24b57..3c54f723310a6f8257c4d405d71216c2643da742 100644 --- a/libcxx/include/__algorithm/ranges_adjacent_find.h +++ b/libcxx/include/__algorithm/ranges_adjacent_find.h @@ -53,7 +53,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_binary_predicate, projected<_Iter, _Proj>> _Pred = ranges::equal_to> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { return __adjacent_find_impl(std::move(__first), std::move(__last), __pred, __proj); } @@ -62,7 +62,7 @@ struct __fn { class _Proj = identity, indirect_binary_predicate, _Proj>, projected, _Proj>> _Pred = ranges::equal_to> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range, _Pred __pred = {}, _Proj __proj = {}) const { return __adjacent_find_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } diff --git a/libcxx/include/__algorithm/ranges_all_of.h b/libcxx/include/__algorithm/ranges_all_of.h index 8976541d590cad16740b6a60aedb77e1cc86295b..2f603b32f32d08a29305271e91ac646ebf27ca33 100644 --- a/libcxx/include/__algorithm/ranges_all_of.h +++ b/libcxx/include/__algorithm/ranges_all_of.h @@ -45,7 +45,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { return __all_of_impl(std::move(__first), std::move(__last), __pred, __proj); } @@ -53,7 +53,7 @@ struct __fn { template , _Proj>> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { return __all_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } diff --git a/libcxx/include/__algorithm/ranges_any_of.h b/libcxx/include/__algorithm/ranges_any_of.h index 7c775f5f64dec0983013b5e16993ae0ac979fa64..205fcecc086e7a65766bea679002819ee889bc21 100644 --- a/libcxx/include/__algorithm/ranges_any_of.h +++ b/libcxx/include/__algorithm/ranges_any_of.h @@ -45,7 +45,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { return __any_of_impl(std::move(__first), std::move(__last), __pred, __proj); } @@ -53,7 +53,7 @@ struct __fn { template , _Proj>> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { return __any_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } diff --git a/libcxx/include/__algorithm/ranges_binary_search.h b/libcxx/include/__algorithm/ranges_binary_search.h index f3b7842d5cccd4428b6a99fa9e10ff33b7b75225..1ef2bd62b5995ab9799eb766c2f78bbaaa392ccc 100644 --- a/libcxx/include/__algorithm/ranges_binary_search.h +++ b/libcxx/include/__algorithm/ranges_binary_search.h @@ -39,7 +39,7 @@ struct __fn { class _Type, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { auto __ret = std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret)); @@ -49,7 +49,7 @@ struct __fn { class _Type, class _Proj = identity, indirect_strict_weak_order, _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { auto __first = ranges::begin(__r); auto __last = ranges::end(__r); diff --git a/libcxx/include/__algorithm/ranges_clamp.h b/libcxx/include/__algorithm/ranges_clamp.h index f5ef5fd7f26ec88bf6e3e95fdca3db5fd31b1217..e6181ef9435e098862a0e0e38c48978e30589e85 100644 --- a/libcxx/include/__algorithm/ranges_clamp.h +++ b/libcxx/include/__algorithm/ranges_clamp.h @@ -35,7 +35,7 @@ struct __fn { template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr const _Type& operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Type& operator()( const _Type& __value, const _Type& __low, const _Type& __high, _Comp __comp = {}, _Proj __proj = {}) const { _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( !bool(std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __low))), diff --git a/libcxx/include/__algorithm/ranges_contains.h b/libcxx/include/__algorithm/ranges_contains.h index 00d0e54019887c448b6b9321ff0654ed42b867f0..4836c3baed173eea19a017784dc7e8df3f4edb64 100644 --- a/libcxx/include/__algorithm/ranges_contains.h +++ b/libcxx/include/__algorithm/ranges_contains.h @@ -37,14 +37,14 @@ namespace __contains { struct __fn { template _Sent, class _Type, class _Proj = identity> requires indirect_binary_predicate, const _Type*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool static + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool static operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) { return ranges::find(std::move(__first), __last, __value, std::ref(__proj)) != __last; } template requires indirect_binary_predicate, _Proj>, const _Type*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool static + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool static operator()(_Range&& __range, const _Type& __value, _Proj __proj = {}) { return ranges::find(ranges::begin(__range), ranges::end(__range), __value, std::ref(__proj)) != ranges::end(__range); diff --git a/libcxx/include/__algorithm/ranges_contains_subrange.h b/libcxx/include/__algorithm/ranges_contains_subrange.h index bc5a86ce3d696a164f6396b90eb7bf6a60c78bec..4398c457fd054d3c02b774b7543588fb822f9410 100644 --- a/libcxx/include/__algorithm/ranges_contains_subrange.h +++ b/libcxx/include/__algorithm/ranges_contains_subrange.h @@ -45,7 +45,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool static operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool static operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -67,7 +67,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool static + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool static operator()(_Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) { if constexpr (sized_range<_Range2>) { if (ranges::size(__range2) == 0) diff --git a/libcxx/include/__algorithm/ranges_count.h b/libcxx/include/__algorithm/ranges_count.h index a8965c1b961f330b1d7a8c8f0f4f717dd394bf39..4f35117438705d418992cecf12103f23cc5a3259 100644 --- a/libcxx/include/__algorithm/ranges_count.h +++ b/libcxx/include/__algorithm/ranges_count.h @@ -38,14 +38,14 @@ namespace __count { struct __fn { template _Sent, class _Type, class _Proj = identity> requires indirect_binary_predicate, const _Type*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const { return std::__count<_RangeAlgPolicy>(std::move(__first), std::move(__last), __value, __proj); } template requires indirect_binary_predicate, _Proj>, const _Type*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range> operator()(_Range&& __r, const _Type& __value, _Proj __proj = {}) const { return std::__count<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __value, __proj); } diff --git a/libcxx/include/__algorithm/ranges_count_if.h b/libcxx/include/__algorithm/ranges_count_if.h index 71b942dd5322b72eacb36e3f98b81ef1a40a494a..5f2396ff7d5315e07d8dba515a85f09d7b9619db 100644 --- a/libcxx/include/__algorithm/ranges_count_if.h +++ b/libcxx/include/__algorithm/ranges_count_if.h @@ -50,7 +50,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_unary_predicate> _Predicate> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> operator()(_Iter __first, _Sent __last, _Predicate __pred, _Proj __proj = {}) const { return ranges::__count_if_impl(std::move(__first), std::move(__last), __pred, __proj); } @@ -58,7 +58,7 @@ struct __fn { template , _Proj>> _Predicate> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range> operator()(_Range&& __r, _Predicate __pred, _Proj __proj = {}) const { return ranges::__count_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj); } diff --git a/libcxx/include/__algorithm/ranges_ends_with.h b/libcxx/include/__algorithm/ranges_ends_with.h index bb01918326b8bc9496fa8cbc4b5ed19324400ab0..06efdef36b7cf22d53972f695b2a319566b3cee4 100644 --- a/libcxx/include/__algorithm/ranges_ends_with.h +++ b/libcxx/include/__algorithm/ranges_ends_with.h @@ -133,7 +133,7 @@ struct __fn { requires(forward_iterator<_Iter1> || sized_sentinel_for<_Sent1, _Iter1>) && (forward_iterator<_Iter2> || sized_sentinel_for<_Sent2, _Iter2>) && indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -152,7 +152,7 @@ struct __fn { class _Proj2 = identity> requires(forward_range<_Range1> || sized_range<_Range1>) && (forward_range<_Range2> || sized_range<_Range2>) && indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { if constexpr (sized_range<_Range1> && sized_range<_Range2>) { auto __n1 = ranges::size(__range1); diff --git a/libcxx/include/__algorithm/ranges_equal.h b/libcxx/include/__algorithm/ranges_equal.h index 31c7ee261da61fe6381eee3ebdb067b57e930fe3..edbd0e3641c1b891a3c10ff32670ec934bbd680d 100644 --- a/libcxx/include/__algorithm/ranges_equal.h +++ b/libcxx/include/__algorithm/ranges_equal.h @@ -44,7 +44,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -74,7 +74,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { if constexpr (sized_range<_Range1> && sized_range<_Range2>) { if (ranges::distance(__range1) != ranges::distance(__range2)) diff --git a/libcxx/include/__algorithm/ranges_equal_range.h b/libcxx/include/__algorithm/ranges_equal_range.h index 4c1c3834ba9f9f2e997a1b393fef9c4d2c496612..4a308e016b546a575d2ccafd1f8592c80bbf0871 100644 --- a/libcxx/include/__algorithm/ranges_equal_range.h +++ b/libcxx/include/__algorithm/ranges_equal_range.h @@ -46,7 +46,7 @@ struct __fn { class _Tp, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> operator()(_Iter __first, _Sent __last, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { auto __ret = std::__equal_range<_RangeAlgPolicy>(std::move(__first), std::move(__last), __value, __comp, __proj); return {std::move(__ret.first), std::move(__ret.second)}; @@ -56,7 +56,7 @@ struct __fn { class _Tp, class _Proj = identity, indirect_strict_weak_order, _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> operator()(_Range&& __range, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { auto __ret = std::__equal_range<_RangeAlgPolicy>(ranges::begin(__range), ranges::end(__range), __value, __comp, __proj); diff --git a/libcxx/include/__algorithm/ranges_find.h b/libcxx/include/__algorithm/ranges_find.h index 7459fad717a5d6d33cc26c7f4f396a40d805ca5f..e1383eb4b071ad965cb802f0b44e9ab91deb3ff4 100644 --- a/libcxx/include/__algorithm/ranges_find.h +++ b/libcxx/include/__algorithm/ranges_find.h @@ -52,14 +52,14 @@ struct __fn { template _Sp, class _Tp, class _Proj = identity> requires indirect_binary_predicate, const _Tp*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __first, _Sp __last, const _Tp& __value, _Proj __proj = {}) const { return __find_unwrap(std::move(__first), std::move(__last), __value, __proj); } template requires indirect_binary_predicate, _Proj>, const _Tp*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> operator()(_Rp&& __r, const _Tp& __value, _Proj __proj = {}) const { return __find_unwrap(ranges::begin(__r), ranges::end(__r), __value, __proj); } diff --git a/libcxx/include/__algorithm/ranges_find_end.h b/libcxx/include/__algorithm/ranges_find_end.h index 0bda4f3e1cea9ee7c3afac99e8bf44f0a083fcbe..e49e66dd4ac04b86f395534b11c800c2a8043220 100644 --- a/libcxx/include/__algorithm/ranges_find_end.h +++ b/libcxx/include/__algorithm/ranges_find_end.h @@ -45,7 +45,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter1> operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter1> operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -72,7 +72,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range1> operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range1> operator()( _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { auto __ret = std::__find_end_impl<_RangeAlgPolicy>( ranges::begin(__range1), diff --git a/libcxx/include/__algorithm/ranges_find_first_of.h b/libcxx/include/__algorithm/ranges_find_first_of.h index 63a7b8335faaf5ebb5e376fc0d3276407988d0cb..d92d9686bc4420921c76ed170d19dff3a81f75c5 100644 --- a/libcxx/include/__algorithm/ranges_find_first_of.h +++ b/libcxx/include/__algorithm/ranges_find_first_of.h @@ -60,7 +60,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter1 operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter1 operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -78,7 +78,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range1> operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range1> operator()( _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { return __find_first_of_impl( ranges::begin(__range1), diff --git a/libcxx/include/__algorithm/ranges_find_if.h b/libcxx/include/__algorithm/ranges_find_if.h index 52ae55ce96c3664b91db68c1538b249a515d3532..888f9ec3cb2d586328a5543ba04ae67502828f0b 100644 --- a/libcxx/include/__algorithm/ranges_find_if.h +++ b/libcxx/include/__algorithm/ranges_find_if.h @@ -48,13 +48,13 @@ struct __fn { sentinel_for<_Ip> _Sp, class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const { return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred, __proj); } template , _Proj>> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const { return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj); } diff --git a/libcxx/include/__algorithm/ranges_find_if_not.h b/libcxx/include/__algorithm/ranges_find_if_not.h index 60c6796cbbfcc73ff8178eecaf0390bf72eb692c..ec19545b5a1b7a34e8d80c5aab070f51776f6bc0 100644 --- a/libcxx/include/__algorithm/ranges_find_if_not.h +++ b/libcxx/include/__algorithm/ranges_find_if_not.h @@ -40,14 +40,14 @@ struct __fn { sentinel_for<_Ip> _Sp, class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const { auto __pred2 = [&](auto&& __e) -> bool { return !std::invoke(__pred, std::forward(__e)); }; return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred2, __proj); } template , _Proj>> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const { auto __pred2 = [&](auto&& __e) -> bool { return !std::invoke(__pred, std::forward(__e)); }; return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred2, __proj); diff --git a/libcxx/include/__algorithm/ranges_includes.h b/libcxx/include/__algorithm/ranges_includes.h index 0bc4c043bd1881406e07056efe5ae4d0b750c9b4..c4c3b8ed088d313381e462e9b5135fc13e87cc59 100644 --- a/libcxx/include/__algorithm/ranges_includes.h +++ b/libcxx/include/__algorithm/ranges_includes.h @@ -45,7 +45,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity, indirect_strict_weak_order, projected<_Iter2, _Proj2>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -69,7 +69,7 @@ struct __fn { class _Proj2 = identity, indirect_strict_weak_order, _Proj1>, projected, _Proj2>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { return std::__includes( ranges::begin(__range1), diff --git a/libcxx/include/__algorithm/ranges_is_heap.h b/libcxx/include/__algorithm/ranges_is_heap.h index 122368c90d924d8141e0fe3299ca5ecf04e027ee..3d9e18ce1d9067806dd7acfda121caebe472fc35 100644 --- a/libcxx/include/__algorithm/ranges_is_heap.h +++ b/libcxx/include/__algorithm/ranges_is_heap.h @@ -51,7 +51,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return __is_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); } @@ -59,7 +59,7 @@ struct __fn { template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { return __is_heap_fn_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj); } diff --git a/libcxx/include/__algorithm/ranges_is_heap_until.h b/libcxx/include/__algorithm/ranges_is_heap_until.h index b2705d37a6d3450572c997c10ddef5dc07711d0b..7a2e1fc7705b6fd81cb6e0f4a50915c805422236 100644 --- a/libcxx/include/__algorithm/ranges_is_heap_until.h +++ b/libcxx/include/__algorithm/ranges_is_heap_until.h @@ -51,7 +51,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return __is_heap_until_fn_impl(std::move(__first), std::move(__last), __comp, __proj); } @@ -59,7 +59,7 @@ struct __fn { template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { return __is_heap_until_fn_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj); } diff --git a/libcxx/include/__algorithm/ranges_is_partitioned.h b/libcxx/include/__algorithm/ranges_is_partitioned.h index c6a585c9f51070cab9ea4100c9a84574d628a688..5be6fba46fd9e247689594a7977d9637ea354114 100644 --- a/libcxx/include/__algorithm/ranges_is_partitioned.h +++ b/libcxx/include/__algorithm/ranges_is_partitioned.h @@ -57,7 +57,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { return __is_partitioned_impl(std::move(__first), std::move(__last), __pred, __proj); } @@ -65,7 +65,7 @@ struct __fn { template , _Proj>> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { return __is_partitioned_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } diff --git a/libcxx/include/__algorithm/ranges_is_permutation.h b/libcxx/include/__algorithm/ranges_is_permutation.h index e0423d722b5b9866a970c2767524560f3d18c119..1f8d67007a573820c2697c938bf668083746ced0 100644 --- a/libcxx/include/__algorithm/ranges_is_permutation.h +++ b/libcxx/include/__algorithm/ranges_is_permutation.h @@ -56,7 +56,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity, indirect_equivalence_relation, projected<_Iter2, _Proj2>> _Pred = ranges::equal_to> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -74,7 +74,7 @@ struct __fn { class _Proj2 = identity, indirect_equivalence_relation, _Proj1>, projected, _Proj2>> _Pred = ranges::equal_to> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { if constexpr (sized_range<_Range1> && sized_range<_Range2>) { if (ranges::distance(__range1) != ranges::distance(__range2)) diff --git a/libcxx/include/__algorithm/ranges_is_sorted.h b/libcxx/include/__algorithm/ranges_is_sorted.h index d71035d5aa1d016111438133c2d521a55df44b53..5b88d422b4b091c8ec8e534ded75e1efb3995fe9 100644 --- a/libcxx/include/__algorithm/ranges_is_sorted.h +++ b/libcxx/include/__algorithm/ranges_is_sorted.h @@ -37,7 +37,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return ranges::__is_sorted_until_impl(std::move(__first), __last, __comp, __proj) == __last; } @@ -45,7 +45,7 @@ struct __fn { template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { auto __last = ranges::end(__range); return ranges::__is_sorted_until_impl(ranges::begin(__range), __last, __comp, __proj) == __last; diff --git a/libcxx/include/__algorithm/ranges_is_sorted_until.h b/libcxx/include/__algorithm/ranges_is_sorted_until.h index dcfb6a4e1813bdc26de8b8ab680580bbcee9959c..54de530c8b2fd8bc3d9cc72fd6310616456270fc 100644 --- a/libcxx/include/__algorithm/ranges_is_sorted_until.h +++ b/libcxx/include/__algorithm/ranges_is_sorted_until.h @@ -53,7 +53,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return ranges::__is_sorted_until_impl(std::move(__first), std::move(__last), __comp, __proj); } @@ -61,7 +61,7 @@ struct __fn { template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { return ranges::__is_sorted_until_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj); } diff --git a/libcxx/include/__algorithm/ranges_lexicographical_compare.h b/libcxx/include/__algorithm/ranges_lexicographical_compare.h index 90e96b5465169b20ac40aa2992285224eae320a9..6d82017e302a70b3f5022399517240867d5e08ed 100644 --- a/libcxx/include/__algorithm/ranges_lexicographical_compare.h +++ b/libcxx/include/__algorithm/ranges_lexicographical_compare.h @@ -60,7 +60,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity, indirect_strict_weak_order, projected<_Iter2, _Proj2>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -78,7 +78,7 @@ struct __fn { class _Proj2 = identity, indirect_strict_weak_order, _Proj1>, projected, _Proj2>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { return __lexicographical_compare_impl( ranges::begin(__range1), diff --git a/libcxx/include/__algorithm/ranges_lower_bound.h b/libcxx/include/__algorithm/ranges_lower_bound.h index ab1f80e7ab7705aaf5abec4a964feb3d9a859933..0651147e0424952f4fd82a76b35128f08e551964 100644 --- a/libcxx/include/__algorithm/ranges_lower_bound.h +++ b/libcxx/include/__algorithm/ranges_lower_bound.h @@ -43,7 +43,7 @@ struct __fn { class _Type, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { return std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); } @@ -52,7 +52,7 @@ struct __fn { class _Type, class _Proj = identity, indirect_strict_weak_order, _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { return std::__lower_bound<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __value, __comp, __proj); } diff --git a/libcxx/include/__algorithm/ranges_max.h b/libcxx/include/__algorithm/ranges_max.h index c63656de51349820e195d894d5c6576ab3ba5857..d0ee6f314b0c3f4a8258cc4bd8ecda05dd9ea477 100644 --- a/libcxx/include/__algorithm/ranges_max.h +++ b/libcxx/include/__algorithm/ranges_max.h @@ -41,7 +41,7 @@ struct __fn { template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator()(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Comp __comp = {}, @@ -52,7 +52,7 @@ struct __fn { template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( __il.begin() != __il.end(), "initializer_list must contain at least one element"); @@ -65,7 +65,7 @@ struct __fn { class _Proj = identity, indirect_strict_weak_order, _Proj>> _Comp = ranges::less> requires indirectly_copyable_storable, range_value_t<_Rp>*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_value_t<_Rp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr range_value_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { auto __first = ranges::begin(__r); auto __last = ranges::end(__r); diff --git a/libcxx/include/__algorithm/ranges_max_element.h b/libcxx/include/__algorithm/ranges_max_element.h index 83adf49b61ad8f9f210bde074e455b6a0b30e572..c577309271165be731e810098d7ffca0e0732f21 100644 --- a/libcxx/include/__algorithm/ranges_max_element.h +++ b/libcxx/include/__algorithm/ranges_max_element.h @@ -38,7 +38,7 @@ struct __fn { sentinel_for<_Ip> _Sp, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) -> bool { return std::invoke(__comp, __rhs, __lhs); }; return ranges::__min_element_impl(__first, __last, __comp_lhs_rhs_swapped, __proj); @@ -47,7 +47,7 @@ struct __fn { template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) -> bool { return std::invoke(__comp, __rhs, __lhs); }; return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp_lhs_rhs_swapped, __proj); diff --git a/libcxx/include/__algorithm/ranges_min.h b/libcxx/include/__algorithm/ranges_min.h index e8f97f2754acaba67ad4b0e1e70755938bf3e212..cc569d2a060c220c132b6ed7a0ae0f78d96fb6f6 100644 --- a/libcxx/include/__algorithm/ranges_min.h +++ b/libcxx/include/__algorithm/ranges_min.h @@ -40,7 +40,7 @@ struct __fn { template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator()(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Comp __comp = {}, @@ -51,7 +51,7 @@ struct __fn { template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( __il.begin() != __il.end(), "initializer_list must contain at least one element"); @@ -62,7 +62,7 @@ struct __fn { class _Proj = identity, indirect_strict_weak_order, _Proj>> _Comp = ranges::less> requires indirectly_copyable_storable, range_value_t<_Rp>*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_value_t<_Rp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr range_value_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { auto __first = ranges::begin(__r); auto __last = ranges::end(__r); diff --git a/libcxx/include/__algorithm/ranges_min_element.h b/libcxx/include/__algorithm/ranges_min_element.h index 4b9cb76da5789c0db059444ac2a1352d1d8437bf..588ef258e26f5d746b347d01d4979b12c9bf6a14 100644 --- a/libcxx/include/__algorithm/ranges_min_element.h +++ b/libcxx/include/__algorithm/ranges_min_element.h @@ -52,7 +52,7 @@ struct __fn { sentinel_for<_Ip> _Sp, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { return ranges::__min_element_impl(__first, __last, __comp, __proj); } @@ -60,7 +60,7 @@ struct __fn { template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); } diff --git a/libcxx/include/__algorithm/ranges_minmax.h b/libcxx/include/__algorithm/ranges_minmax.h index ca5722523336fdf43e6558f422425b677d40b903..09cbefd91a8c77cc5b93d10894712998ef89dcb6 100644 --- a/libcxx/include/__algorithm/ranges_minmax.h +++ b/libcxx/include/__algorithm/ranges_minmax.h @@ -52,7 +52,7 @@ struct __fn { template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result operator()(_LIBCPP_LIFETIMEBOUND const _Type& __a, _LIBCPP_LIFETIMEBOUND const _Type& __b, _Comp __comp = {}, @@ -65,7 +65,7 @@ struct __fn { template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result<_Type> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result<_Type> operator()(initializer_list<_Type> __il, _Comp __comp = {}, _Proj __proj = {}) const { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( __il.begin() != __il.end(), "initializer_list has to contain at least one element"); @@ -77,7 +77,7 @@ struct __fn { class _Proj = identity, indirect_strict_weak_order, _Proj>> _Comp = ranges::less> requires indirectly_copyable_storable, range_value_t<_Range>*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { auto __first = ranges::begin(__r); auto __last = ranges::end(__r); diff --git a/libcxx/include/__algorithm/ranges_minmax_element.h b/libcxx/include/__algorithm/ranges_minmax_element.h index 5132856ebcd5ca5a15ebca8496ad9d71eda0ef32..4bf6d2404e463d960bfed6ca4af3b9ffc8d5c754 100644 --- a/libcxx/include/__algorithm/ranges_minmax_element.h +++ b/libcxx/include/__algorithm/ranges_minmax_element.h @@ -46,7 +46,7 @@ struct __fn { sentinel_for<_Ip> _Sp, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_element_result<_Ip> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_element_result<_Ip> operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { auto __ret = std::__minmax_element_impl(std::move(__first), std::move(__last), __comp, __proj); return {__ret.first, __ret.second}; @@ -55,7 +55,7 @@ struct __fn { template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_element_result> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_element_result> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { auto __ret = std::__minmax_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); return {__ret.first, __ret.second}; diff --git a/libcxx/include/__algorithm/ranges_mismatch.h b/libcxx/include/__algorithm/ranges_mismatch.h index d8a7dd43af09d5da283dfb44cd2e6203d86e1589..c4bf0022a9bcc0dd335f388bd94c75ff15293096 100644 --- a/libcxx/include/__algorithm/ranges_mismatch.h +++ b/libcxx/include/__algorithm/ranges_mismatch.h @@ -65,7 +65,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable<_I1, _I2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr mismatch_result<_I1, _I2> operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr mismatch_result<_I1, _I2> operator()( _I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { return __go(std::move(__first1), __last1, std::move(__first2), __last2, __pred, __proj1, __proj2); @@ -77,7 +77,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable, iterator_t<_R2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr mismatch_result, borrowed_iterator_t<_R2>> operator()(_R1&& __r1, _R2&& __r2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { return __go( diff --git a/libcxx/include/__algorithm/ranges_none_of.h b/libcxx/include/__algorithm/ranges_none_of.h index 59bd87997d448fabc261eac64ab47e09206995f0..7df3c1829fcfcb990ff2bbc728b8e9fc07ab2b40 100644 --- a/libcxx/include/__algorithm/ranges_none_of.h +++ b/libcxx/include/__algorithm/ranges_none_of.h @@ -46,7 +46,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { return __none_of_impl(std::move(__first), std::move(__last), __pred, __proj); } @@ -54,7 +54,7 @@ struct __fn { template , _Proj>> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { return __none_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } diff --git a/libcxx/include/__algorithm/ranges_remove.h b/libcxx/include/__algorithm/ranges_remove.h index 315bed8fba775bfbc118d63910853c30bc36a495..17c3a2c5cd06b6f57a3d1fb4a7d5814e8f1d3936 100644 --- a/libcxx/include/__algorithm/ranges_remove.h +++ b/libcxx/include/__algorithm/ranges_remove.h @@ -37,7 +37,7 @@ namespace __remove { struct __fn { template _Sent, class _Type, class _Proj = identity> requires indirect_binary_predicate, const _Type*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const { auto __pred = [&](auto&& __other) -> bool { return __value == __other; }; return ranges::__remove_if_impl(std::move(__first), std::move(__last), __pred, __proj); @@ -46,7 +46,7 @@ struct __fn { template requires permutable> && indirect_binary_predicate, _Proj>, const _Type*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> operator()(_Range&& __range, const _Type& __value, _Proj __proj = {}) const { auto __pred = [&](auto&& __other) -> bool { return __value == __other; }; return ranges::__remove_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); diff --git a/libcxx/include/__algorithm/ranges_remove_if.h b/libcxx/include/__algorithm/ranges_remove_if.h index 943dbdd73807e665b8ee9a1d3e4d078a828e2492..0ea5d9a01b88183aea02bceb5d2e051112d9c639 100644 --- a/libcxx/include/__algorithm/ranges_remove_if.h +++ b/libcxx/include/__algorithm/ranges_remove_if.h @@ -59,7 +59,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { return ranges::__remove_if_impl(std::move(__first), std::move(__last), __pred, __proj); } @@ -68,7 +68,7 @@ struct __fn { class _Proj = identity, indirect_unary_predicate, _Proj>> _Pred> requires permutable> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { return ranges::__remove_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } diff --git a/libcxx/include/__algorithm/ranges_search.h b/libcxx/include/__algorithm/ranges_search.h index ca2326e9ab27348cb24113ddec00ef8ae4fd2ddf..55294c60631b18964f4f679ad275fe6cbcf35344 100644 --- a/libcxx/include/__algorithm/ranges_search.h +++ b/libcxx/include/__algorithm/ranges_search.h @@ -77,7 +77,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter1> operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter1> operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -94,7 +94,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range1> operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range1> operator()( _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { auto __first1 = ranges::begin(__range1); if constexpr (sized_range<_Range2>) { diff --git a/libcxx/include/__algorithm/ranges_search_n.h b/libcxx/include/__algorithm/ranges_search_n.h index 4c1d73d8e6c34013ee7cce5f2a9a24241626f41e..56e12755b9bf6b5d2e235e50055c8ade711cc54f 100644 --- a/libcxx/include/__algorithm/ranges_search_n.h +++ b/libcxx/include/__algorithm/ranges_search_n.h @@ -71,7 +71,7 @@ struct __fn { class _Pred = ranges::equal_to, class _Proj = identity> requires indirectly_comparable<_Iter, const _Type*, _Pred, _Proj> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> operator()(_Iter __first, _Sent __last, iter_difference_t<_Iter> __count, @@ -83,7 +83,7 @@ struct __fn { template requires indirectly_comparable, const _Type*, _Pred, _Proj> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> operator()( _Range&& __range, range_difference_t<_Range> __count, const _Type& __value, _Pred __pred = {}, _Proj __proj = {}) const { auto __first = ranges::begin(__range); diff --git a/libcxx/include/__algorithm/ranges_starts_with.h b/libcxx/include/__algorithm/ranges_starts_with.h index 7ba8af13a8d1c83084bcb227a8c145fbc7359875..17084e4f24336acbbfb20fda4a0ba5c9e604aacb 100644 --- a/libcxx/include/__algorithm/ranges_starts_with.h +++ b/libcxx/include/__algorithm/ranges_starts_with.h @@ -42,7 +42,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr bool operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -67,7 +67,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr bool operator()(_Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) { return __mismatch::__fn::__go( ranges::begin(__range1), diff --git a/libcxx/include/__algorithm/ranges_unique.h b/libcxx/include/__algorithm/ranges_unique.h index 7340310eb36a90e210fcf9b74b73863fe9850f91..7a9b7843218737e6dc8a4a75de7d50a6fc4c8306 100644 --- a/libcxx/include/__algorithm/ranges_unique.h +++ b/libcxx/include/__algorithm/ranges_unique.h @@ -47,7 +47,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_equivalence_relation> _Comp = ranges::equal_to> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { auto __ret = std::__unique<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::__make_projected(__comp, __proj)); @@ -58,7 +58,7 @@ struct __fn { class _Proj = identity, indirect_equivalence_relation, _Proj>> _Comp = ranges::equal_to> requires permutable> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { auto __ret = std::__unique<_RangeAlgPolicy>( ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj)); diff --git a/libcxx/include/__algorithm/ranges_upper_bound.h b/libcxx/include/__algorithm/ranges_upper_bound.h index 7b571fb3448f94c7514d54b9c0782e7d2c56f12d..fa6fa7f70ed5a7316a4021bac054e1d1d5a980c4 100644 --- a/libcxx/include/__algorithm/ranges_upper_bound.h +++ b/libcxx/include/__algorithm/ranges_upper_bound.h @@ -37,7 +37,7 @@ struct __fn { class _Type, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) -> bool { return !std::invoke(__comp, __rhs, __lhs); @@ -50,7 +50,7 @@ struct __fn { class _Type, class _Proj = identity, indirect_strict_weak_order, _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) -> bool { return !std::invoke(__comp, __rhs, __lhs); diff --git a/libcxx/include/__algorithm/remove.h b/libcxx/include/__algorithm/remove.h index 1498852c4361308912202cea1620ae35fcb832d7..fd01c23cb6708a8ed9a9378511383b81848f8b6d 100644 --- a/libcxx/include/__algorithm/remove.h +++ b/libcxx/include/__algorithm/remove.h @@ -24,7 +24,7 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { __first = std::find(__first, __last, __value); if (__first != __last) { diff --git a/libcxx/include/__algorithm/remove_if.h b/libcxx/include/__algorithm/remove_if.h index c77b78023f529f959ce0b2cfa35f9bd20e18abf5..b14f3c0efa7e97e4b9c20362e7a962c4ca443232 100644 --- a/libcxx/include/__algorithm/remove_if.h +++ b/libcxx/include/__algorithm/remove_if.h @@ -23,7 +23,7 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { __first = std::find_if<_ForwardIterator, _Predicate&>(__first, __last, __pred); if (__first != __last) { diff --git a/libcxx/include/__algorithm/search.h b/libcxx/include/__algorithm/search.h index 8557c76f80c4094edd3f0b95bb0aca45071b40b0..b82ca7809535416c4005fd2c4f97744fed439cc9 100644 --- a/libcxx/include/__algorithm/search.h +++ b/libcxx/include/__algorithm/search.h @@ -160,7 +160,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __searc } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, @@ -173,14 +173,14 @@ search(_ForwardIterator1 __first1, } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { return std::search(__first1, __last1, __first2, __last2, __equal_to()); } #if _LIBCPP_STD_VER >= 17 template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher& __s) { return __s(__f, __l).first; } diff --git a/libcxx/include/__algorithm/search_n.h b/libcxx/include/__algorithm/search_n.h index 12007fa7dea0f188cce3153280ba8f954cfd6925..771647d3168a43f03bef02f88d7ee6de0bdb154b 100644 --- a/libcxx/include/__algorithm/search_n.h +++ b/libcxx/include/__algorithm/search_n.h @@ -136,7 +136,7 @@ __search_n_impl(_Iter1 __first, _Sent1 __last, _DiffT __count, const _Type& __va } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator search_n( +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator search_n( _ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value, _BinaryPredicate __pred) { static_assert( __is_callable<_BinaryPredicate, decltype(*__first), const _Tp&>::value, "BinaryPredicate has to be callable"); @@ -145,7 +145,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value) { return std::search_n(__first, __last, std::__convert_to_integral(__count), __value, __equal_to()); } diff --git a/libcxx/include/__algorithm/unique.h b/libcxx/include/__algorithm/unique.h index 056373d06fe44c5688fa474dcc7532149e598ca1..d597014596f2ea4245c70e071a3d806c95098adb 100644 --- a/libcxx/include/__algorithm/unique.h +++ b/libcxx/include/__algorithm/unique.h @@ -29,7 +29,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD // unique template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 std::pair<_Iter, _Iter> +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 std::pair<_Iter, _Iter> __unique(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) { __first = std::__adjacent_find(__first, __last, __pred); if (__first != __last) { @@ -46,13 +46,13 @@ __unique(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) { } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { return std::__unique<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred).first; } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator unique(_ForwardIterator __first, _ForwardIterator __last) { return std::unique(__first, __last, __equal_to()); } diff --git a/libcxx/include/__algorithm/upper_bound.h b/libcxx/include/__algorithm/upper_bound.h index 9c7d8fbcde07b5ac6bb2f429bb47da236029cbcf..c39dec2e89698247a20678edf575690aceef9f11 100644 --- a/libcxx/include/__algorithm/upper_bound.h +++ b/libcxx/include/__algorithm/upper_bound.h @@ -48,7 +48,7 @@ __upper_bound(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { static_assert(is_copy_constructible<_ForwardIterator>::value, "Iterator has to be copy constructible"); return std::__upper_bound<_ClassicAlgPolicy>( @@ -56,7 +56,7 @@ upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { return std::upper_bound(std::move(__first), std::move(__last), __value, __less<>()); } diff --git a/libcxx/include/__bit/bit_cast.h b/libcxx/include/__bit/bit_cast.h index 6298810f3733031fa45d23ca165a138cb21864b5..cd0456738179326923610cac599e8ed53ebe07a3 100644 --- a/libcxx/include/__bit/bit_cast.h +++ b/libcxx/include/__bit/bit_cast.h @@ -33,7 +33,7 @@ _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr _ToType __bit_cast(const _From template requires(sizeof(_ToType) == sizeof(_FromType) && is_trivially_copyable_v<_ToType> && is_trivially_copyable_v<_FromType>) -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _ToType bit_cast(const _FromType& __from) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _ToType bit_cast(const _FromType& __from) noexcept { return __builtin_bit_cast(_ToType, __from); } diff --git a/libcxx/include/__bit/bit_ceil.h b/libcxx/include/__bit/bit_ceil.h index 77fa739503bc58c0ca5d39574d4aa5169a81a608..cfd792dc2e2adbd04f0a1dc2177e06ec6d30e146 100644 --- a/libcxx/include/__bit/bit_ceil.h +++ b/libcxx/include/__bit/bit_ceil.h @@ -24,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp __bit_ceil(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp __bit_ceil(_Tp __t) noexcept { if (__t < 2) return 1; const unsigned __n = numeric_limits<_Tp>::digits - std::__countl_zero((_Tp)(__t - 1u)); @@ -42,7 +42,7 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp __bit_ceil(_Tp __t) no # if _LIBCPP_STD_VER >= 20 template <__libcpp_unsigned_integer _Tp> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept { return std::__bit_ceil(__t); } diff --git a/libcxx/include/__bit/bit_floor.h b/libcxx/include/__bit/bit_floor.h index cf5cf5803ad64fe9b617ddfc2ed8c7e5b864823e..133e369504e431c137505bf48affd394eb2c5bdb 100644 --- a/libcxx/include/__bit/bit_floor.h +++ b/libcxx/include/__bit/bit_floor.h @@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 template <__libcpp_unsigned_integer _Tp> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept { return __t == 0 ? 0 : _Tp{1} << std::__bit_log2(__t); } diff --git a/libcxx/include/__bit/bit_width.h b/libcxx/include/__bit/bit_width.h index a2020a01421e321d54c026f4c36ebcdf2911ba28..853e481776f7d2d2e705a978fa26ce5365072896 100644 --- a/libcxx/include/__bit/bit_width.h +++ b/libcxx/include/__bit/bit_width.h @@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <__libcpp_unsigned_integer _Tp> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept { return __t == 0 ? 0 : std::__bit_log2(__t) + 1; } diff --git a/libcxx/include/__bit/byteswap.h b/libcxx/include/__bit/byteswap.h index 20045d6fd43cb57a1e41f1a0356b5067f3d38cdd..6225ecf2f92dfb4fff1146e73a7272ccf2af7e1d 100644 --- a/libcxx/include/__bit/byteswap.h +++ b/libcxx/include/__bit/byteswap.h @@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 23 template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept { if constexpr (sizeof(_Tp) == 1) { return __val; } else if constexpr (sizeof(_Tp) == 2) { diff --git a/libcxx/include/__bit/countl.h b/libcxx/include/__bit/countl.h index 13df8d4e66c402610114bf5d3bb71f7231ae38f1..998a0b44c19dcb90fa4614fe309cadb19a9e1eb6 100644 --- a/libcxx/include/__bit/countl.h +++ b/libcxx/include/__bit/countl.h @@ -95,12 +95,12 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int __countl_zero(_Tp __t) _ #if _LIBCPP_STD_VER >= 20 template <__libcpp_unsigned_integer _Tp> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept { return std::__countl_zero(__t); } template <__libcpp_unsigned_integer _Tp> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept { return __t != numeric_limits<_Tp>::max() ? std::countl_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits; } diff --git a/libcxx/include/__bit/countr.h b/libcxx/include/__bit/countr.h index 724a0bc23801c49f13438f9678894a67e7467cdb..9e92021fba355188732e130c3449bf8b57dbe039 100644 --- a/libcxx/include/__bit/countr.h +++ b/libcxx/include/__bit/countr.h @@ -66,12 +66,12 @@ _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int __coun #if _LIBCPP_STD_VER >= 20 template <__libcpp_unsigned_integer _Tp> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept { return std::__countr_zero(__t); } template <__libcpp_unsigned_integer _Tp> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept { return __t != numeric_limits<_Tp>::max() ? std::countr_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits; } diff --git a/libcxx/include/__bit/has_single_bit.h b/libcxx/include/__bit/has_single_bit.h index a4e178060a73a3830de869649256a14f66122957..52f5853a1bc8a4092c636db0d5c4d683a9733f51 100644 --- a/libcxx/include/__bit/has_single_bit.h +++ b/libcxx/include/__bit/has_single_bit.h @@ -24,7 +24,7 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template <__libcpp_unsigned_integer _Tp> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept { return __t != 0 && (((__t & (__t - 1)) == 0)); } diff --git a/libcxx/include/__bit/popcount.h b/libcxx/include/__bit/popcount.h index 37b3a3e1f3f2b92d26c369d2729cf705d1ea60d7..5cf0a01d0733823c9708c4a9a11c50bc1a091f6c 100644 --- a/libcxx/include/__bit/popcount.h +++ b/libcxx/include/__bit/popcount.h @@ -41,7 +41,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_popcount(unsigned lo #if _LIBCPP_STD_VER >= 20 template <__libcpp_unsigned_integer _Tp> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept { # if __has_builtin(__builtin_popcountg) return __builtin_popcountg(__t); # else // __has_builtin(__builtin_popcountg) diff --git a/libcxx/include/__chrono/convert_to_tm.h b/libcxx/include/__chrono/convert_to_tm.h index f7256db3bea661101d5f5c2536fa21bbf1dce861..881a4970822d8e0bcb44e24865353f3247b8d1c0 100644 --- a/libcxx/include/__chrono/convert_to_tm.h +++ b/libcxx/include/__chrono/convert_to_tm.h @@ -173,7 +173,7 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _ChronoT& __value) { if (__value.hours().count() > std::numeric_limits::max()) std::__throw_format_error("Formatting hh_mm_ss, encountered an hour overflow"); __result.tm_hour = __value.hours().count(); -# if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +# if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) } else if constexpr (same_as<_ChronoT, chrono::sys_info>) { // Has no time information. } else if constexpr (same_as<_ChronoT, chrono::local_info>) { diff --git a/libcxx/include/__chrono/formatter.h b/libcxx/include/__chrono/formatter.h index 6a14c344fa1188c0cbd71289d0562d93c6c6a1f2..226fccbee6d1331a7ad75cb6c9a636c4cdb8f78a 100644 --- a/libcxx/include/__chrono/formatter.h +++ b/libcxx/include/__chrono/formatter.h @@ -205,7 +205,7 @@ struct _LIBCPP_HIDE_FROM_ABI __time_zone { template _LIBCPP_HIDE_FROM_ABI __time_zone __convert_to_time_zone([[maybe_unused]] const _Tp& __value) { -# if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +# if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) if constexpr (same_as<_Tp, chrono::sys_info>) return {__value.abbrev, __value.offset}; else @@ -417,7 +417,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_ok(const _Tp& __value) { return __value.weekday().ok(); else if constexpr (__is_hh_mm_ss<_Tp>) return true; -# if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +# if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) else if constexpr (same_as<_Tp, chrono::sys_info>) return true; else if constexpr (same_as<_Tp, chrono::local_info>) @@ -463,7 +463,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_name_ok(const _Tp& __value) { return __value.weekday().ok(); else if constexpr (__is_hh_mm_ss<_Tp>) return true; -# if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +# if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) else if constexpr (same_as<_Tp, chrono::sys_info>) return true; else if constexpr (same_as<_Tp, chrono::local_info>) @@ -509,7 +509,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __date_ok(const _Tp& __value) { return __value.ok(); else if constexpr (__is_hh_mm_ss<_Tp>) return true; -# if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +# if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) else if constexpr (same_as<_Tp, chrono::sys_info>) return true; else if constexpr (same_as<_Tp, chrono::local_info>) @@ -555,7 +555,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __month_name_ok(const _Tp& __value) { return __value.month().ok(); else if constexpr (__is_hh_mm_ss<_Tp>) return true; -# if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +# if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) else if constexpr (same_as<_Tp, chrono::sys_info>) return true; else if constexpr (same_as<_Tp, chrono::local_info>) @@ -891,7 +891,7 @@ public: } }; -# if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +# if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) template <__fmt_char_type _CharT> struct formatter : public __formatter_chrono<_CharT> { public: @@ -913,7 +913,7 @@ public: return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags{}); } }; -# endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +# endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) #endif // if _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/leap_second.h b/libcxx/include/__chrono/leap_second.h index 557abc15ff18470eb186111975e9d4acff483246..1a0e7f3107de81aa8b696fb324b2525099d3684c 100644 --- a/libcxx/include/__chrono/leap_second.h +++ b/libcxx/include/__chrono/leap_second.h @@ -14,7 +14,7 @@ #include // Enable the contents of the header only when libc++ was built with experimental features enabled. -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) # include <__chrono/duration.h> # include <__chrono/system_clock.h> @@ -43,9 +43,9 @@ public: _LIBCPP_HIDE_FROM_ABI leap_second(const leap_second&) = default; _LIBCPP_HIDE_FROM_ABI leap_second& operator=(const leap_second&) = default; - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr sys_seconds date() const noexcept { return __date_; } + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr sys_seconds date() const noexcept { return __date_; } - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr seconds value() const noexcept { return __value_; } + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr seconds value() const noexcept { return __value_; } private: sys_seconds __date_; @@ -121,6 +121,6 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>(const leap_second& __x, const s _LIBCPP_END_NAMESPACE_STD -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) #endif // _LIBCPP___CHRONO_LEAP_SECOND_H diff --git a/libcxx/include/__chrono/local_info.h b/libcxx/include/__chrono/local_info.h index b1a03ad7df2acab44fce1b44b04aff84ef372e97..cfe1448904d3f77831340bcad50e7fa3f6347828 100644 --- a/libcxx/include/__chrono/local_info.h +++ b/libcxx/include/__chrono/local_info.h @@ -14,7 +14,7 @@ #include // Enable the contents of the header only when libc++ was built with experimental features enabled. -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) # include <__chrono/sys_info.h> # include <__config> @@ -45,6 +45,6 @@ struct local_info { _LIBCPP_END_NAMESPACE_STD -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) #endif // _LIBCPP___CHRONO_LOCAL_INFO_H diff --git a/libcxx/include/__chrono/ostream.h b/libcxx/include/__chrono/ostream.h index cb17dbea58bee3606014379ac0c69596f92b0945..ecf07a320c8b945e68edae1cfbc8f15cf68e9543 100644 --- a/libcxx/include/__chrono/ostream.h +++ b/libcxx/include/__chrono/ostream.h @@ -264,7 +264,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const hh_mm_ss<_Duration> __hms return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%T}"), __hms); } -# if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +# if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) template _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& @@ -302,7 +302,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const local_info& __info) { _LIBCPP_STATICALLY_WIDEN(_CharT, "{}: {{{}, {}}}"), __result(), __info.first, __info.second); } -# endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +# endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) } // namespace chrono diff --git a/libcxx/include/__chrono/sys_info.h b/libcxx/include/__chrono/sys_info.h index 461d5322d413b3a4bf3c2ec2be2b41532f34f6b8..11536cbde3a37c481cd0fce344f040708f5503a4 100644 --- a/libcxx/include/__chrono/sys_info.h +++ b/libcxx/include/__chrono/sys_info.h @@ -14,7 +14,7 @@ #include // Enable the contents of the header only when libc++ was built with experimental features enabled. -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) # include <__chrono/duration.h> # include <__chrono/system_clock.h> @@ -46,6 +46,6 @@ struct sys_info { _LIBCPP_END_NAMESPACE_STD -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) #endif // _LIBCPP___CHRONO_SYS_INFO_H diff --git a/libcxx/include/__chrono/time_zone.h b/libcxx/include/__chrono/time_zone.h index 8e30034b799ad9feea959942988ac9fd565feed3..91ddab8903fe219b235825dacaa08ee036302f17 100644 --- a/libcxx/include/__chrono/time_zone.h +++ b/libcxx/include/__chrono/time_zone.h @@ -14,7 +14,7 @@ #include // Enable the contents of the header only when libc++ was built with experimental features enabled. -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) # include <__chrono/duration.h> # include <__chrono/sys_info.h> @@ -56,10 +56,10 @@ public: _LIBCPP_HIDE_FROM_ABI time_zone(time_zone&&) = default; _LIBCPP_HIDE_FROM_ABI time_zone& operator=(time_zone&&) = default; - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI string_view name() const noexcept { return __name(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_view name() const noexcept { return __name(); } template - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI sys_info get_info(const sys_time<_Duration>& __time) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI sys_info get_info(const sys_time<_Duration>& __time) const { return __get_info(chrono::time_point_cast(__time)); } @@ -73,12 +73,12 @@ private: unique_ptr<__impl> __impl_; }; -_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline bool +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline bool operator==(const time_zone& __x, const time_zone& __y) noexcept { return __x.name() == __y.name(); } -_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline strong_ordering +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline strong_ordering operator<=>(const time_zone& __x, const time_zone& __y) noexcept { return __x.name() <=> __y.name(); } @@ -92,6 +92,6 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) #endif // _LIBCPP___CHRONO_TIME_ZONE_H diff --git a/libcxx/include/__chrono/time_zone_link.h b/libcxx/include/__chrono/time_zone_link.h index c76ddeff9f966d020b0d4ed29990322a387194aa..b2d365c5fd0820db7076fa1f4bb0c3d0563f9d4b 100644 --- a/libcxx/include/__chrono/time_zone_link.h +++ b/libcxx/include/__chrono/time_zone_link.h @@ -14,7 +14,7 @@ #include // Enable the contents of the header only when libc++ was built with experimental features enabled. -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) # include <__compare/strong_order.h> # include <__config> @@ -38,15 +38,15 @@ namespace chrono { class time_zone_link { public: - _LIBCPP_NODISCARD_EXT + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit time_zone_link(__private_constructor_tag, string_view __name, string_view __target) : __name_{__name}, __target_{__target} {} _LIBCPP_HIDE_FROM_ABI time_zone_link(time_zone_link&&) = default; _LIBCPP_HIDE_FROM_ABI time_zone_link& operator=(time_zone_link&&) = default; - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI string_view name() const noexcept { return __name_; } - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI string_view target() const noexcept { return __target_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_view name() const noexcept { return __name_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_view target() const noexcept { return __target_; } private: string __name_; @@ -56,12 +56,12 @@ private: string __target_; }; -_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline bool +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline bool operator==(const time_zone_link& __x, const time_zone_link& __y) noexcept { return __x.name() == __y.name(); } -_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline strong_ordering +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline strong_ordering operator<=>(const time_zone_link& __x, const time_zone_link& __y) noexcept { return __x.name() <=> __y.name(); } @@ -74,6 +74,6 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) #endif // _LIBCPP___CHRONO_TIME_ZONE_LINK_H diff --git a/libcxx/include/__chrono/tzdb.h b/libcxx/include/__chrono/tzdb.h index e0bfedf0d78239e65dd883886e09b9d83aeda5a7..f731f8c318be079ab251014963636b9eda5c4a6c 100644 --- a/libcxx/include/__chrono/tzdb.h +++ b/libcxx/include/__chrono/tzdb.h @@ -14,7 +14,7 @@ #include // Enable the contents of the header only when libc++ was built with experimental features enabled. -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) # include <__algorithm/ranges_lower_bound.h> # include <__chrono/leap_second.h> @@ -57,14 +57,14 @@ struct tzdb { return nullptr; } - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI const time_zone* locate_zone(string_view __name) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const time_zone* locate_zone(string_view __name) const { if (const time_zone* __result = __locate_zone(__name)) return __result; std::__throw_runtime_error("tzdb: requested time zone not found"); } - _LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI const time_zone* current_zone() const { + [[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI const time_zone* current_zone() const { return __current_zone(); } @@ -89,6 +89,6 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) #endif // _LIBCPP___CHRONO_TZDB_H diff --git a/libcxx/include/__chrono/tzdb_list.h b/libcxx/include/__chrono/tzdb_list.h index 693899d372112dead062faa49eca871ace8b2ea9..62db7e3d2e0b5e3597e7cd3f30bfd0e2140d8971 100644 --- a/libcxx/include/__chrono/tzdb_list.h +++ b/libcxx/include/__chrono/tzdb_list.h @@ -14,7 +14,7 @@ #include // Enable the contents of the header only when libc++ was built with experimental features enabled. -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) # include <__availability> # include <__chrono/time_zone.h> @@ -53,15 +53,15 @@ public: using const_iterator = forward_list::const_iterator; - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI const tzdb& front() const noexcept { return __front(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const tzdb& front() const noexcept { return __front(); } _LIBCPP_HIDE_FROM_ABI const_iterator erase_after(const_iterator __p) { return __erase_after(__p); } - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI const_iterator begin() const noexcept { return __begin(); } - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI const_iterator end() const noexcept { return __end(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const noexcept { return __begin(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const noexcept { return __end(); } - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const noexcept { return __cbegin(); } - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI const_iterator cend() const noexcept { return __cend(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const noexcept { return __cbegin(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const noexcept { return __cend(); } [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __impl& __implementation() { return *__impl_; } @@ -79,24 +79,23 @@ private: __impl* __impl_; }; -_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI tzdb_list& get_tzdb_list(); +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI tzdb_list& get_tzdb_list(); -_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline const tzdb& get_tzdb() { +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline const tzdb& get_tzdb() { return get_tzdb_list().front(); } -_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline const time_zone* -locate_zone(string_view __name) { +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline const time_zone* locate_zone(string_view __name) { return get_tzdb().locate_zone(__name); } -_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline const time_zone* current_zone() { +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline const time_zone* current_zone() { return get_tzdb().current_zone(); } _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI const tzdb& reload_tzdb(); -_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI string remote_version(); +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI string remote_version(); } // namespace chrono @@ -105,6 +104,6 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI string _LIBCPP_END_NAMESPACE_STD -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) +#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) #endif // _LIBCPP___CHRONO_TZDB_LIST_H diff --git a/libcxx/include/__config b/libcxx/include/__config index 4ccef2ca0d73b4d42c1de5c1f95ec06ea50b56ae..97cdd020c55d1f5d3c3c7d6ee6cb923631164c7b 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -421,7 +421,7 @@ _LIBCPP_HARDENING_MODE_DEBUG # if !defined(_LIBCPP_ENABLE_EXPERIMENTAL) && !defined(_LIBCPP_BUILDING_LIBRARY) # define _LIBCPP_HAS_NO_INCOMPLETE_PSTL # define _LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN -# define _LIBCPP_HAS_NO_INCOMPLETE_TZDB +# define _LIBCPP_HAS_NO_EXPERIMENTAL_TZDB # define _LIBCPP_HAS_NO_EXPERIMENTAL_SYNCSTREAM # endif @@ -1375,7 +1375,7 @@ typedef __char32_t char32_t; # define _LIBCPP_USING_IF_EXISTS # endif -# if __has_cpp_attribute(nodiscard) +# if __has_cpp_attribute(__nodiscard__) # define _LIBCPP_NODISCARD [[__nodiscard__]] # else // We can't use GCC's [[gnu::warn_unused_result]] and @@ -1384,20 +1384,6 @@ typedef __char32_t char32_t; # define _LIBCPP_NODISCARD # endif -// _LIBCPP_NODISCARD_EXT may be used to apply [[nodiscard]] to entities not -// specified as such as an extension. -# if !defined(_LIBCPP_DISABLE_NODISCARD_EXT) -# define _LIBCPP_NODISCARD_EXT _LIBCPP_NODISCARD -# else -# define _LIBCPP_NODISCARD_EXT -# endif - -# if _LIBCPP_STD_VER >= 20 || !defined(_LIBCPP_DISABLE_NODISCARD_EXT) -# define _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_NODISCARD -# else -# define _LIBCPP_NODISCARD_AFTER_CXX17 -# endif - # if __has_attribute(__no_destroy__) # define _LIBCPP_NO_DESTROY __attribute__((__no_destroy__)) # else diff --git a/libcxx/include/__filesystem/path.h b/libcxx/include/__filesystem/path.h index 9ffc90ada5e716d120ddb22aab484daef449ed40..89d319b4b19b57c77743ce08e14475e08418c8bf 100644 --- a/libcxx/include/__filesystem/path.h +++ b/libcxx/include/__filesystem/path.h @@ -812,7 +812,7 @@ public: _LIBCPP_HIDE_FROM_ABI path extension() const { return string_type(__extension()); } // query - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool empty() const noexcept { return __pn_.empty(); } + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool empty() const noexcept { return __pn_.empty(); } _LIBCPP_HIDE_FROM_ABI bool has_root_name() const { return !__root_name().empty(); } _LIBCPP_HIDE_FROM_ABI bool has_root_directory() const { return !__root_directory().empty(); } diff --git a/libcxx/include/__format/format_functions.h b/libcxx/include/__format/format_functions.h index c7810140105a07225e522d9719e61a385815003f..d14b49aff149573e85cdff3ac2b7cbd5bcd5341d 100644 --- a/libcxx/include/__format/format_functions.h +++ b/libcxx/include/__format/format_functions.h @@ -66,14 +66,13 @@ using wformat_args = basic_format_args; # endif template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> make_format_args(_Args&... __args) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> make_format_args(_Args&... __args) { return std::__format_arg_store<_Context, _Args...>(__args...); } # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI __format_arg_store -make_wformat_args(_Args&... __args) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI __format_arg_store make_wformat_args(_Args&... __args) { return std::__format_arg_store(__args...); } # endif @@ -452,8 +451,7 @@ format_to(_OutIt __out_it, wformat_string<_Args...> __fmt, _Args&&... __args) { // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup // fires too eagerly, see http://llvm.org/PR61563. template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string -vformat(string_view __fmt, format_args __args) { +[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string vformat(string_view __fmt, format_args __args) { string __res; std::vformat_to(std::back_inserter(__res), __fmt, __args); return __res; @@ -463,7 +461,7 @@ vformat(string_view __fmt, format_args __args) { // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup // fires too eagerly, see http://llvm.org/PR61563. template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring +[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring vformat(wstring_view __fmt, wformat_args __args) { wstring __res; std::vformat_to(std::back_inserter(__res), __fmt, __args); @@ -472,14 +470,14 @@ vformat(wstring_view __fmt, wformat_args __args) { # endif template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string format(format_string<_Args...> __fmt, _Args&&... __args) { return std::vformat(__fmt.get(), std::make_format_args(__args...)); } # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring format(wformat_string<_Args...> __fmt, _Args&&... __args) { return std::vformat(__fmt.get(), std::make_wformat_args(__args...)); } @@ -520,14 +518,14 @@ _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(basic_string_view<_CharT> __fmt, } template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t formatted_size(format_string<_Args...> __fmt, _Args&&... __args) { return std::__vformatted_size(__fmt.get(), basic_format_args{std::make_format_args(__args...)}); } # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t formatted_size(wformat_string<_Args...> __fmt, _Args&&... __args) { return std::__vformatted_size(__fmt.get(), basic_format_args{std::make_wformat_args(__args...)}); } @@ -585,7 +583,7 @@ format_to(_OutIt __out_it, locale __loc, wformat_string<_Args...> __fmt, _Args&& // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup // fires too eagerly, see http://llvm.org/PR61563. template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string +[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string vformat(locale __loc, string_view __fmt, format_args __args) { string __res; std::vformat_to(std::back_inserter(__res), std::move(__loc), __fmt, __args); @@ -596,7 +594,7 @@ vformat(locale __loc, string_view __fmt, format_args __args) { // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup // fires too eagerly, see http://llvm.org/PR61563. template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring +[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring vformat(locale __loc, wstring_view __fmt, wformat_args __args) { wstring __res; std::vformat_to(std::back_inserter(__res), std::move(__loc), __fmt, __args); @@ -605,14 +603,14 @@ vformat(locale __loc, wstring_view __fmt, wformat_args __args) { # endif template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string format(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) { return std::vformat(std::move(__loc), __fmt.get(), std::make_format_args(__args...)); } # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring format(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) { return std::vformat(std::move(__loc), __fmt.get(), std::make_wformat_args(__args...)); } @@ -658,14 +656,14 @@ _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(locale __loc, basic_string_view<_ } template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t formatted_size(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) { return std::__vformatted_size(std::move(__loc), __fmt.get(), basic_format_args{std::make_format_args(__args...)}); } # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t formatted_size(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) { return std::__vformatted_size(std::move(__loc), __fmt.get(), basic_format_args{std::make_wformat_args(__args...)}); } diff --git a/libcxx/include/__functional/identity.h b/libcxx/include/__functional/identity.h index b7be367bd5eed7a4fa05d22dbc849040dc73275c..8468de3dae26c2ca4a1657a1f23688c684afc699 100644 --- a/libcxx/include/__functional/identity.h +++ b/libcxx/include/__functional/identity.h @@ -44,7 +44,7 @@ struct __is_identity > : true_type {}; struct identity { template - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator()(_Tp&& __t) const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator()(_Tp&& __t) const noexcept { return std::forward<_Tp>(__t); } diff --git a/libcxx/include/__iterator/empty.h b/libcxx/include/__iterator/empty.h index 3ca0aff6be46efb2ea7c19a241ec1cf55a4f9312..773f2776955b2a16707e1805e40967e35757cbef 100644 --- a/libcxx/include/__iterator/empty.h +++ b/libcxx/include/__iterator/empty.h @@ -23,18 +23,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 template -_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI constexpr auto empty(const _Cont& __c) - _NOEXCEPT_(noexcept(__c.empty())) -> decltype(__c.empty()) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto +empty(const _Cont& __c) noexcept(noexcept(__c.empty())) -> decltype(__c.empty()) { return __c.empty(); } template -_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI constexpr bool empty(const _Tp (&)[_Sz]) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty(const _Tp (&)[_Sz]) noexcept { return false; } template -_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI constexpr bool empty(initializer_list<_Ep> __il) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; } diff --git a/libcxx/include/__math/abs.h b/libcxx/include/__math/abs.h index 6004690f4c4f4c352190a5d2ad5ca1c55590e508..ab82a2800f53c918c5cdf6cdfc9ade264167f245 100644 --- a/libcxx/include/__math/abs.h +++ b/libcxx/include/__math/abs.h @@ -23,19 +23,19 @@ namespace __math { // fabs -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float fabs(float __x) _NOEXCEPT { return __builtin_fabsf(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float fabs(float __x) _NOEXCEPT { return __builtin_fabsf(__x); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double fabs(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI double fabs(double __x) _NOEXCEPT { return __builtin_fabs(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double fabs(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double fabs(long double __x) _NOEXCEPT { return __builtin_fabsl(__x); } template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI double fabs(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI double fabs(_A1 __x) _NOEXCEPT { return __builtin_fabs((double)__x); } diff --git a/libcxx/include/__math/copysign.h b/libcxx/include/__math/copysign.h index 2219297e8b8c1eae2fb06acff1151eaf5a94d7ea..b38690bb581a1155325bf9a25d4e2a4399a8e7b2 100644 --- a/libcxx/include/__math/copysign.h +++ b/libcxx/include/__math/copysign.h @@ -25,17 +25,16 @@ namespace __math { // copysign -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float copysign(float __x, float __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float copysign(float __x, float __y) _NOEXCEPT { return ::__builtin_copysignf(__x, __y); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double copysign(long double __x, long double __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double copysign(long double __x, long double __y) _NOEXCEPT { return ::__builtin_copysignl(__x, __y); } template ::value && is_arithmetic<_A2>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type -copysign(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type copysign(_A1 __x, _A2 __y) _NOEXCEPT { return ::__builtin_copysign(__x, __y); } diff --git a/libcxx/include/__math/min_max.h b/libcxx/include/__math/min_max.h index 381b2af4a56cf0c705e180eb98873e00a9673820..c2c4f6b645609ce9b9d1b85f653573b927ac5993 100644 --- a/libcxx/include/__math/min_max.h +++ b/libcxx/include/__math/min_max.h @@ -25,21 +25,21 @@ namespace __math { // fmax -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float fmax(float __x, float __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float fmax(float __x, float __y) _NOEXCEPT { return __builtin_fmaxf(__x, __y); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double fmax(double __x, double __y) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI double fmax(double __x, double __y) _NOEXCEPT { return __builtin_fmax(__x, __y); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double fmax(long double __x, long double __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double fmax(long double __x, long double __y) _NOEXCEPT { return __builtin_fmaxl(__x, __y); } template ::value && is_arithmetic<_A2>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type fmax(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type fmax(_A1 __x, _A2 __y) _NOEXCEPT { using __result_type = typename __promote<_A1, _A2>::type; static_assert((!(_IsSame<_A1, __result_type>::value && _IsSame<_A2, __result_type>::value)), ""); return __math::fmax((__result_type)__x, (__result_type)__y); @@ -47,21 +47,21 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>: // fmin -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float fmin(float __x, float __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float fmin(float __x, float __y) _NOEXCEPT { return __builtin_fminf(__x, __y); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double fmin(double __x, double __y) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI double fmin(double __x, double __y) _NOEXCEPT { return __builtin_fmin(__x, __y); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double fmin(long double __x, long double __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double fmin(long double __x, long double __y) _NOEXCEPT { return __builtin_fminl(__x, __y); } template ::value && is_arithmetic<_A2>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type fmin(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type fmin(_A1 __x, _A2 __y) _NOEXCEPT { using __result_type = typename __promote<_A1, _A2>::type; static_assert((!(_IsSame<_A1, __result_type>::value && _IsSame<_A2, __result_type>::value)), ""); return __math::fmin((__result_type)__x, (__result_type)__y); diff --git a/libcxx/include/__math/roots.h b/libcxx/include/__math/roots.h index faee688bc95b82530feef87676233e2157d9ce16..359fd747cfbef396cc28b42784fcd67c027344c7 100644 --- a/libcxx/include/__math/roots.h +++ b/libcxx/include/__math/roots.h @@ -39,19 +39,19 @@ inline _LIBCPP_HIDE_FROM_ABI double sqrt(_A1 __x) _NOEXCEPT { // cbrt -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float cbrt(float __x) _NOEXCEPT { return __builtin_cbrtf(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float cbrt(float __x) _NOEXCEPT { return __builtin_cbrtf(__x); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double cbrt(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI double cbrt(double __x) _NOEXCEPT { return __builtin_cbrt(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double cbrt(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double cbrt(long double __x) _NOEXCEPT { return __builtin_cbrtl(__x); } template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI double cbrt(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI double cbrt(_A1 __x) _NOEXCEPT { return __builtin_cbrt((double)__x); } diff --git a/libcxx/include/__math/rounding_functions.h b/libcxx/include/__math/rounding_functions.h index 29e42fd80b00d60f984cd82124927cb155a6015a..33e6cbc37d604ccdbc7c656d2f3790b5f3bd03cf 100644 --- a/libcxx/include/__math/rounding_functions.h +++ b/libcxx/include/__math/rounding_functions.h @@ -26,37 +26,37 @@ namespace __math { // ceil -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float ceil(float __x) _NOEXCEPT { return __builtin_ceilf(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float ceil(float __x) _NOEXCEPT { return __builtin_ceilf(__x); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double ceil(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI double ceil(double __x) _NOEXCEPT { return __builtin_ceil(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double ceil(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double ceil(long double __x) _NOEXCEPT { return __builtin_ceill(__x); } template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI double ceil(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI double ceil(_A1 __x) _NOEXCEPT { return __builtin_ceil((double)__x); } // floor -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float floor(float __x) _NOEXCEPT { return __builtin_floorf(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float floor(float __x) _NOEXCEPT { return __builtin_floorf(__x); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double floor(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI double floor(double __x) _NOEXCEPT { return __builtin_floor(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double floor(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double floor(long double __x) _NOEXCEPT { return __builtin_floorl(__x); } template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI double floor(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI double floor(_A1 __x) _NOEXCEPT { return __builtin_floor((double)__x); } @@ -126,21 +126,21 @@ inline _LIBCPP_HIDE_FROM_ABI long lround(_A1 __x) _NOEXCEPT { // nearbyint -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float nearbyint(float __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float nearbyint(float __x) _NOEXCEPT { return __builtin_nearbyintf(__x); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double nearbyint(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI double nearbyint(double __x) _NOEXCEPT { return __builtin_nearbyint(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double nearbyint(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double nearbyint(long double __x) _NOEXCEPT { return __builtin_nearbyintl(__x); } template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI double nearbyint(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI double nearbyint(_A1 __x) _NOEXCEPT { return __builtin_nearbyint((double)__x); } @@ -186,55 +186,55 @@ inline _LIBCPP_HIDE_FROM_ABI double nexttoward(_A1 __x, long double __y) _NOEXCE // rint -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float rint(float __x) _NOEXCEPT { return __builtin_rintf(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float rint(float __x) _NOEXCEPT { return __builtin_rintf(__x); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double rint(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI double rint(double __x) _NOEXCEPT { return __builtin_rint(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double rint(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double rint(long double __x) _NOEXCEPT { return __builtin_rintl(__x); } template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI double rint(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI double rint(_A1 __x) _NOEXCEPT { return __builtin_rint((double)__x); } // round -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float round(float __x) _NOEXCEPT { return __builtin_round(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float round(float __x) _NOEXCEPT { return __builtin_round(__x); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double round(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI double round(double __x) _NOEXCEPT { return __builtin_round(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double round(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double round(long double __x) _NOEXCEPT { return __builtin_roundl(__x); } template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI double round(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI double round(_A1 __x) _NOEXCEPT { return __builtin_round((double)__x); } // trunc -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float trunc(float __x) _NOEXCEPT { return __builtin_trunc(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float trunc(float __x) _NOEXCEPT { return __builtin_trunc(__x); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double trunc(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI double trunc(double __x) _NOEXCEPT { return __builtin_trunc(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double trunc(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double trunc(long double __x) _NOEXCEPT { return __builtin_truncl(__x); } template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI double trunc(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI double trunc(_A1 __x) _NOEXCEPT { return __builtin_trunc((double)__x); } diff --git a/libcxx/include/__math/traits.h b/libcxx/include/__math/traits.h index da585af8837f0cbe9af67cb79cd9dd362ace78b7..a4482667975576cb3bc8b94d5b42d3788f46a49f 100644 --- a/libcxx/include/__math/traits.h +++ b/libcxx/include/__math/traits.h @@ -29,55 +29,55 @@ namespace __math { // signbit template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT { return __builtin_signbit(__x); } template ::value && is_signed<_A1>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT { return __x < 0; } template ::value && !is_signed<_A1>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1) _NOEXCEPT { return false; } // isfinite template ::value && numeric_limits<_A1>::has_infinity, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1 __x) _NOEXCEPT { return __builtin_isfinite((typename __promote<_A1>::type)__x); } template ::value && !numeric_limits<_A1>::has_infinity, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1) _NOEXCEPT { return true; } // isinf template ::value && numeric_limits<_A1>::has_infinity, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1 __x) _NOEXCEPT { return __builtin_isinf((typename __promote<_A1>::type)__x); } template ::value && !numeric_limits<_A1>::has_infinity, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1) _NOEXCEPT { return false; } #ifdef _LIBCPP_PREFERRED_OVERLOAD -_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(float __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(float __x) _NOEXCEPT { return __builtin_isinf(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool +_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool isinf(double __x) _NOEXCEPT { return __builtin_isinf(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(long double __x) _NOEXCEPT { return __builtin_isinf(__x); } #endif @@ -85,26 +85,26 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI // isnan template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1 __x) _NOEXCEPT { return __builtin_isnan(__x); } template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1) _NOEXCEPT { return false; } #ifdef _LIBCPP_PREFERRED_OVERLOAD -_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(float __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(float __x) _NOEXCEPT { return __builtin_isnan(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool +_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool isnan(double __x) _NOEXCEPT { return __builtin_isnan(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(long double __x) _NOEXCEPT { return __builtin_isnan(__x); } #endif @@ -112,19 +112,19 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI // isnormal template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT { return __builtin_isnormal(__x); } template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT { return __x != 0; } // isgreater template ::value && is_arithmetic<_A2>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 __y) _NOEXCEPT { using type = typename __promote<_A1, _A2>::type; return __builtin_isgreater((type)__x, (type)__y); } @@ -132,7 +132,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 _ // isgreaterequal template ::value && is_arithmetic<_A2>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT { using type = typename __promote<_A1, _A2>::type; return __builtin_isgreaterequal((type)__x, (type)__y); } @@ -140,7 +140,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, // isless template ::value && is_arithmetic<_A2>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) _NOEXCEPT { using type = typename __promote<_A1, _A2>::type; return __builtin_isless((type)__x, (type)__y); } @@ -148,7 +148,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) // islessequal template ::value && is_arithmetic<_A2>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 __y) _NOEXCEPT { using type = typename __promote<_A1, _A2>::type; return __builtin_islessequal((type)__x, (type)__y); } @@ -156,7 +156,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 // islessgreater template ::value && is_arithmetic<_A2>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _A2 __y) _NOEXCEPT { using type = typename __promote<_A1, _A2>::type; return __builtin_islessgreater((type)__x, (type)__y); } @@ -164,7 +164,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _ // isunordered template ::value && is_arithmetic<_A2>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2 __y) _NOEXCEPT { using type = typename __promote<_A1, _A2>::type; return __builtin_isunordered((type)__x, (type)__y); } diff --git a/libcxx/include/__memory/allocator.h b/libcxx/include/__memory/allocator.h index 26e5d4978b151e0830c6334935ce0e7e210b9280..215d3832f9ef341de1a13326af11ad08cb21d53f 100644 --- a/libcxx/include/__memory/allocator.h +++ b/libcxx/include/__memory/allocator.h @@ -110,7 +110,7 @@ public: template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator(const allocator<_Up>&) _NOEXCEPT {} - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp* allocate(size_t __n) { + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp* allocate(size_t __n) { if (__n > allocator_traits::max_size(*this)) __throw_bad_array_new_length(); if (__libcpp_is_constant_evaluated()) { @@ -153,8 +153,7 @@ public: return std::addressof(__x); } - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 _Tp* - allocate(size_t __n, const void*) { + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 _Tp* allocate(size_t __n, const void*) { return allocate(__n); } @@ -190,7 +189,7 @@ public: template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator(const allocator<_Up>&) _NOEXCEPT {} - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const _Tp* allocate(size_t __n) { + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const _Tp* allocate(size_t __n) { if (__n > allocator_traits::max_size(*this)) __throw_bad_array_new_length(); if (__libcpp_is_constant_evaluated()) { @@ -230,8 +229,7 @@ public: return std::addressof(__x); } - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 const _Tp* - allocate(size_t __n, const void*) { + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 const _Tp* allocate(size_t __n, const void*) { return allocate(__n); } diff --git a/libcxx/include/__memory/allocator_traits.h b/libcxx/include/__memory/allocator_traits.h index 7b3deb0f58e950cecf0adfa46d583202713ac1c4..47fe132d15cb1f82bab97fb99ffe1d9c21c764d3 100644 --- a/libcxx/include/__memory/allocator_traits.h +++ b/libcxx/include/__memory/allocator_traits.h @@ -275,13 +275,13 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits { }; #endif // _LIBCPP_CXX03_LANG - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer allocate(allocator_type& __a, size_type __n) { return __a.allocate(__n); } template ::value, int> = 0> - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer allocate(allocator_type& __a, size_type __n, const_void_pointer __hint) { _LIBCPP_SUPPRESS_DEPRECATED_PUSH return __a.allocate(__n, __hint); @@ -290,7 +290,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits { template ::value, int> = 0> - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer allocate(allocator_type& __a, size_type __n, const_void_pointer) { return __a.allocate(__n); } diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h index e3797caff8c9f2065401960fa003d0db633d81ea..88799ca95c1f352c80698661ee3c4738c77cf902 100644 --- a/libcxx/include/__memory/temporary_buffer.h +++ b/libcxx/include/__memory/temporary_buffer.h @@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t> +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { pair<_Tp*, ptrdiff_t> __r(0, 0); const ptrdiff_t __m = diff --git a/libcxx/include/__memory/uses_allocator_construction.h b/libcxx/include/__memory/uses_allocator_construction.h index 9b7262bec5cf8bfe7a03515782ad8b6ceeec4c8f..5e5819d4c281e4c462a702c6503b988512196f31 100644 --- a/libcxx/include/__memory/uses_allocator_construction.h +++ b/libcxx/include/__memory/uses_allocator_construction.h @@ -184,20 +184,18 @@ __uses_allocator_construction_args(const _Alloc& __alloc, _Type&& __value) noexc struct __pair_constructor { using _PairMutable = remove_cv_t<_Pair>; - _LIBCPP_HIDE_FROM_ABI constexpr auto __do_construct(const _PairMutable& __pair) const { + _LIBCPP_HIDDEN constexpr auto __do_construct(const _PairMutable& __pair) const { return std::__make_obj_using_allocator<_PairMutable>(__alloc_, __pair); } - _LIBCPP_HIDE_FROM_ABI constexpr auto __do_construct(_PairMutable&& __pair) const { + _LIBCPP_HIDDEN constexpr auto __do_construct(_PairMutable&& __pair) const { return std::__make_obj_using_allocator<_PairMutable>(__alloc_, std::move(__pair)); } const _Alloc& __alloc_; _Type& __value_; - _LIBCPP_HIDE_FROM_ABI constexpr operator _PairMutable() const { - return __do_construct(std::forward<_Type>(this->__value_)); - } + _LIBCPP_HIDDEN constexpr operator _PairMutable() const { return __do_construct(std::forward<_Type>(__value_)); } }; return std::make_tuple(__pair_constructor{__alloc, __value}); diff --git a/libcxx/include/__memory_resource/memory_resource.h b/libcxx/include/__memory_resource/memory_resource.h index 418f36dc9b390d729d4aa967f64bc98b9599d4d2..e605838bf5ea4096b270352daaf1f884a493e3c8 100644 --- a/libcxx/include/__memory_resource/memory_resource.h +++ b/libcxx/include/__memory_resource/memory_resource.h @@ -32,9 +32,8 @@ class _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource { public: virtual ~memory_resource(); - _LIBCPP_NODISCARD_AFTER_CXX17 - [[using __gnu__: __returns_nonnull__, __alloc_size__(2), __alloc_align__(3)]] _LIBCPP_HIDE_FROM_ABI void* - allocate(size_t __bytes, size_t __align = __max_align) { + [[nodiscard]] [[using __gnu__: __returns_nonnull__, __alloc_size__(2), __alloc_align__(3)]] + _LIBCPP_HIDE_FROM_ABI void* allocate(size_t __bytes, size_t __align = __max_align) { return do_allocate(__bytes, __align); } diff --git a/libcxx/include/__memory_resource/polymorphic_allocator.h b/libcxx/include/__memory_resource/polymorphic_allocator.h index 823c1503c22b65be76098614ee0cee2fc6fbff78..8fda201124387e82dcebdac05b14eebab2959000 100644 --- a/libcxx/include/__memory_resource/polymorphic_allocator.h +++ b/libcxx/include/__memory_resource/polymorphic_allocator.h @@ -61,7 +61,7 @@ public: // [mem.poly.allocator.mem] - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _ValueType* allocate(size_t __n) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _ValueType* allocate(size_t __n) { if (__n > __max_size()) { __throw_bad_array_new_length(); } diff --git a/libcxx/include/__mutex/lock_guard.h b/libcxx/include/__mutex/lock_guard.h index c075512fb97a95bdb9f13710ece20c50532101b7..739d1683b317b0a1a37c5928c39b88076b53b6c5 100644 --- a/libcxx/include/__mutex/lock_guard.h +++ b/libcxx/include/__mutex/lock_guard.h @@ -29,13 +29,13 @@ private: mutex_type& __m_; public: - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI explicit lock_guard(mutex_type& __m) - _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m)) + _LIBCPP_NODISCARD + _LIBCPP_HIDE_FROM_ABI explicit lock_guard(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m)) : __m_(__m) { __m_.lock(); } - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI lock_guard(mutex_type& __m, adopt_lock_t) + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI lock_guard(mutex_type& __m, adopt_lock_t) _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m)) : __m_(__m) {} _LIBCPP_HIDE_FROM_ABI ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) { __m_.unlock(); } diff --git a/libcxx/include/__node_handle b/libcxx/include/__node_handle index 24d2624c37394618c0a69340ed9fcf0ebb480712..d0b35bfd193409d0c868369db84aff4c15dc3711 100644 --- a/libcxx/include/__node_handle +++ b/libcxx/include/__node_handle @@ -147,7 +147,7 @@ public: _LIBCPP_HIDE_FROM_ABI explicit operator bool() const { return __ptr_ != nullptr; } - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool empty() const { return __ptr_ == nullptr; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool empty() const { return __ptr_ == nullptr; } _LIBCPP_HIDE_FROM_ABI void swap(__basic_node_handle& __other) noexcept( __alloc_traits::propagate_on_container_swap::value || __alloc_traits::is_always_equal::value) { diff --git a/libcxx/include/__random/linear_congruential_engine.h b/libcxx/include/__random/linear_congruential_engine.h index fe9cb909b74d21a3134452a6356d1363dcf6af4a..9d77649e9cfc8e04b4f778d15b6f2100a9694f36 100644 --- a/libcxx/include/__random/linear_congruential_engine.h +++ b/libcxx/include/__random/linear_congruential_engine.h @@ -26,32 +26,60 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD +enum __lce_alg_type { + _LCE_Full, + _LCE_Part, + _LCE_Schrage, + _LCE_Promote, +}; + template (_Mp - __c) / __a), - bool _OverflowOK = ((__m & (__m - 1)) == 0ull), // m = 2^n - bool _SchrageOK = (__a != 0 && __m != 0 && __m % __a <= __m / __a)> // r <= q + bool _HasOverflow = (__a != 0ull && (__m & (__m - 1ull)) != 0ull), // a != 0, m != 0, m != 2^n + bool _Full = (!_HasOverflow || __m - 1ull <= (_Mp - __c) / __a), // (a * x + c) % m works + bool _Part = (!_HasOverflow || __m - 1ull <= _Mp / __a), // (a * x) % m works + bool _Schrage = (_HasOverflow && __m % __a <= __m / __a)> // r <= q struct __lce_alg_picker { - static_assert(!_MightOverflow || _OverflowOK || _SchrageOK, - "The current values of a, c, and m cannot generate a number " - "within bounds of linear_congruential_engine."); - - static _LIBCPP_CONSTEXPR const bool __use_schrage = _MightOverflow && !_OverflowOK && _SchrageOK; + static _LIBCPP_CONSTEXPR const __lce_alg_type __mode = + _Full ? _LCE_Full + : _Part ? _LCE_Part + : _Schrage ? _LCE_Schrage + : _LCE_Promote; + +#ifdef _LIBCPP_HAS_NO_INT128 + static_assert(_Mp != (unsigned long long)(-1) || _Full || _Part || _Schrage, + "The current values for a, c, and m are not currently supported on platforms without __int128"); +#endif }; template ::__use_schrage> + __lce_alg_type _Mode = __lce_alg_picker<__a, __c, __m, _Mp>::__mode> struct __lce_ta; // 64 +#ifndef _LIBCPP_HAS_NO_INT128 +template +struct __lce_ta<_Ap, _Cp, _Mp, (unsigned long long)(-1), _LCE_Promote> { + typedef unsigned long long result_type; + _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __xp) { + __extension__ using __calc_type = unsigned __int128; + const __calc_type __a = static_cast<__calc_type>(_Ap); + const __calc_type __c = static_cast<__calc_type>(_Cp); + const __calc_type __m = static_cast<__calc_type>(_Mp); + const __calc_type __x = static_cast<__calc_type>(__xp); + return static_cast((__a * __x + __c) % __m); + } +}; +#endif + template -struct __lce_ta<__a, __c, __m, (unsigned long long)(~0), true> { +struct __lce_ta<__a, __c, __m, (unsigned long long)(-1), _LCE_Schrage> { typedef unsigned long long result_type; _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { // Schrage's algorithm @@ -66,7 +94,7 @@ struct __lce_ta<__a, __c, __m, (unsigned long long)(~0), true> { }; template -struct __lce_ta<__a, 0, __m, (unsigned long long)(~0), true> { +struct __lce_ta<__a, 0ull, __m, (unsigned long long)(-1), _LCE_Schrage> { typedef unsigned long long result_type; _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { // Schrage's algorithm @@ -80,21 +108,40 @@ struct __lce_ta<__a, 0, __m, (unsigned long long)(~0), true> { }; template -struct __lce_ta<__a, __c, __m, (unsigned long long)(~0), false> { +struct __lce_ta<__a, __c, __m, (unsigned long long)(-1), _LCE_Part> { + typedef unsigned long long result_type; + _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { + // Use (((a*x) % m) + c) % m + __x = (__a * __x) % __m; + __x += __c - (__x >= __m - __c) * __m; + return __x; + } +}; + +template +struct __lce_ta<__a, __c, __m, (unsigned long long)(-1), _LCE_Full> { typedef unsigned long long result_type; _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { return (__a * __x + __c) % __m; } }; template -struct __lce_ta<__a, __c, 0, (unsigned long long)(~0), false> { +struct __lce_ta<__a, __c, 0ull, (unsigned long long)(-1), _LCE_Full> { typedef unsigned long long result_type; _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { return __a * __x + __c; } }; // 32 +template +struct __lce_ta<__a, __c, __m, unsigned(-1), _LCE_Promote> { + typedef unsigned result_type; + _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { + return static_cast(__lce_ta<__a, __c, __m, (unsigned long long)(-1)>::next(__x)); + } +}; + template -struct __lce_ta<_Ap, _Cp, _Mp, unsigned(~0), true> { +struct __lce_ta<_Ap, _Cp, _Mp, unsigned(-1), _LCE_Schrage> { typedef unsigned result_type; _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { const result_type __a = static_cast(_Ap); @@ -112,7 +159,7 @@ struct __lce_ta<_Ap, _Cp, _Mp, unsigned(~0), true> { }; template -struct __lce_ta<_Ap, 0, _Mp, unsigned(~0), true> { +struct __lce_ta<_Ap, 0ull, _Mp, unsigned(-1), _LCE_Schrage> { typedef unsigned result_type; _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { const result_type __a = static_cast(_Ap); @@ -128,7 +175,21 @@ struct __lce_ta<_Ap, 0, _Mp, unsigned(~0), true> { }; template -struct __lce_ta<_Ap, _Cp, _Mp, unsigned(~0), false> { +struct __lce_ta<_Ap, _Cp, _Mp, unsigned(-1), _LCE_Part> { + typedef unsigned result_type; + _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { + const result_type __a = static_cast(_Ap); + const result_type __c = static_cast(_Cp); + const result_type __m = static_cast(_Mp); + // Use (((a*x) % m) + c) % m + __x = (__a * __x) % __m; + __x += __c - (__x >= __m - __c) * __m; + return __x; + } +}; + +template +struct __lce_ta<_Ap, _Cp, _Mp, unsigned(-1), _LCE_Full> { typedef unsigned result_type; _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { const result_type __a = static_cast(_Ap); @@ -139,7 +200,7 @@ struct __lce_ta<_Ap, _Cp, _Mp, unsigned(~0), false> { }; template -struct __lce_ta<_Ap, _Cp, 0, unsigned(~0), false> { +struct __lce_ta<_Ap, _Cp, 0ull, unsigned(-1), _LCE_Full> { typedef unsigned result_type; _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { const result_type __a = static_cast(_Ap); @@ -150,11 +211,11 @@ struct __lce_ta<_Ap, _Cp, 0, unsigned(~0), false> { // 16 -template -struct __lce_ta<__a, __c, __m, (unsigned short)(~0), __b> { +template +struct __lce_ta<__a, __c, __m, (unsigned short)(-1), __mode> { typedef unsigned short result_type; _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { - return static_cast(__lce_ta<__a, __c, __m, unsigned(~0)>::next(__x)); + return static_cast(__lce_ta<__a, __c, __m, unsigned(-1)>::next(__x)); } }; @@ -178,7 +239,7 @@ public: private: result_type __x_; - static _LIBCPP_CONSTEXPR const result_type _Mp = result_type(~0); + static _LIBCPP_CONSTEXPR const result_type _Mp = result_type(-1); static_assert(__m == 0 || __a < __m, "linear_congruential_engine invalid parameters"); static_assert(__m == 0 || __c < __m, "linear_congruential_engine invalid parameters"); diff --git a/libcxx/include/__ranges/as_rvalue_view.h b/libcxx/include/__ranges/as_rvalue_view.h index 2fc272e798d6e0a9be5f05c7885315fe2efaebf6..5849a6c3683960ef804bf79b9d496e76daae8737 100644 --- a/libcxx/include/__ranges/as_rvalue_view.h +++ b/libcxx/include/__ranges/as_rvalue_view.h @@ -111,7 +111,7 @@ namespace views { namespace __as_rvalue { struct __fn : __range_adaptor_closure<__fn> { template - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr auto + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Range&& __range) noexcept(noexcept(as_rvalue_view(std::forward<_Range>(__range)))) -> decltype(/*--------------------------*/ as_rvalue_view(std::forward<_Range>(__range))) { return /*---------------------------------*/ as_rvalue_view(std::forward<_Range>(__range)); @@ -119,7 +119,7 @@ struct __fn : __range_adaptor_closure<__fn> { template requires same_as, range_reference_t<_Range>> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr auto + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Range&& __range) noexcept(noexcept(views::all(std::forward<_Range>(__range)))) -> decltype(/*--------------------------*/ views::all(std::forward<_Range>(__range))) { return /*---------------------------------*/ views::all(std::forward<_Range>(__range)); diff --git a/libcxx/include/__ranges/chunk_by_view.h b/libcxx/include/__ranges/chunk_by_view.h index b04a23de99fb2a756158fb6e83f86f5e4f9bd41a..00014d9f10ae8865a913e8aedf54b066803124eb 100644 --- a/libcxx/include/__ranges/chunk_by_view.h +++ b/libcxx/include/__ranges/chunk_by_view.h @@ -205,7 +205,7 @@ namespace views { namespace __chunk_by { struct __fn { template - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Pred&& __pred) const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Pred&& __pred) const noexcept(noexcept(/**/ chunk_by_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred)))) -> decltype(/*--*/ chunk_by_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred))) { return /*-------------*/ chunk_by_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred)); @@ -213,7 +213,7 @@ struct __fn { template requires constructible_from, _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pred&& __pred) const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pred&& __pred) const noexcept(is_nothrow_constructible_v, _Pred>) { return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Pred>(__pred))); } diff --git a/libcxx/include/__ranges/drop_view.h b/libcxx/include/__ranges/drop_view.h index 83bb598b0a0c916c9420301775d4b4f19471467d..fbfbca4db62186b135bf5ab375a190ffdb658766 100644 --- a/libcxx/include/__ranges/drop_view.h +++ b/libcxx/include/__ranges/drop_view.h @@ -266,7 +266,7 @@ struct __fn { class _RawRange = remove_cvref_t<_Range>, class _Dist = range_difference_t<_Range>> requires (__is_repeat_specialization<_RawRange> && sized_range<_RawRange>) - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const noexcept(noexcept(views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))))) -> decltype( views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n)))) { return views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))); } @@ -277,7 +277,7 @@ struct __fn { class _RawRange = remove_cvref_t<_Range>, class _Dist = range_difference_t<_Range>> requires (__is_repeat_specialization<_RawRange> && !sized_range<_RawRange>) - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&&) const noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range)))) -> decltype( _LIBCPP_AUTO_CAST(std::forward<_Range>(__range))) diff --git a/libcxx/include/__ranges/repeat_view.h b/libcxx/include/__ranges/repeat_view.h index 5caea757a393141263f95ba0ecdf56cbd657ca26..0941770f0eef80f82dcb46bbb1e70b97d3b96825 100644 --- a/libcxx/include/__ranges/repeat_view.h +++ b/libcxx/include/__ranges/repeat_view.h @@ -229,13 +229,13 @@ namespace views { namespace __repeat { struct __fn { template - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Tp&& __value) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Tp&& __value) noexcept(noexcept(ranges::repeat_view(std::forward<_Tp>(__value)))) -> decltype( ranges::repeat_view(std::forward<_Tp>(__value))) { return ranges::repeat_view(std::forward<_Tp>(__value)); } template - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Tp&& __value, _Bound&& __bound_sentinel) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Tp&& __value, _Bound&& __bound_sentinel) noexcept(noexcept(ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel)))) -> decltype( ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel))) { return ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel)); } diff --git a/libcxx/include/__ranges/split_view.h b/libcxx/include/__ranges/split_view.h index 98f17be04f628f5d78bf1b86c3798fdce52eba6d..ce3606aedfefb93cf4606035a5c5368c7173bda5 100644 --- a/libcxx/include/__ranges/split_view.h +++ b/libcxx/include/__ranges/split_view.h @@ -200,7 +200,7 @@ namespace __split_view { struct __fn { // clang-format off template - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Pattern&& __pattern) const noexcept(noexcept(split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern)))) -> decltype( split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern))) @@ -209,7 +209,7 @@ struct __fn { template requires constructible_from, _Pattern> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pattern&& __pattern) const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pattern&& __pattern) const noexcept(is_nothrow_constructible_v, _Pattern>) { return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Pattern>(__pattern))); } diff --git a/libcxx/include/__ranges/take_view.h b/libcxx/include/__ranges/take_view.h index 83ed5ca0ebd390960ff574e715474b4a4ea7525a..27ca8155a69b18831284230f5ede4dd8e3eed722 100644 --- a/libcxx/include/__ranges/take_view.h +++ b/libcxx/include/__ranges/take_view.h @@ -308,7 +308,7 @@ struct __fn { class _RawRange = remove_cvref_t<_Range>, class _Dist = range_difference_t<_Range>> requires(__is_repeat_specialization<_RawRange> && sized_range<_RawRange>) - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const noexcept(noexcept(views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))))) -> decltype( views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n)))) { return views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))); } @@ -319,7 +319,7 @@ struct __fn { class _RawRange = remove_cvref_t<_Range>, class _Dist = range_difference_t<_Range>> requires(__is_repeat_specialization<_RawRange> && !sized_range<_RawRange>) - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const noexcept(noexcept(views::repeat(*__range.__value_, static_cast<_Dist>(__n)))) -> decltype( views::repeat(*__range.__value_, static_cast<_Dist>(__n))) { return views::repeat(*__range.__value_, static_cast<_Dist>(__n)); } diff --git a/libcxx/include/__ranges/to.h b/libcxx/include/__ranges/to.h index 67818c521b150006f48b8223c9507da6f3106156..8a815bce58111e80a67a410b9a32c0e0c19e2485 100644 --- a/libcxx/include/__ranges/to.h +++ b/libcxx/include/__ranges/to.h @@ -85,7 +85,7 @@ concept __always_false = false; // `ranges::to` base template -- the `_Container` type is a simple type template parameter. template requires(!view<_Container>) -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Container to(_Range&& __range, _Args&&... __args) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Container to(_Range&& __range, _Args&&... __args) { // Mandates: C is a cv-unqualified class type. static_assert(!is_const_v<_Container>, "The target container cannot be const-qualified, please remove the const"); static_assert( @@ -192,7 +192,7 @@ struct _Deducer { // `ranges::to` specialization -- `_Container` is a template template parameter requiring deduction to figure out the // container element type. template