diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 33ac65e715ce81..b27616f3dcc658 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -9,7 +9,6 @@ #include "../ClangTidy.h" #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" -#include "../cppcoreguidelines/NarrowingConversionsCheck.h" #include "ArgumentCommentCheck.h" #include "AssertSideEffectCheck.h" #include "AssignmentInIfConditionCheck.h" @@ -47,6 +46,7 @@ #include "MultiLevelImplicitPointerConversionCheck.h" #include "MultipleNewInOneExpressionCheck.h" #include "MultipleStatementMacroCheck.h" +#include "NarrowingConversionsCheck.h" #include "NoEscapeCheck.h" #include "NonZeroEnumToBoolConversionCheck.h" #include "NondeterministicPointerIterationOrderCheck.h" @@ -183,7 +183,7 @@ class BugproneModule : public ClangTidyModule { "bugprone-pointer-arithmetic-on-polymorphic-object"); CheckFactories.registerCheck( "bugprone-redundant-branch-condition"); - CheckFactories.registerCheck( + CheckFactories.registerCheck( "bugprone-narrowing-conversions"); CheckFactories.registerCheck("bugprone-no-escape"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 13adad7c3dadbd..73ab22381631c8 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -42,6 +42,7 @@ add_clang_library(clangTidyBugproneModule STATIC MultiLevelImplicitPointerConversionCheck.cpp MultipleNewInOneExpressionCheck.cpp MultipleStatementMacroCheck.cpp + NarrowingConversionsCheck.cpp NoEscapeCheck.cpp NonZeroEnumToBoolConversionCheck.cpp NondeterministicPointerIterationOrderCheck.cpp diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp similarity index 99% rename from clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp rename to clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp index 45fef9471d5211..a950704208c73b 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp @@ -22,7 +22,7 @@ using namespace clang::ast_matchers; -namespace clang::tidy::cppcoreguidelines { +namespace clang::tidy::bugprone { namespace { @@ -614,4 +614,4 @@ void NarrowingConversionsCheck::check(const MatchFinder::MatchResult &Result) { return handleImplicitCast(*Result.Context, *Cast); llvm_unreachable("must be binary operator or cast expression"); } -} // namespace clang::tidy::cppcoreguidelines +} // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h b/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.h similarity index 90% rename from clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h rename to clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.h index 1add40b91778a3..20403f920b9257 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.h @@ -6,19 +6,19 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_NARROWING_CONVERSIONS_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_NARROWING_CONVERSIONS_H +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_NARROWING_CONVERSIONS_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_NARROWING_CONVERSIONS_H #include "../ClangTidyCheck.h" -namespace clang::tidy::cppcoreguidelines { +namespace clang::tidy::bugprone { /// Checks for narrowing conversions, e.g: /// int i = 0; /// i += 0.1; /// /// For the user-facing documentation see: -/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines/narrowing-conversions.html +/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/narrowing-conversions.html class NarrowingConversionsCheck : public ClangTidyCheck { public: NarrowingConversionsCheck(StringRef Name, ClangTidyContext *Context); @@ -104,6 +104,6 @@ class NarrowingConversionsCheck : public ClangTidyCheck { const bool PedanticMode; }; -} // namespace clang::tidy::cppcoreguidelines +} // namespace clang::tidy::bugprone -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_NARROWING_CONVERSIONS_H +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_NARROWING_CONVERSIONS_H diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt index 07bb89ec7937a0..1f4107c0b35e70 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt @@ -16,7 +16,6 @@ add_clang_library(clangTidyCppCoreGuidelinesModule STATIC MacroUsageCheck.cpp MisleadingCaptureDefaultByValueCheck.cpp MissingStdForwardCheck.cpp - NarrowingConversionsCheck.cpp NoMallocCheck.cpp NoSuspendWithLockCheck.cpp OwningMemoryCheck.cpp diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp index e9f0201615616f..6adef04264347b 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp @@ -9,6 +9,7 @@ #include "../ClangTidy.h" #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" +#include "../bugprone/NarrowingConversionsCheck.h" #include "../misc/NonPrivateMemberVariablesInClassesCheck.h" #include "../misc/UnconventionalAssignOperatorCheck.h" #include "../modernize/AvoidCArraysCheck.h" @@ -30,7 +31,6 @@ #include "MacroUsageCheck.h" #include "MisleadingCaptureDefaultByValueCheck.h" #include "MissingStdForwardCheck.h" -#include "NarrowingConversionsCheck.h" #include "NoMallocCheck.h" #include "NoSuspendWithLockCheck.h" #include "OwningMemoryCheck.h" @@ -87,7 +87,7 @@ class CppCoreGuidelinesModule : public ClangTidyModule { "cppcoreguidelines-misleading-capture-default-by-value"); CheckFactories.registerCheck( "cppcoreguidelines-missing-std-forward"); - CheckFactories.registerCheck( + CheckFactories.registerCheck( "cppcoreguidelines-narrowing-conversions"); CheckFactories.registerCheck("cppcoreguidelines-no-malloc"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index fabd0cc78ac645..3cab440155250b 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -361,6 +361,13 @@ Removed checks Miscellaneous ^^^^^^^^^^^^^ +- The :doc:`bugprone-narrowing-conversions ` + check is no longer an alias of :doc:`cppcoreguidelines-narrowing-conversions + `. Instead, + :doc:`cppcoreguidelines-narrowing-conversions + ` is now an alias + of :doc:`bugprone-narrowing-conversions `. + Improvements to include-fixer ----------------------------- diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/narrowing-conversions.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/narrowing-conversions.rst index f4bb40b341bcdd..1a1217ed5a21c2 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/narrowing-conversions.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/narrowing-conversions.rst @@ -1,10 +1,126 @@ .. title:: clang-tidy - bugprone-narrowing-conversions -.. meta:: - :http-equiv=refresh: 5;URL=../cppcoreguidelines/narrowing-conversions.html bugprone-narrowing-conversions ============================== -The bugprone-narrowing-conversions check is an alias, please see -:doc:`cppcoreguidelines-narrowing-conversions <../cppcoreguidelines/narrowing-conversions>` -for more information. +`cppcoreguidelines-narrowing-conversions` redirects here as an alias for this check. + +Checks for silent narrowing conversions, e.g: ``int i = 0; i += 0.1;``. While +the issue is obvious in this former example, it might not be so in the +following: ``void MyClass::f(double d) { int_member_ += d; }``. + +We flag narrowing conversions from: + - an integer to a narrower integer (e.g. ``char`` to ``unsigned char``) + if WarnOnIntegerNarrowingConversion Option is set, + - an integer to a narrower floating-point (e.g. ``uint64_t`` to ``float``) + if WarnOnIntegerToFloatingPointNarrowingConversion Option is set, + - a floating-point to an integer (e.g. ``double`` to ``int``), + - a floating-point to a narrower floating-point (e.g. ``double`` to ``float``) + if WarnOnFloatingPointNarrowingConversion Option is set. + +This check will flag: + - All narrowing conversions that are not marked by an explicit cast (c-style or + ``static_cast``). For example: ``int i = 0; i += 0.1;``, + ``void f(int); f(0.1);``, + - All applications of binary operators with a narrowing conversions. + For example: ``int i; i+= 0.1;``. + +Arithmetic with smaller integer types than ``int`` trigger implicit conversions, +as explained under `"Integral Promotion" on cppreference.com +`_. +This check diagnoses more instances of narrowing than the compiler warning +`-Wconversion` does. The example below demonstrates this behavior. + +.. code-block:: c++ + + // The following function definition demonstrates usage of arithmetic with + // integer types smaller than `int` and how the narrowing conversion happens + // implicitly. + void computation(short argument1, short argument2) { + // Arithmetic written by humans: + short result = argument1 + argument2; + // Arithmetic actually performed by C++: + short result = static_cast(static_cast(argument1) + static_cast(argument2)); + } + + void recommended_resolution(short argument1, short argument2) { + short result = argument1 + argument2; + // ^ warning: narrowing conversion from 'int' to signed type 'short' is implementation-defined + + // The cppcoreguidelines recommend to resolve this issue by using the GSL + // in one of two ways. Either by a cast that throws if a loss of precision + // would occur. + short result = gsl::narrow(argument1 + argument2); + // Or it can be resolved without checking the result risking invalid results. + short result = gsl::narrow_cast(argument1 + argument2); + + // A classical `static_cast` will silence the warning as well if the GSL + // is not available. + short result = static_cast(argument1 + argument2); + } + +Options +------- + +.. option:: WarnOnIntegerNarrowingConversion + + When `true`, the check will warn on narrowing integer conversion + (e.g. ``int`` to ``size_t``). `true` by default. + +.. option:: WarnOnIntegerToFloatingPointNarrowingConversion + + When `true`, the check will warn on narrowing integer to floating-point + conversion (e.g. ``size_t`` to ``double``). `true` by default. + +.. option:: WarnOnFloatingPointNarrowingConversion + + When `true`, the check will warn on narrowing floating point conversion + (e.g. ``double`` to ``float``). `true` by default. + +.. option:: WarnWithinTemplateInstantiation + + When `true`, the check will warn on narrowing conversions within template + instantiations. `false` by default. + +.. option:: WarnOnEquivalentBitWidth + + When `true`, the check will warn on narrowing conversions that arise from + casting between types of equivalent bit width. (e.g. + `int n = uint(0);` or `long long n = double(0);`) `true` by default. + +.. option:: IgnoreConversionFromTypes + + Narrowing conversions from any type in this semicolon-separated list will be + ignored. This may be useful to weed out commonly occurring, but less commonly + problematic assignments such as `int n = std::vector().size();` or + `int n = std::difference(it1, it2);`. The default list is empty, but one + suggested list for a legacy codebase would be + `size_t;ptrdiff_t;size_type;difference_type`. + +.. option:: PedanticMode + + When `true`, the check will warn on assigning a floating point constant + to an integer value even if the floating point value is exactly + representable in the destination type (e.g. ``int i = 1.0;``). + `false` by default. + +FAQ +--- + + - What does "narrowing conversion from 'int' to 'float'" mean? + +An IEEE754 Floating Point number can represent all integer values in the range +[-2^PrecisionBits, 2^PrecisionBits] where PrecisionBits is the number of bits in +the mantissa. + +For ``float`` this would be [-2^23, 2^23], where ``int`` can represent values in +the range [-2^31, 2^31-1]. + + - What does "implementation-defined" mean? + +You may have encountered messages like "narrowing conversion from 'unsigned int' +to signed type 'int' is implementation-defined". +The C/C++ standard does not mandate two's complement for signed integers, and so +the compiler is free to define what the semantics are for converting an unsigned +integer to signed integer. Clang's implementation uses the two's complement +format. diff --git a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/narrowing-conversions.rst b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/narrowing-conversions.rst index 7cc0b2809b4589..ea24e870d32d47 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/narrowing-conversions.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/narrowing-conversions.rst @@ -1,129 +1,14 @@ .. title:: clang-tidy - cppcoreguidelines-narrowing-conversions +.. meta:: + :http-equiv=refresh: 5;URL=../bugprone/narrowing-conversions.html cppcoreguidelines-narrowing-conversions ======================================= -Checks for silent narrowing conversions, e.g: ``int i = 0; i += 0.1;``. While -the issue is obvious in this former example, it might not be so in the -following: ``void MyClass::f(double d) { int_member_ += d; }``. - -This check implements `ES.46 +This check implements part of `ES.46 `_ from the C++ Core Guidelines. -We enforce only part of the guideline, more specifically, we flag narrowing conversions from: - - an integer to a narrower integer (e.g. ``char`` to ``unsigned char``) - if WarnOnIntegerNarrowingConversion Option is set, - - an integer to a narrower floating-point (e.g. ``uint64_t`` to ``float``) - if WarnOnIntegerToFloatingPointNarrowingConversion Option is set, - - a floating-point to an integer (e.g. ``double`` to ``int``), - - a floating-point to a narrower floating-point (e.g. ``double`` to ``float``) - if WarnOnFloatingPointNarrowingConversion Option is set. - -This check will flag: - - All narrowing conversions that are not marked by an explicit cast (c-style or - ``static_cast``). For example: ``int i = 0; i += 0.1;``, - ``void f(int); f(0.1);``, - - All applications of binary operators with a narrowing conversions. - For example: ``int i; i+= 0.1;``. - -Arithmetic with smaller integer types than ``int`` trigger implicit conversions, -as explained under `"Integral Promotion" on cppreference.com -`_. -This check diagnoses more instances of narrowing than the compiler warning -`-Wconversion` does. The example below demonstrates this behavior. - -.. code-block:: c++ - - // The following function definition demonstrates usage of arithmetic with - // integer types smaller than `int` and how the narrowing conversion happens - // implicitly. - void computation(short argument1, short argument2) { - // Arithmetic written by humans: - short result = argument1 + argument2; - // Arithmetic actually performed by C++: - short result = static_cast(static_cast(argument1) + static_cast(argument2)); - } - - void recommended_resolution(short argument1, short argument2) { - short result = argument1 + argument2; - // ^ warning: narrowing conversion from 'int' to signed type 'short' is implementation-defined - - // The cppcoreguidelines recommend to resolve this issue by using the GSL - // in one of two ways. Either by a cast that throws if a loss of precision - // would occur. - short result = gsl::narrow(argument1 + argument2); - // Or it can be resolved without checking the result risking invalid results. - short result = gsl::narrow_cast(argument1 + argument2); - - // A classical `static_cast` will silence the warning as well if the GSL - // is not available. - short result = static_cast(argument1 + argument2); - } - - -Options -------- - -.. option:: WarnOnIntegerNarrowingConversion - - When `true`, the check will warn on narrowing integer conversion - (e.g. ``int`` to ``size_t``). `true` by default. - -.. option:: WarnOnIntegerToFloatingPointNarrowingConversion - - When `true`, the check will warn on narrowing integer to floating-point - conversion (e.g. ``size_t`` to ``double``). `true` by default. - -.. option:: WarnOnFloatingPointNarrowingConversion - - When `true`, the check will warn on narrowing floating point conversion - (e.g. ``double`` to ``float``). `true` by default. - -.. option:: WarnWithinTemplateInstantiation - - When `true`, the check will warn on narrowing conversions within template - instantiations. `false` by default. - -.. option:: WarnOnEquivalentBitWidth - - When `true`, the check will warn on narrowing conversions that arise from - casting between types of equivalent bit width. (e.g. - `int n = uint(0);` or `long long n = double(0);`) `true` by default. - -.. option:: IgnoreConversionFromTypes - - Narrowing conversions from any type in this semicolon-separated list will be - ignored. This may be useful to weed out commonly occurring, but less commonly - problematic assignments such as `int n = std::vector().size();` or - `int n = std::difference(it1, it2);`. The default list is empty, but one - suggested list for a legacy codebase would be - `size_t;ptrdiff_t;size_type;difference_type`. - -.. option:: PedanticMode - - When `true`, the check will warn on assigning a floating point constant - to an integer value even if the floating point value is exactly - representable in the destination type (e.g. ``int i = 1.0;``). - `false` by default. - -FAQ ---- - - - What does "narrowing conversion from 'int' to 'float'" mean? - -An IEEE754 Floating Point number can represent all integer values in the range -[-2^PrecisionBits, 2^PrecisionBits] where PrecisionBits is the number of bits in -the mantissa. - -For ``float`` this would be [-2^23, 2^23], where ``int`` can represent values in -the range [-2^31, 2^31-1]. - - - What does "implementation-defined" mean? - -You may have encountered messages like "narrowing conversion from 'unsigned int' -to signed type 'int' is implementation-defined". -The C/C++ standard does not mandate two's complement for signed integers, and so -the compiler is free to define what the semantics are for converting an unsigned -integer to signed integer. Clang's implementation uses the two's complement -format. +The cppcoreguidelines-narrowing-conversions check is an alias, please see +:doc:`bugprone-narrowing-conversions <../bugprone/narrowing-conversions>` +for more information. diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 4d8853a0f6d86c..e8f9b4e829634b 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -114,6 +114,7 @@ Clang-Tidy Checks :doc:`bugprone-multi-level-implicit-pointer-conversion `, :doc:`bugprone-multiple-new-in-one-expression `, :doc:`bugprone-multiple-statement-macro `, + :doc:`bugprone-narrowing-conversions `, :doc:`bugprone-no-escape `, :doc:`bugprone-non-zero-enum-to-bool-conversion `, :doc:`bugprone-nondeterministic-pointer-iteration-order `, @@ -190,7 +191,6 @@ Clang-Tidy Checks :doc:`cppcoreguidelines-macro-usage `, :doc:`cppcoreguidelines-misleading-capture-default-by-value `, "Yes" :doc:`cppcoreguidelines-missing-std-forward `, - :doc:`cppcoreguidelines-narrowing-conversions `, :doc:`cppcoreguidelines-no-malloc `, :doc:`cppcoreguidelines-no-suspend-with-lock `, :doc:`cppcoreguidelines-owning-memory `, @@ -411,7 +411,6 @@ Check aliases .. csv-table:: :header: "Name", "Redirect", "Offers fixes" - :doc:`bugprone-narrowing-conversions `, :doc:`cppcoreguidelines-narrowing-conversions `, :doc:`cert-arr39-c `, :doc:`bugprone-sizeof-expression `, :doc:`cert-con36-c `, :doc:`bugprone-spuriously-wake-up-functions `, :doc:`cert-con54-cpp `, :doc:`bugprone-spuriously-wake-up-functions `, @@ -541,6 +540,7 @@ Check aliases :doc:`cppcoreguidelines-c-copy-assignment-signature `, :doc:`misc-unconventional-assign-operator `, :doc:`cppcoreguidelines-explicit-virtual-functions `, :doc:`modernize-use-override `, "Yes" :doc:`cppcoreguidelines-macro-to-enum `, :doc:`modernize-macro-to-enum `, "Yes" + :doc:`cppcoreguidelines-narrowing-conversions `, :doc:`bugprone-narrowing-conversions `, :doc:`cppcoreguidelines-noexcept-destructor `, :doc:`performance-noexcept-destructor `, "Yes" :doc:`cppcoreguidelines-noexcept-move-operations `, :doc:`performance-noexcept-move-constructor `, "Yes" :doc:`cppcoreguidelines-noexcept-swap `, :doc:`performance-noexcept-swap `, "Yes" diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-bitfields.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-bitfields.cpp similarity index 97% rename from clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-bitfields.cpp rename to clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-bitfields.cpp index 36fde38202efcd..a7bb3c8d0c0c7e 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-bitfields.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-bitfields.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \ +// RUN: %check_clang_tidy %s bugprone-narrowing-conversions %t \ // RUN: -std=c++17 -- -target x86_64-unknown-linux #define CHAR_BITS 8 @@ -31,7 +31,7 @@ struct CompleteBitfield { }; int example_warning(unsigned x) { - // CHECK-MESSAGES: :[[@LINE+1]]:10: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE+1]]:10: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] return x; } diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-equivalentbitwidth-option.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-equivalentbitwidth-option.cpp similarity index 66% rename from clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-equivalentbitwidth-option.cpp rename to clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-equivalentbitwidth-option.cpp index fb5c7e36eeb0df..0deb0067113673 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-equivalentbitwidth-option.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-equivalentbitwidth-option.cpp @@ -1,35 +1,35 @@ // RUN: %check_clang_tidy -check-suffix=DEFAULT %s \ -// RUN: cppcoreguidelines-narrowing-conversions %t -- +// RUN: bugprone-narrowing-conversions %t -- // RUN: %check_clang_tidy -check-suffix=DISABLED %s \ -// RUN: cppcoreguidelines-narrowing-conversions %t -- \ +// RUN: bugprone-narrowing-conversions %t -- \ // RUN: -config='{CheckOptions: { \ -// RUN: cppcoreguidelines-narrowing-conversions.WarnOnEquivalentBitWidth: 0}}' +// RUN: bugprone-narrowing-conversions.WarnOnEquivalentBitWidth: 0}}' void narrowing_equivalent_bitwidth() { int i; unsigned int ui; i = ui; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] // DISABLED: Warning disabled with WarnOnEquivalentBitWidth=0. float f; i = f; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [bugprone-narrowing-conversions] // DISABLED: Warning disabled with WarnOnEquivalentBitWidth=0. f = i; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'int' to 'float' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'int' to 'float' [bugprone-narrowing-conversions] // DISABLED: Warning disabled with WarnOnEquivalentBitWidth=0. long long ll; double d; ll = d; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'long long' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'long long' [bugprone-narrowing-conversions] // DISABLED: Warning disabled with WarnOnEquivalentBitWidth=0. d = ll; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to 'double' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to 'double' [bugprone-narrowing-conversions] // DISABLED: Warning disabled with WarnOnEquivalentBitWidth=0. } @@ -37,6 +37,6 @@ void most_narrowing_is_not_ok() { int i; long long ui; i = ui; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] - // CHECK-MESSAGES-DISABLED: :[[@LINE-2]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] + // CHECK-MESSAGES-DISABLED: :[[@LINE-2]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] } diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-ignoreconversionfromtypes-option.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-ignoreconversionfromtypes-option.cpp similarity index 75% rename from clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-ignoreconversionfromtypes-option.cpp rename to clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-ignoreconversionfromtypes-option.cpp index 91e908f535a0d4..6d93f5d642b5e4 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-ignoreconversionfromtypes-option.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-ignoreconversionfromtypes-option.cpp @@ -1,10 +1,10 @@ // RUN: %check_clang_tidy -check-suffix=DEFAULT %s \ -// RUN: cppcoreguidelines-narrowing-conversions %t -- +// RUN: bugprone-narrowing-conversions %t -- // RUN: %check_clang_tidy -check-suffix=IGNORED %s \ -// RUN: cppcoreguidelines-narrowing-conversions %t -- \ +// RUN: bugprone-narrowing-conversions %t -- \ // RUN: -config='{CheckOptions: { \ -// RUN: cppcoreguidelines-narrowing-conversions.IgnoreConversionFromTypes: "global_size_t;nested_size_type;long" \ +// RUN: bugprone-narrowing-conversions.IgnoreConversionFromTypes: "global_size_t;nested_size_type;long" \ // RUN: }}' // We use global_size_t instead of 'size_t' because windows predefines size_t. @@ -20,7 +20,7 @@ void narrowing_global_size_t() { int i; global_size_t j; i = j; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'global_size_t' (aka 'long long') to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'global_size_t' (aka 'long long') to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] // IGNORED: Warning is disabled with IgnoreConversionFromTypes=global_size_t. } @@ -28,7 +28,7 @@ void narrowing_size_type() { int i; vector::nested_size_type j; i = j; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'vector::nested_size_type' (aka 'long long') to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'vector::nested_size_type' (aka 'long long') to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] // IGNORED: Warning is disabled with IgnoreConversionFromTypes=nested_size_type. } @@ -36,11 +36,11 @@ void narrowing_size_method() { vector v; int i, j; i = v.size(); - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'global_size_t' (aka 'long long') to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'global_size_t' (aka 'long long') to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] // IGNORED: Warning is disabled with IgnoreConversionFromTypes=global_size_t. i = j + v.size(); - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'global_size_t' (aka 'long long') to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'global_size_t' (aka 'long long') to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] // IGNORED: Warning is disabled with IgnoreConversionFromTypes=global_size_t. } @@ -49,7 +49,7 @@ void narrowing_size_method_binary_expr() { int j; vector v; i = j + v.size(); - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'global_size_t' (aka 'long long') to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'global_size_t' (aka 'long long') to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] // IGNORED: Warning is disabled with IgnoreConversionFromTypes=global_size_t. } @@ -57,11 +57,11 @@ void narrowing_size_method_binary_op() { int i, j; vector v; i += v.size(); - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:8: warning: narrowing conversion from 'global_size_t' (aka 'long long') to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:8: warning: narrowing conversion from 'global_size_t' (aka 'long long') to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] // IGNORED: Warning is disabled with IgnoreConversionFromTypes=global_size_t. i += j + v.size(); - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:8: warning: narrowing conversion from 'global_size_t' (aka 'long long') to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:8: warning: narrowing conversion from 'global_size_t' (aka 'long long') to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] // IGNORED: Warning is disabled with IgnoreConversionFromTypes=global_size_t. } @@ -69,13 +69,13 @@ void most_narrowing_is_not_ok() { int i; long long j; i = j; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] - // CHECK-MESSAGES-IGNORED: :[[@LINE-2]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] + // CHECK-MESSAGES-IGNORED: :[[@LINE-2]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] } void test_ignore_builtin_type_pr58809() { long x = 123; short y = x; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:13: warning: narrowing conversion from 'long' to signed type 'short' is implementation-defined [cppcoreguidelines-narrowing-conversions] - // CHECK-MESSAGES-NOT-IGNORED: :[[@LINE-2]]:13: warning: narrowing conversion from 'long' to signed type 'short' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:13: warning: narrowing conversion from 'long' to signed type 'short' is implementation-defined [bugprone-narrowing-conversions] + // CHECK-MESSAGES-NOT-IGNORED: :[[@LINE-2]]:13: warning: narrowing conversion from 'long' to signed type 'short' is implementation-defined [bugprone-narrowing-conversions] } diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-intemplates-option.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-intemplates-option.cpp similarity index 73% rename from clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-intemplates-option.cpp rename to clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-intemplates-option.cpp index cb19ed78cce8a7..625dc45abcbecd 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-intemplates-option.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-intemplates-option.cpp @@ -1,10 +1,10 @@ // RUN: %check_clang_tidy -check-suffix=DEFAULT %s \ -// RUN: cppcoreguidelines-narrowing-conversions %t -- +// RUN: bugprone-narrowing-conversions %t -- // RUN: %check_clang_tidy -check-suffix=WARN %s \ -// RUN: cppcoreguidelines-narrowing-conversions %t -- \ +// RUN: bugprone-narrowing-conversions %t -- \ // RUN: -config='{CheckOptions: { \ -// RUN: cppcoreguidelines-narrowing-conversions.WarnWithinTemplateInstantiation: 1 \ +// RUN: bugprone-narrowing-conversions.WarnWithinTemplateInstantiation: 1 \ // RUN: }}' template @@ -12,7 +12,7 @@ void assign_in_template(OrigType jj) { int ii; ii = jj; // DEFAULT: Warning disabled because WarnWithinTemplateInstantiation=0. - // CHECK-MESSAGES-WARN: :[[@LINE-2]]:8: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES-WARN: :[[@LINE-2]]:8: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] } void narrow_inside_template_not_ok() { @@ -23,8 +23,8 @@ void narrow_inside_template_not_ok() { void assign_outside_template(long long jj) { int ii; ii = jj; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:8: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] - // CHECK-MESSAGES-WARN: :[[@LINE-2]]:8: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:8: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] + // CHECK-MESSAGES-WARN: :[[@LINE-2]]:8: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] } void narrow_outside_template_not_ok() { diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-long-is-32bits.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-long-is-32bits.cpp similarity index 84% rename from clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-long-is-32bits.cpp rename to clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-long-is-32bits.cpp index dcf1848a30f664..8e801a0eeea37a 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-long-is-32bits.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-long-is-32bits.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \ +// RUN: %check_clang_tidy %s bugprone-narrowing-conversions %t \ // RUN: -- -- -target x86_64-unknown-linux -m32 static_assert(sizeof(int) * 8 == 32, "int is 32-bits"); @@ -16,8 +16,8 @@ void narrow_integer_to_signed_integer_is_not_ok() { i = l; // int and long are the same type. i = ll; // int64_t does not fit in an int32_t - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] ll = ul; // uint32_t fits into int64_t ll = ull; // uint64_t does not fit in an int64_t - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [bugprone-narrowing-conversions] } diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-narrowingfloatingpoint-option.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-narrowingfloatingpoint-option.cpp similarity index 70% rename from clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-narrowingfloatingpoint-option.cpp rename to clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-narrowingfloatingpoint-option.cpp index 6cad3204c18e41..9ded2f0923f4e6 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-narrowingfloatingpoint-option.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-narrowingfloatingpoint-option.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \ +// RUN: %check_clang_tidy %s bugprone-narrowing-conversions %t \ // RUN: -- -- -target x86_64-unknown-linux -fsigned-char namespace floats { @@ -6,15 +6,15 @@ namespace floats { void narrow_constant_floating_point_to_int_not_ok(double d) { int i = 0; i += 0.5; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [bugprone-narrowing-conversions] i += 0.5f; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [bugprone-narrowing-conversions] i *= 0.5f; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [bugprone-narrowing-conversions] i /= 0.5f; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [bugprone-narrowing-conversions] i += (double)0.5f; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [bugprone-narrowing-conversions] i += 2.0; i += 2.0f; } @@ -28,11 +28,11 @@ float narrow_double_to_float_return() { void narrow_double_to_float_not_ok(double d) { float f; f = d; - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [bugprone-narrowing-conversions] f = 15_double; - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [bugprone-narrowing-conversions] f += d; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'float' [bugprone-narrowing-conversions] f = narrow_double_to_float_return(); } @@ -46,11 +46,11 @@ void narrow_fp_constants() { f = __builtin_nanf("0"); // float NaN is not narrowing. f = __builtin_huge_val(); // max double is not within-range of float. - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'double' to 'float' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'double' to 'float' [bugprone-narrowing-conversions] f = -__builtin_huge_val(); // -max double is not within-range of float. - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'double' to 'float' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'double' to 'float' [bugprone-narrowing-conversions] f = __builtin_inf(); // double infinity is not within-range of float. - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'double' to 'float' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'double' to 'float' [bugprone-narrowing-conversions] f = __builtin_nan("0"); // double NaN is not narrowing. } diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-narrowinginteger-option.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-narrowinginteger-option.cpp similarity index 59% rename from clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-narrowinginteger-option.cpp rename to clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-narrowinginteger-option.cpp index f58de65f042328..fce90ecf0881dc 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-narrowinginteger-option.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-narrowinginteger-option.cpp @@ -1,23 +1,23 @@ // RUN: %check_clang_tidy -check-suffix=DEFAULT %s \ -// RUN: cppcoreguidelines-narrowing-conversions %t -- \ -// RUN: -config='{CheckOptions: {cppcoreguidelines-narrowing-conversions.WarnOnIntegerNarrowingConversion: true}}' +// RUN: bugprone-narrowing-conversions %t -- \ +// RUN: -config='{CheckOptions: {bugprone-narrowing-conversions.WarnOnIntegerNarrowingConversion: true}}' // RUN: %check_clang_tidy -check-suffix=DISABLED %s \ -// RUN: cppcoreguidelines-narrowing-conversions %t -- \ -// RUN: -config='{CheckOptions: {cppcoreguidelines-narrowing-conversions.WarnOnIntegerNarrowingConversion: false}}' +// RUN: bugprone-narrowing-conversions %t -- \ +// RUN: -config='{CheckOptions: {bugprone-narrowing-conversions.WarnOnIntegerNarrowingConversion: false}}' void foo(unsigned long long value) { int a = value; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:11: warning: narrowing conversion from 'unsigned long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:11: warning: narrowing conversion from 'unsigned long long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] // DISABLED: No warning for integer narrowing conversions when WarnOnIntegerNarrowingConversion = false. long long b = value; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:17: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:17: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [bugprone-narrowing-conversions] // DISABLED: No warning for integer narrowing conversions when WarnOnIntegerNarrowingConversion = false. } void casting_float_to_bool_is_still_operational_when_integer_narrowing_is_disabled(float f) { if (f) { - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'bool' [cppcoreguidelines-narrowing-conversions] - // CHECK-MESSAGES-DISABLED: :[[@LINE-2]]:7: warning: narrowing conversion from 'float' to 'bool' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'bool' [bugprone-narrowing-conversions] + // CHECK-MESSAGES-DISABLED: :[[@LINE-2]]:7: warning: narrowing conversion from 'float' to 'bool' [bugprone-narrowing-conversions] } } diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-narrowingintegertofloatingpoint-option.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-narrowingintegertofloatingpoint-option.cpp new file mode 100644 index 00000000000000..704d24dbb973df --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-narrowingintegertofloatingpoint-option.cpp @@ -0,0 +1,19 @@ +// RUN: %check_clang_tidy -check-suffix=DEFAULT %s \ +// RUN: bugprone-narrowing-conversions %t -- \ +// RUN: -config='{CheckOptions: {bugprone-narrowing-conversions.WarnOnIntegerToFloatingPointNarrowingConversion: true}}' + +// RUN: %check_clang_tidy -check-suffix=DISABLED %s \ +// RUN: bugprone-narrowing-conversions %t -- \ +// RUN: -config='{CheckOptions: {bugprone-narrowing-conversions.WarnOnIntegerToFloatingPointNarrowingConversion: false}}' + +void foo(unsigned long long value) { + double a = value; + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:14: warning: narrowing conversion from 'unsigned long long' to 'double' [bugprone-narrowing-conversions] + // DISABLED: No warning for integer to floating-point narrowing conversions when WarnOnIntegerToFloatingPointNarrowingConversion = false. +} + +void floating_point_to_integer_is_still_not_ok(double f) { + int a = f; + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:11: warning: narrowing conversion from 'double' to 'int' [bugprone-narrowing-conversions] + // CHECK-MESSAGES-DISABLED: :[[@LINE-2]]:11: warning: narrowing conversion from 'double' to 'int' [bugprone-narrowing-conversions] +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-pedanticmode-option.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-pedanticmode-option.cpp similarity index 52% rename from clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-pedanticmode-option.cpp rename to clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-pedanticmode-option.cpp index eb1a5a67ee1183..d2e2eada96c4b9 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-pedanticmode-option.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-pedanticmode-option.cpp @@ -1,22 +1,22 @@ -// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \ +// RUN: %check_clang_tidy %s bugprone-narrowing-conversions %t \ // RUN: -config="{CheckOptions: { \ -// RUN: cppcoreguidelines-narrowing-conversions.PedanticMode: true}}" \ +// RUN: bugprone-narrowing-conversions.PedanticMode: true}}" \ // RUN: -- -target x86_64-unknown-linux -fsigned-char namespace floats { void triggers_wrong_constant_type_warning(double d) { int i = 0.0; - // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: constant value should be of type of type 'int' instead of 'double' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: constant value should be of type of type 'int' instead of 'double' [bugprone-narrowing-conversions] i += 2.0; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: constant value should be of type of type 'int' instead of 'double' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: constant value should be of type of type 'int' instead of 'double' [bugprone-narrowing-conversions] i += 2.0f; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: constant value should be of type of type 'int' instead of 'float' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: constant value should be of type of type 'int' instead of 'float' [bugprone-narrowing-conversions] } void triggers_narrowing_warning_when_overflowing() { unsigned short us = 65537.0; - // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: narrowing conversion from constant 'double' to 'unsigned short' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: narrowing conversion from constant 'double' to 'unsigned short' [bugprone-narrowing-conversions] } } // namespace floats diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-unsigned-char.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-unsigned-char.cpp similarity index 80% rename from clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-unsigned-char.cpp rename to clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-unsigned-char.cpp index 6bd437f98d44c5..6a544b46b65d08 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-unsigned-char.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-unsigned-char.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \ +// RUN: %check_clang_tidy %s bugprone-narrowing-conversions %t \ // RUN: -- -- -target x86_64-unknown-linux -funsigned-char void narrow_integer_to_unsigned_integer_is_ok() { @@ -42,24 +42,24 @@ void narrow_integer_to_signed_integer_is_not_ok() { sc = sc; sc = s; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'short' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'short' to signed type 'signed char' is implementation-defined [bugprone-narrowing-conversions] sc = i; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'int' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'int' to signed type 'signed char' is implementation-defined [bugprone-narrowing-conversions] sc = l; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'long' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'long' to signed type 'signed char' is implementation-defined [bugprone-narrowing-conversions] sc = ll; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'long long' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'long long' to signed type 'signed char' is implementation-defined [bugprone-narrowing-conversions] sc = c; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'char' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'char' to signed type 'signed char' is implementation-defined [bugprone-narrowing-conversions] sc = us; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned short' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned short' to signed type 'signed char' is implementation-defined [bugprone-narrowing-conversions] sc = ui; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned int' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned int' to signed type 'signed char' is implementation-defined [bugprone-narrowing-conversions] sc = ul; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long' to signed type 'signed char' is implementation-defined [bugprone-narrowing-conversions] sc = ull; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long long' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long long' to signed type 'signed char' is implementation-defined [bugprone-narrowing-conversions] } void narrow_constant_to_unsigned_integer_is_ok() { @@ -72,7 +72,7 @@ void narrow_constant_to_unsigned_integer_is_ok() { unsigned char uc3 = -1; // unsigned dst type is well defined. unsigned char uc4 = 256; // unsigned dst type is well defined. signed char sc = 128; - // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: narrowing conversion from constant value 128 (0x00000080) of type 'int' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: narrowing conversion from constant value 128 (0x00000080) of type 'int' to signed type 'signed char' is implementation-defined [bugprone-narrowing-conversions] } void narrow_conditional_operator_contant_to_unsigned_is_ok(bool b) { diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions.cpp similarity index 77% rename from clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions.cpp rename to clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions.cpp index 29b38e74e1a22d..39875264bd1e64 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions.cpp @@ -1,6 +1,6 @@ -// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \ +// RUN: %check_clang_tidy %s bugprone-narrowing-conversions %t \ // RUN: -config="{CheckOptions: { \ -// RUN: cppcoreguidelines-narrowing-conversions.WarnOnFloatingPointNarrowingConversion: false}}" \ +// RUN: bugprone-narrowing-conversions.WarnOnFloatingPointNarrowingConversion: false}}" \ // RUN: -- -target x86_64-unknown-linux -fsigned-char float ceil(float); @@ -20,27 +20,27 @@ float operator"" _float(unsigned long long); void narrow_fp_to_int_not_ok(double d) { int i = 0; i = d; - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [bugprone-narrowing-conversions] i = 0.5f; - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'float' to 'int' [bugprone-narrowing-conversions] i = static_cast(d); - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [bugprone-narrowing-conversions] i = ConvertsToFloat(); - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [bugprone-narrowing-conversions] i = 15_float; - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [bugprone-narrowing-conversions] i += d; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'int' [bugprone-narrowing-conversions] i += 0.5; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [bugprone-narrowing-conversions] i += 0.5f; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [bugprone-narrowing-conversions] i *= 0.5f; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [bugprone-narrowing-conversions] i /= 0.5f; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [bugprone-narrowing-conversions] i += (double)0.5f; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [bugprone-narrowing-conversions] i += 2.0; i += 2.0f; } @@ -84,29 +84,29 @@ void narrow_double_to_float_not_ok_binary_ops(double d) { void narrow_fp_constant_to_bool_not_ok() { bool b1 = 1.0; - // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant 'double' to 'bool' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant 'double' to 'bool' [bugprone-narrowing-conversions] bool b2 = 1.0f; - // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant 'float' to 'bool' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant 'float' to 'bool' [bugprone-narrowing-conversions] } void narrow_integer_to_floating() { { long long ll; // 64 bits float f = ll; // doesn't fit in 24 bits - // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'long long' to 'float' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'long long' to 'float' [bugprone-narrowing-conversions] double d = ll; // doesn't fit in 53 bits. - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: narrowing conversion from 'long long' to 'double' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: narrowing conversion from 'long long' to 'double' [bugprone-narrowing-conversions] } { int i; // 32 bits float f = i; // doesn't fit in 24 bits - // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'int' to 'float' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'int' to 'float' [bugprone-narrowing-conversions] double d = i; // fits in 53 bits. } { short n1, n2; float f = n1 + n2; // 'n1 + n2' is of type 'int' because of integer rules - // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'int' to 'float' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'int' to 'float' [bugprone-narrowing-conversions] } { short s; // 16 bits @@ -156,41 +156,41 @@ void narrow_integer_to_signed_integer_is_not_ok() { c = c; c = s; - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'short' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'short' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions] c = i; - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'int' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions] c = l; - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions] c = ll; - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions] c = uc; - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned char' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned char' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions] c = us; - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned short' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned short' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions] c = ui; - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned int' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions] c = ul; - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions] c = ull; - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long long' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long long' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions] i = c; i = s; i = i; i = l; - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] i = ll; - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] i = uc; i = us; i = ui; - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] i = ul; - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] i = ull; - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] ll = c; ll = s; @@ -202,9 +202,9 @@ void narrow_integer_to_signed_integer_is_not_ok() { ll = us; ll = ui; ll = ul; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long' to signed type 'long long' is implementation-defined [bugprone-narrowing-conversions] ll = ull; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [bugprone-narrowing-conversions] } void narrow_constant_to_unsigned_integer_is_ok() { @@ -222,16 +222,16 @@ void narrow_constant_to_signed_integer_is_not_ok() { char c1 = -128; char c2 = 127; char c3 = -129; - // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant value -129 (0xFFFFFF7F) of type 'int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant value -129 (0xFFFFFF7F) of type 'int' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions] char c4 = 128; - // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant value 128 (0x00000080) of type 'int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant value 128 (0x00000080) of type 'int' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions] short s1 = -32768; short s2 = 32767; short s3 = -32769; - // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from constant value -32769 (0xFFFF7FFF) of type 'int' to signed type 'short' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from constant value -32769 (0xFFFF7FFF) of type 'int' to signed type 'short' is implementation-defined [bugprone-narrowing-conversions] short s4 = 32768; - // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from constant value 32768 (0x00008000) of type 'int' to signed type 'short' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from constant value 32768 (0x00008000) of type 'int' to signed type 'short' is implementation-defined [bugprone-narrowing-conversions] } void narrow_conditional_operator_contant_to_unsigned_is_ok(bool b) { @@ -244,22 +244,22 @@ void narrow_conditional_operator_contant_to_unsigned_is_ok(bool b) { void narrow_conditional_operator_contant_to_signed_is_not_ok(bool b) { char uc1 = b ? 1 : 0; char uc2 = b ? 1 : 128; - // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: narrowing conversion from constant value 128 (0x00000080) of type 'int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: narrowing conversion from constant value 128 (0x00000080) of type 'int' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions] char uc3 = b ? -129 : 0; - // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: narrowing conversion from constant value -129 (0xFFFFFF7F) of type 'int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: narrowing conversion from constant value -129 (0xFFFFFF7F) of type 'int' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions] unsigned long long ysize; long long mirror = b ? -1 : ysize - 1; - // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: narrowing conversion from constant value 18446744073709551615 (0xFFFFFFFFFFFFFFFF) of type 'unsigned long long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions] - // CHECK-MESSAGES: :[[@LINE-2]]:37: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: narrowing conversion from constant value 18446744073709551615 (0xFFFFFFFFFFFFFFFF) of type 'unsigned long long' to signed type 'long long' is implementation-defined [bugprone-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-2]]:37: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [bugprone-narrowing-conversions] } void narrow_constant_to_floating_point() { float f_ok = 1ULL << 24; // fits in 24 bits mantissa. float f_not_ok = (1ULL << 24) + 1ULL; // doesn't fit in 24 bits mantissa. - // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: narrowing conversion from constant value 16777217 of type 'unsigned long long' to 'float' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: narrowing conversion from constant value 16777217 of type 'unsigned long long' to 'float' [bugprone-narrowing-conversions] double d_ok = 1ULL << 53; // fits in 53 bits mantissa. double d_not_ok = (1ULL << 53) + 1ULL; // doesn't fit in 53 bits mantissa. - // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: narrowing conversion from constant value 9007199254740993 of type 'unsigned long long' to 'double' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: narrowing conversion from constant value 9007199254740993 of type 'unsigned long long' to 'double' [bugprone-narrowing-conversions] } void casting_integer_to_bool_is_ok() { @@ -275,13 +275,13 @@ void casting_integer_to_bool_is_ok() { void casting_float_to_bool_is_not_ok() { float f; while (f) { - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'float' to 'bool' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'float' to 'bool' [bugprone-narrowing-conversions] } for (; f;) { - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'float' to 'bool' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'float' to 'bool' [bugprone-narrowing-conversions] } if (f) { - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'bool' [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'bool' [bugprone-narrowing-conversions] } } @@ -352,7 +352,7 @@ void typedef_context() { i64 = i; // Okay, no narrowing. i = i64; - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'myint64_t' (aka 'long long') to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'myint64_t' (aka 'long long') to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] } } // namespace floats diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-narrowingintegertofloatingpoint-option.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-narrowingintegertofloatingpoint-option.cpp deleted file mode 100644 index 35ca61b6a9a8c5..00000000000000 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-narrowingintegertofloatingpoint-option.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %check_clang_tidy -check-suffix=DEFAULT %s \ -// RUN: cppcoreguidelines-narrowing-conversions %t -- \ -// RUN: -config='{CheckOptions: {cppcoreguidelines-narrowing-conversions.WarnOnIntegerToFloatingPointNarrowingConversion: true}}' - -// RUN: %check_clang_tidy -check-suffix=DISABLED %s \ -// RUN: cppcoreguidelines-narrowing-conversions %t -- \ -// RUN: -config='{CheckOptions: {cppcoreguidelines-narrowing-conversions.WarnOnIntegerToFloatingPointNarrowingConversion: false}}' - -void foo(unsigned long long value) { - double a = value; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:14: warning: narrowing conversion from 'unsigned long long' to 'double' [cppcoreguidelines-narrowing-conversions] - // DISABLED: No warning for integer to floating-point narrowing conversions when WarnOnIntegerToFloatingPointNarrowingConversion = false. -} - -void floating_point_to_integer_is_still_not_ok(double f) { - int a = f; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:11: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions] - // CHECK-MESSAGES-DISABLED: :[[@LINE-2]]:11: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions] -} diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 0e414921324b7f..b4a961de224aa0 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -9,7 +9,11 @@ #ifndef LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H #define LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H +#include "clang/CIR/Dialect/IR/CIRAttrs.h" + #include "mlir/IR/Builders.h" +#include "mlir/IR/BuiltinTypes.h" +#include "mlir/IR/Types.h" namespace cir { @@ -26,6 +30,13 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { cir::PointerType getVoidPtrTy() { return getPointerTo(cir::VoidType::get(getContext())); } + + mlir::TypedAttr getConstPtrAttr(mlir::Type type, int64_t value) { + auto valueAttr = mlir::IntegerAttr::get( + mlir::IntegerType::get(type.getContext(), 64), value); + return cir::ConstPtrAttr::get( + getContext(), mlir::cast(type), valueAttr); + } }; } // namespace cir diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h new file mode 100644 index 00000000000000..438fb7d09608db --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file declares the attributes in the CIR dialect. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_H +#define LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_H + +#include "clang/CIR/Dialect/IR/CIRTypes.h" + +#include "mlir/IR/Attributes.h" +#include "mlir/IR/BuiltinAttributeInterfaces.h" + +#include "llvm/ADT/SmallVector.h" + +//===----------------------------------------------------------------------===// +// CIR Dialect Attrs +//===----------------------------------------------------------------------===// + +namespace clang { +class FunctionDecl; +class VarDecl; +class RecordDecl; +} // namespace clang + +#define GET_ATTRDEF_CLASSES +#include "clang/CIR/Dialect/IR/CIROpsAttributes.h.inc" + +#endif // LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_H diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td new file mode 100644 index 00000000000000..bd1665e1ac1a06 --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -0,0 +1,142 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file declares the CIR dialect attributes. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_TD +#define LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_TD + +include "mlir/IR/BuiltinAttributeInterfaces.td" +include "mlir/IR/EnumAttr.td" + +include "clang/CIR/Dialect/IR/CIRDialect.td" + +//===----------------------------------------------------------------------===// +// CIR Attrs +//===----------------------------------------------------------------------===// + +class CIR_Attr traits = []> + : AttrDef { + let mnemonic = attrMnemonic; +} + +class CIRUnitAttr traits = []> + : CIR_Attr { + let returnType = "bool"; + let defaultValue = "false"; + let valueType = NoneType; + let isOptional = 1; +} + +//===----------------------------------------------------------------------===// +// IntegerAttr +//===----------------------------------------------------------------------===// + +def IntAttr : CIR_Attr<"Int", "int", [TypedAttrInterface]> { + let summary = "An attribute containing an integer value"; + let description = [{ + An integer attribute is a literal attribute that represents an integral + value of the specified integer type. + }]; + let parameters = (ins AttributeSelfTypeParameter<"">:$type, + "llvm::APInt":$value); + let builders = [ + AttrBuilderWithInferredContext<(ins "mlir::Type":$type, + "const llvm::APInt &":$value), [{ + return $_get(type.getContext(), type, value); + }]>, + AttrBuilderWithInferredContext<(ins "mlir::Type":$type, + "int64_t":$value), [{ + IntType intType = mlir::cast(type); + mlir::APInt apValue(intType.getWidth(), value, intType.isSigned()); + return $_get(intType.getContext(), intType, apValue); + }]>, + ]; + let extraClassDeclaration = [{ + int64_t getSInt() const { return getValue().getSExtValue(); } + uint64_t getUInt() const { return getValue().getZExtValue(); } + bool isNullValue() const { return getValue() == 0; } + uint64_t getBitWidth() const { + return mlir::cast(getType()).getWidth(); + } + }]; + let genVerifyDecl = 1; + let hasCustomAssemblyFormat = 1; +} + +//===----------------------------------------------------------------------===// +// FPAttr +//===----------------------------------------------------------------------===// + +def FPAttr : CIR_Attr<"FP", "fp", [TypedAttrInterface]> { + let summary = "An attribute containing a floating-point value"; + let description = [{ + An fp attribute is a literal attribute that represents a floating-point + value of the specified floating-point type. Supporting only CIR FP types. + }]; + let parameters = (ins + AttributeSelfTypeParameter<"", "::cir::CIRFPTypeInterface">:$type, + APFloatParameter<"">:$value + ); + let builders = [ + AttrBuilderWithInferredContext<(ins "mlir::Type":$type, + "const llvm::APFloat &":$value), [{ + return $_get(type.getContext(), mlir::cast(type), + value); + }]>, + AttrBuilder<(ins "mlir::Type":$type, + "const llvm::APFloat &":$value), [{ + return $_get($_ctxt, mlir::cast(type), value); + }]>, + ]; + let extraClassDeclaration = [{ + static FPAttr getZero(mlir::Type type); + }]; + let genVerifyDecl = 1; + + let assemblyFormat = [{ + `<` custom($value, ref($type)) `>` + }]; +} + +//===----------------------------------------------------------------------===// +// ConstPtrAttr +//===----------------------------------------------------------------------===// + +def ConstPtrAttr : CIR_Attr<"ConstPtr", "ptr", [TypedAttrInterface]> { + let summary = "Holds a constant pointer value"; + let parameters = (ins + AttributeSelfTypeParameter<"", "::cir::PointerType">:$type, + "mlir::IntegerAttr":$value); + let description = [{ + A pointer attribute is a literal attribute that represents an integral + value of a pointer type. + }]; + let builders = [ + AttrBuilderWithInferredContext<(ins "mlir::Type":$type, + "mlir::IntegerAttr":$value), [{ + return $_get(type.getContext(), mlir::cast(type), + value); + }]>, + AttrBuilder<(ins "mlir::Type":$type, + "mlir::IntegerAttr":$value), [{ + return $_get($_ctxt, mlir::cast(type), value); + }]>, + ]; + let extraClassDeclaration = [{ + bool isNullValue() const { return getValue().getInt() == 0; } + }]; + + let assemblyFormat = [{ + `<` custom($value) `>` + }]; +} + +#endif // LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_TD diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.h b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h index 0b71bdad29a3af..683176b139ca49 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRDialect.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h @@ -26,6 +26,7 @@ #include "mlir/Interfaces/MemorySlotInterfaces.h" #include "mlir/Interfaces/SideEffectInterfaces.h" +#include "clang/CIR/Dialect/IR/CIRAttrs.h" #include "clang/CIR/Dialect/IR/CIROpsDialect.h.inc" // TableGen'erated files for MLIR dialects require that a macro be defined when diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 0d6c65ecf41029..b15e0415360ead 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -16,6 +16,7 @@ include "clang/CIR/Dialect/IR/CIRDialect.td" include "clang/CIR/Dialect/IR/CIRTypes.td" +include "clang/CIR/Dialect/IR/CIRAttrs.td" include "mlir/IR/BuiltinAttributeInterfaces.td" include "mlir/IR/EnumAttr.td" @@ -75,6 +76,45 @@ class LLVMLoweringInfo { class CIR_Op traits = []> : Op, LLVMLoweringInfo; +//===----------------------------------------------------------------------===// +// ConstantOp +//===----------------------------------------------------------------------===// + +def ConstantOp : CIR_Op<"const", + [ConstantLike, Pure, AllTypesMatch<["value", "res"]>]> { + let summary = "Defines a CIR constant"; + let description = [{ + The `cir.const` operation turns a literal into an SSA value. The data is + attached to the operation as an attribute. + + ```mlir + %0 = cir.const 42 : i32 + %1 = cir.const 4.2 : f32 + %2 = cir.const nullptr : !cir.ptr + ``` + }]; + + // The constant operation takes an attribute as the only input. + let arguments = (ins TypedAttrInterface:$value); + + // The constant operation returns a single value of CIR_AnyType. + let results = (outs CIR_AnyType:$res); + + let assemblyFormat = "attr-dict $value"; + + let hasVerifier = 1; + + let extraClassDeclaration = [{ + bool isNullPtr() { + if (const auto ptrAttr = mlir::dyn_cast(getValue())) + return ptrAttr.isNullValue(); + return false; + } + }]; + + let hasFolder = 1; +} + //===----------------------------------------------------------------------===// // GlobalOp //===----------------------------------------------------------------------===// @@ -92,9 +132,19 @@ def GlobalOp : CIR_Op<"global"> { described by the type of the variable. }]; - let arguments = (ins SymbolNameAttr:$sym_name, TypeAttr:$sym_type); + let arguments = (ins SymbolNameAttr:$sym_name, TypeAttr:$sym_type, + OptionalAttr:$initial_value); + + let assemblyFormat = [{ + $sym_name + custom($sym_type, $initial_value) + attr-dict + }]; - let assemblyFormat = [{ $sym_name `:` $sym_type attr-dict }]; + let extraClassDeclaration = [{ + bool isDeclaration() { return !getInitialValue(); } + bool hasInitializer() { return !isDeclaration(); } + }]; let skipDefaultBuilders = 1; diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index ef00b26c1fd98c..a32fb3c801114a 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -220,8 +220,8 @@ def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> { // Constraints -def CIR_AnyFloat: AnyTypeOf<[CIR_Single, CIR_Double, CIR_FP80, CIR_FP128, CIR_LongDouble, - CIR_FP16, CIR_BFloat16]>; +def CIR_AnyFloat: AnyTypeOf<[CIR_Single, CIR_Double, CIR_FP80, CIR_FP128, + CIR_LongDouble, CIR_FP16, CIR_BFloat16]>; def CIR_AnyIntOrFloat: AnyTypeOf<[CIR_AnyFloat, CIR_IntType]>; //===----------------------------------------------------------------------===// @@ -350,4 +350,12 @@ def VoidPtr : Type< "cir::VoidType::get($_builder.getContext()))"> { } +//===----------------------------------------------------------------------===// +// Global type constraints +//===----------------------------------------------------------------------===// + +def CIR_AnyType : AnyTypeOf<[ + CIR_VoidType, CIR_IntType, CIR_AnyFloat, CIR_PointerType, CIR_FuncType +]>; + #endif // MLIR_CIR_DIALECT_CIR_TYPES diff --git a/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt b/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt index 28ae30dab8dfb2..1fdbc24ba6b4a3 100644 --- a/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt +++ b/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt @@ -14,3 +14,6 @@ mlir_tablegen(CIROpsDialect.cpp.inc -gen-dialect-defs) add_public_tablegen_target(MLIRCIROpsIncGen) add_dependencies(mlir-headers MLIRCIROpsIncGen) +mlir_tablegen(CIROpsAttributes.h.inc -gen-attrdef-decls) +mlir_tablegen(CIROpsAttributes.cpp.inc -gen-attrdef-defs) +add_public_tablegen_target(MLIRCIRAttrsEnumsGen) diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 416d532028d090..2615ae382cb8b5 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -115,6 +115,48 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd, if (clang::IdentifierInfo *identifier = vd->getIdentifier()) { auto varOp = builder.create(getLoc(vd->getSourceRange()), identifier->getName(), type); + // TODO(CIR): This code for processing initial values is a placeholder + // until class ConstantEmitter is upstreamed and the code for processing + // constant expressions is filled out. Only the most basic handling of + // certain constant expressions is implemented for now. + const VarDecl *initDecl; + const Expr *initExpr = vd->getAnyInitializer(initDecl); + if (initExpr) { + mlir::Attribute initializer; + if (APValue *value = initDecl->evaluateValue()) { + switch (value->getKind()) { + case APValue::Int: { + initializer = builder.getAttr(type, value->getInt()); + break; + } + case APValue::Float: { + initializer = builder.getAttr(type, value->getFloat()); + break; + } + case APValue::LValue: { + if (value->getLValueBase()) { + errorNYI(initExpr->getSourceRange(), + "non-null pointer initialization"); + } else { + if (auto ptrType = mlir::dyn_cast(type)) { + initializer = builder.getConstPtrAttr( + ptrType, value->getLValueOffset().getQuantity()); + } else { + llvm_unreachable( + "non-pointer variable initialized with a pointer"); + } + } + break; + } + default: + errorNYI(initExpr->getSourceRange(), "unsupported initializer kind"); + break; + } + } else { + errorNYI(initExpr->getSourceRange(), "non-constant initializer"); + } + varOp.setInitialValueAttr(initializer); + } theModule.push_back(varOp); } else { errorNYI(vd->getSourceRange().getBegin(), diff --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp index 7d42da1ab20d76..8e8f7d5b7d7cb4 100644 --- a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp @@ -12,6 +12,24 @@ #include "clang/CIR/Dialect/IR/CIRDialect.h" +#include "mlir/IR/DialectImplementation.h" +#include "llvm/ADT/TypeSwitch.h" + +static void printFloatLiteral(mlir::AsmPrinter &p, llvm::APFloat value, + mlir::Type ty); +static mlir::ParseResult +parseFloatLiteral(mlir::AsmParser &parser, + mlir::FailureOr &value, + cir::CIRFPTypeInterface fpType); + +static mlir::ParseResult parseConstPtr(mlir::AsmParser &parser, + mlir::IntegerAttr &value); + +static void printConstPtr(mlir::AsmPrinter &p, mlir::IntegerAttr value); + +#define GET_ATTRDEF_CLASSES +#include "clang/CIR/Dialect/IR/CIROpsAttributes.cpp.inc" + using namespace mlir; using namespace cir; @@ -21,12 +39,155 @@ using namespace cir; Attribute CIRDialect::parseAttribute(DialectAsmParser &parser, Type type) const { - // No attributes yet to parse - return Attribute{}; + llvm::SMLoc typeLoc = parser.getCurrentLocation(); + llvm::StringRef mnemonic; + Attribute genAttr; + OptionalParseResult parseResult = + generatedAttributeParser(parser, &mnemonic, type, genAttr); + if (parseResult.has_value()) + return genAttr; + parser.emitError(typeLoc, "unknown attribute in CIR dialect"); + return Attribute(); } void CIRDialect::printAttribute(Attribute attr, DialectAsmPrinter &os) const { - // No attributes yet to print + if (failed(generatedAttributePrinter(attr, os))) + llvm_unreachable("unexpected CIR type kind"); +} + +//===----------------------------------------------------------------------===// +// ConstPtrAttr definitions +//===----------------------------------------------------------------------===// + +// TODO(CIR): Consider encoding the null value differently and use conditional +// assembly format instead of custom parsing/printing. +static ParseResult parseConstPtr(AsmParser &parser, mlir::IntegerAttr &value) { + + if (parser.parseOptionalKeyword("null").succeeded()) { + value = mlir::IntegerAttr::get( + mlir::IntegerType::get(parser.getContext(), 64), 0); + return success(); + } + + return parser.parseAttribute(value); +} + +static void printConstPtr(AsmPrinter &p, mlir::IntegerAttr value) { + if (!value.getInt()) + p << "null"; + else + p << value; +} + +//===----------------------------------------------------------------------===// +// IntAttr definitions +//===----------------------------------------------------------------------===// + +Attribute IntAttr::parse(AsmParser &parser, Type odsType) { + mlir::APInt apValue; + + if (!mlir::isa(odsType)) + return {}; + auto type = mlir::cast(odsType); + + // Consume the '<' symbol. + if (parser.parseLess()) + return {}; + + // Fetch arbitrary precision integer value. + if (type.isSigned()) { + int64_t value = 0; + if (parser.parseInteger(value)) { + parser.emitError(parser.getCurrentLocation(), "expected integer value"); + } else { + apValue = mlir::APInt(type.getWidth(), value, type.isSigned(), + /*implicitTrunc=*/true); + if (apValue.getSExtValue() != value) + parser.emitError(parser.getCurrentLocation(), + "integer value too large for the given type"); + } + } else { + uint64_t value = 0; + if (parser.parseInteger(value)) { + parser.emitError(parser.getCurrentLocation(), "expected integer value"); + } else { + apValue = mlir::APInt(type.getWidth(), value, type.isSigned(), + /*implicitTrunc=*/true); + if (apValue.getZExtValue() != value) + parser.emitError(parser.getCurrentLocation(), + "integer value too large for the given type"); + } + } + + // Consume the '>' symbol. + if (parser.parseGreater()) + return {}; + + return IntAttr::get(type, apValue); +} + +void IntAttr::print(AsmPrinter &printer) const { + auto type = mlir::cast(getType()); + printer << '<'; + if (type.isSigned()) + printer << getSInt(); + else + printer << getUInt(); + printer << '>'; +} + +LogicalResult IntAttr::verify(function_ref emitError, + Type type, APInt value) { + if (!mlir::isa(type)) { + emitError() << "expected 'simple.int' type"; + return failure(); + } + + auto intType = mlir::cast(type); + if (value.getBitWidth() != intType.getWidth()) { + emitError() << "type and value bitwidth mismatch: " << intType.getWidth() + << " != " << value.getBitWidth(); + return failure(); + } + + return success(); +} + +//===----------------------------------------------------------------------===// +// FPAttr definitions +//===----------------------------------------------------------------------===// + +static void printFloatLiteral(AsmPrinter &p, APFloat value, Type ty) { + p << value; +} + +static ParseResult parseFloatLiteral(AsmParser &parser, + FailureOr &value, + CIRFPTypeInterface fpType) { + + APFloat parsedValue(0.0); + if (parser.parseFloat(fpType.getFloatSemantics(), parsedValue)) + return failure(); + + value.emplace(parsedValue); + return success(); +} + +FPAttr FPAttr::getZero(Type type) { + return get(type, + APFloat::getZero( + mlir::cast(type).getFloatSemantics())); +} + +LogicalResult FPAttr::verify(function_ref emitError, + CIRFPTypeInterface fpType, APFloat value) { + if (APFloat::SemanticsToEnum(fpType.getFloatSemantics()) != + APFloat::SemanticsToEnum(value.getSemantics())) { + emitError() << "floating-point semantics mismatch"; + return failure(); + } + + return success(); } //===----------------------------------------------------------------------===// @@ -34,5 +195,8 @@ void CIRDialect::printAttribute(Attribute attr, DialectAsmPrinter &os) const { //===----------------------------------------------------------------------===// void CIRDialect::registerAttributes() { - // No attributes yet to register + addAttributes< +#define GET_ATTRDEF_LIST +#include "clang/CIR/Dialect/IR/CIROpsAttributes.cpp.inc" + >(); } diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index dbdca1f8401663..f98d8b60f6ff87 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -12,6 +12,8 @@ #include "clang/CIR/Dialect/IR/CIRDialect.h" +#include "clang/CIR/Dialect/IR/CIRTypes.h" + #include "mlir/Support/LogicalResult.h" #include "clang/CIR/Dialect/IR/CIROpsDialect.cpp.inc" @@ -32,13 +34,73 @@ void cir::CIRDialect::initialize() { >(); } +//===----------------------------------------------------------------------===// +// ConstantOp +//===----------------------------------------------------------------------===// + +static LogicalResult checkConstantTypes(mlir::Operation *op, mlir::Type opType, + mlir::Attribute attrType) { + if (isa(attrType)) { + if (!mlir::isa(opType)) + return op->emitOpError( + "pointer constant initializing a non-pointer type"); + return success(); + } + + if (mlir::isa(attrType)) { + auto at = cast(attrType); + if (at.getType() != opType) { + return op->emitOpError("result type (") + << opType << ") does not match value type (" << at.getType() + << ")"; + } + return success(); + } + + assert(isa(attrType) && "What else could we be looking at here?"); + return op->emitOpError("global with type ") + << cast(attrType).getType() << " not yet supported"; +} + +LogicalResult cir::ConstantOp::verify() { + // ODS already generates checks to make sure the result type is valid. We just + // need to additionally check that the value's attribute type is consistent + // with the result type. + return checkConstantTypes(getOperation(), getType(), getValue()); +} + +OpFoldResult cir::ConstantOp::fold(FoldAdaptor /*adaptor*/) { + return getValue(); +} + //===----------------------------------------------------------------------===// // GlobalOp //===----------------------------------------------------------------------===// -// TODO(CIR): The properties of global variables that require verification -// haven't been implemented yet. -mlir::LogicalResult cir::GlobalOp::verify() { return success(); } +static ParseResult parseConstantValue(OpAsmParser &parser, + mlir::Attribute &valueAttr) { + NamedAttrList attr; + return parser.parseAttribute(valueAttr, "value", attr); +} + +static void printConstant(OpAsmPrinter &p, Attribute value) { + p.printAttribute(value); +} + +mlir::LogicalResult cir::GlobalOp::verify() { + // Verify that the initial value, if present, is either a unit attribute or + // an attribute CIR supports. + if (getInitialValue().has_value()) { + if (checkConstantTypes(getOperation(), getSymType(), *getInitialValue()) + .failed()) + return failure(); + } + + // TODO(CIR): Many other checks for properties that haven't been upstreamed + // yet. + + return success(); +} void cir::GlobalOp::build(OpBuilder &odsBuilder, OperationState &odsState, llvm::StringRef sym_name, mlir::Type sym_type) { @@ -48,6 +110,45 @@ void cir::GlobalOp::build(OpBuilder &odsBuilder, OperationState &odsState, mlir::TypeAttr::get(sym_type)); } +static void printGlobalOpTypeAndInitialValue(OpAsmPrinter &p, cir::GlobalOp op, + TypeAttr type, + Attribute initAttr) { + if (!op.isDeclaration()) { + p << "= "; + // This also prints the type... + if (initAttr) + printConstant(p, initAttr); + } else { + p << ": " << type; + } +} + +static ParseResult +parseGlobalOpTypeAndInitialValue(OpAsmParser &parser, TypeAttr &typeAttr, + Attribute &initialValueAttr) { + mlir::Type opTy; + if (parser.parseOptionalEqual().failed()) { + // Absence of equal means a declaration, so we need to parse the type. + // cir.global @a : !cir.int + if (parser.parseColonType(opTy)) + return failure(); + } else { + // Parse constant with initializer, examples: + // cir.global @y = #cir.fp<1.250000e+00> : !cir.double + // cir.global @rgb = #cir.const_array<[...] : !cir.array> + if (parseConstantValue(parser, initialValueAttr).failed()) + return failure(); + + assert(mlir::isa(initialValueAttr) && + "Non-typed attrs shouldn't appear here."); + auto typedAttr = mlir::cast(initialValueAttr); + opTy = typedAttr.getType(); + } + + typeAttr = TypeAttr::get(opTy); + return success(); +} + //===----------------------------------------------------------------------===// // FuncOp //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Dialect/IR/CMakeLists.txt b/clang/lib/CIR/Dialect/IR/CMakeLists.txt index df60f69df6fc0e..baf8bff1852212 100644 --- a/clang/lib/CIR/Dialect/IR/CMakeLists.txt +++ b/clang/lib/CIR/Dialect/IR/CMakeLists.txt @@ -5,6 +5,7 @@ add_clang_library(MLIRCIR DEPENDS MLIRCIROpsIncGen + MLIRCIRAttrsEnumsGen LINK_LIBS PUBLIC MLIRIR diff --git a/clang/lib/CIR/Interfaces/CMakeLists.txt b/clang/lib/CIR/Interfaces/CMakeLists.txt index fcd8b6963d06c2..b826bf612cc356 100644 --- a/clang/lib/CIR/Interfaces/CMakeLists.txt +++ b/clang/lib/CIR/Interfaces/CMakeLists.txt @@ -5,6 +5,7 @@ add_clang_library(MLIRCIRInterfaces ${MLIR_MAIN_INCLUDE_DIR}/mlir/Interfaces DEPENDS + MLIRCIRAttrsEnumsGen MLIRCIRFPTypeInterfaceIncGen LINK_LIBS diff --git a/clang/test/CIR/global-var-simple.cpp b/clang/test/CIR/global-var-simple.cpp index bbd452655a01bf..ffcc3ef71a6c74 100644 --- a/clang/test/CIR/global-var-simple.cpp +++ b/clang/test/CIR/global-var-simple.cpp @@ -13,11 +13,11 @@ unsigned char uc; short ss; // CHECK: cir.global @ss : !cir.int -unsigned short us; -// CHECK: cir.global @us : !cir.int +unsigned short us = 100; +// CHECK: cir.global @us = #cir.int<100> : !cir.int -int si; -// CHECK: cir.global @si : !cir.int +int si = 42; +// CHECK: cir.global @si = #cir.int<42> : !cir.int unsigned ui; // CHECK: cir.global @ui : !cir.int @@ -31,8 +31,8 @@ unsigned long ul; long long sll; // CHECK: cir.global @sll : !cir.int -unsigned long long ull; -// CHECK: cir.global @ull : !cir.int +unsigned long long ull = 123456; +// CHECK: cir.global @ull = #cir.int<123456> : !cir.int __int128 s128; // CHECK: cir.global @s128 : !cir.int @@ -67,8 +67,8 @@ __bf16 bf16; float f; // CHECK: cir.global @f : !cir.float -double d; -// CHECK: cir.global @d : !cir.double +double d = 1.25; +// CHECK: cir.global @d = #cir.fp<1.250000e+00> : !cir.double long double ld; // CHECK: cir.global @ld : !cir.long_double @@ -79,8 +79,8 @@ __float128 f128; void *vp; // CHECK: cir.global @vp : !cir.ptr -int *ip; -// CHECK: cir.global @ip : !cir.ptr> +int *ip = 0; +// CHECK: cir.global @ip = #cir.ptr : !cir.ptr> double *dp; // CHECK: cir.global @dp : !cir.ptr @@ -91,8 +91,8 @@ char **cpp; void (*fp)(); // CHECK: cir.global @fp : !cir.ptr> -int (*fpii)(int); -// CHECK: cir.global @fpii : !cir.ptr (!cir.int)>> +int (*fpii)(int) = 0; +// CHECK: cir.global @fpii = #cir.ptr : !cir.ptr (!cir.int)>> void (*fpvar)(int, ...); // CHECK: cir.global @fpvar : !cir.ptr, ...)>> diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c index 8344c1aa399737..8e46690cce5a63 100644 --- a/clang/test/Driver/print-supported-extensions-riscv.c +++ b/clang/test/Driver/print-supported-extensions-riscv.c @@ -189,6 +189,7 @@ // CHECK-NEXT: ssctr 1.0 'Ssctr' (Control Transfer Records Supervisor Level) // CHECK-NEXT: svukte 0.3 'Svukte' (Address-Independent Latency of User-Mode Faults to Supervisor Addresses) // CHECK-NEXT: xqcia 0.2 'Xqcia' (Qualcomm uC Arithmetic Extension) +// CHECK-NEXT: xqciac 0.2 'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension) // CHECK-NEXT: xqcics 0.2 'Xqcics' (Qualcomm uC Conditional Select Extension) // CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension) // CHECK-NEXT: xqcilsm 0.2 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension) diff --git a/clang/test/Driver/sanitizer-ld.c b/clang/test/Driver/sanitizer-ld.c index c5a6ebbd9b72b1..4653d842d4a5d1 100644 --- a/clang/test/Driver/sanitizer-ld.c +++ b/clang/test/Driver/sanitizer-ld.c @@ -15,7 +15,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-ASAN-LINUX // -// CHECK-ASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-ASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-ASAN-LINUX-NOT: "-lc" // CHECK-ASAN-LINUX: "--whole-archive" "{{.*}}libclang_rt.asan_static.a" "--no-whole-archive" // CHECK-ASAN-LINUX: "--whole-archive" "{{.*}}libclang_rt.asan.a" "--no-whole-archive" @@ -33,7 +33,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-ASAN-NO-LINK-RUNTIME-LINUX // -// CHECK-ASAN-NO-LINK-RUNTIME-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-ASAN-NO-LINK-RUNTIME-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // RUN: %clang -fsanitize=address -fno-sanitize-link-runtime -### %s 2>&1 \ // RUN: --target=arm64e-apple-macosx -fuse-ld=ld \ @@ -41,7 +41,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-ASAN-NO-LINK-RUNTIME-DARWIN // -// CHECK-ASAN-NO-LINK-RUNTIME-DARWIN: "{{.*}}ld" +// CHECK-ASAN-NO-LINK-RUNTIME-DARWIN: "{{.*}}ld{{(.exe)?}}" // RUN: %clang -fsanitize=address -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -fuse-ld=ld \ @@ -80,7 +80,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-SHARED-ASAN-LINUX // -// CHECK-SHARED-ASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-SHARED-ASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-SHARED-ASAN-LINUX-NOT: "-lc" // CHECK-SHARED-ASAN-LINUX: libclang_rt.asan.so" // CHECK-SHARED-ASAN-LINUX: "--whole-archive" "{{.*}}libclang_rt.asan-preinit.a" "--no-whole-archive" @@ -98,7 +98,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-DSO-SHARED-ASAN-LINUX // -// CHECK-DSO-SHARED-ASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-DSO-SHARED-ASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-DSO-SHARED-ASAN-LINUX-NOT: "-lc" // CHECK-DSO-SHARED-ASAN-LINUX: libclang_rt.asan.so" // CHECK-DSO-SHARED-ASAN-LINUX: "--whole-archive" "{{.*}}libclang_rt.asan_static.a" "--no-whole-archive" @@ -115,7 +115,7 @@ // RUN: --sysroot=%S/Inputs/basic_freebsd_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-ASAN-FREEBSD // -// CHECK-ASAN-FREEBSD: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-ASAN-FREEBSD: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-ASAN-FREEBSD-NOT: "-lc" // CHECK-ASAN-FREEBSD: freebsd{{/|\\+}}libclang_rt.asan_static.a" // CHECK-ASAN-FREEBSD: freebsd{{/|\\+}}libclang_rt.asan.a" @@ -130,7 +130,7 @@ // RUN: --sysroot=%S/Inputs/basic_freebsd_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-ASAN-FREEBSD-LDL // -// CHECK-ASAN-FREEBSD-LDL: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-ASAN-FREEBSD-LDL: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-ASAN-FREEBSD-LDL-NOT: "-ldl" // CHECK-ASAN-FREEBSD-LDL: "--whole-archive" "{{.*}}libclang_rt.asan_static.a" "--no-whole-archive" // CHECK-ASAN-FREEBSD-LDL: "--whole-archive" "{{.*}}libclang_rt.asan.a" "--no-whole-archive" @@ -148,7 +148,7 @@ // RUN: -fsanitize-link-c++-runtime \ // RUN: | %{filecheck} --check-prefix=CHECK-ASAN-LINUX-CXX -// CHECK-ASAN-LINUX-CXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-ASAN-LINUX-CXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-ASAN-LINUX-CXX-SAME: "--whole-archive" "{{.*}}libclang_rt.asan.a" "--no-whole-archive" // CHECK-ASAN-LINUX-CXX-SAME: "--whole-archive" "{{.*}}libclang_rt.asan_cxx.a" "--no-whole-archive" // CHECK-ASAN-LINUX-CXX-NOT: "--dynamic-list" @@ -167,7 +167,7 @@ // RUN: -fno-sanitize-link-c++-runtime \ // RUN: | %{filecheck} --check-prefix=CHECK-ASAN-LINUX-CNOCXX -// CHECK-ASAN-LINUX-CNOCXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-ASAN-LINUX-CNOCXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-ASAN-LINUX-CNOCXX-SAME: "--whole-archive" "{{.*}}libclang_rt.asan.a" "--no-whole-archive" // CHECK-ASAN-LINUX-CNOCXX-SAME: "--export-dynamic" // CHECK-ASAN-LINUX-CNOCXX-NOT: stdc++ @@ -184,7 +184,7 @@ // RUN: -fno-sanitize-link-c++-runtime \ // RUN: | %{filecheck} --check-prefix=CHECK-ASAN-LINUX-NOCXX -// CHECK-ASAN-LINUX-NOCXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-ASAN-LINUX-NOCXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-ASAN-LINUX-NOCXX-SAME: "--whole-archive" "{{.*}}libclang_rt.asan.a" "--no-whole-archive" // CHECK-ASAN-LINUX-NOCXX-SAME: "--export-dynamic" // CHECK-ASAN-LINUX-NOCXX-SAME: "-lstdc++" @@ -201,7 +201,7 @@ // RUN: -nostdlib++ \ // RUN: | %{filecheck} --check-prefix=CHECK-ASAN-LINUX-NOSTDCXX -// CHECK-ASAN-LINUX-NOSTDCXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-ASAN-LINUX-NOSTDCXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-ASAN-LINUX-NOSTDCXX-SAME: "--whole-archive" "{{.*}}libclang_rt.asan.a" "--no-whole-archive" // CHECK-ASAN-LINUX-NOSTDCXX-SAME: "--whole-archive" "{{.*}}libclang_rt.asan_cxx.a" "--no-whole-archive" // CHECK-ASAN-LINUX-NOSTDCXX-SAME: "--export-dynamic" @@ -217,7 +217,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree -lstdc++ -static 2>&1 \ // RUN: | %{filecheck} --check-prefix=CHECK-ASAN-LINUX-CXX-STATIC // -// CHECK-ASAN-LINUX-CXX-STATIC: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-ASAN-LINUX-CXX-STATIC: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-ASAN-LINUX-CXX-STATIC-NOT: stdc++ // CHECK-ASAN-LINUX-CXX-STATIC: "--whole-archive" "{{.*}}libclang_rt.asan.a" "--no-whole-archive" // CHECK-ASAN-LINUX-CXX-STATIC: "--dynamic-list={{.*}}libclang_rt.asan.a.syms" @@ -228,7 +228,7 @@ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | %{filecheck} --check-prefix=CHECK-ASAN-ARM // -// CHECK-ASAN-ARM: "{{(.*[^.0-9A-Z_a-z])?}}ld" +// CHECK-ASAN-ARM: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-ASAN-ARM-NOT: "-lc" // CHECK-ASAN-ARM: libclang_rt.asan_static.a" // CHECK-ASAN-ARM: libclang_rt.asan.a" @@ -238,7 +238,7 @@ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | %{filecheck} --check-prefix=CHECK-ASAN-ARMv7 // -// CHECK-ASAN-ARMv7: "{{(.*[^.0-9A-Z_a-z])?}}ld" +// CHECK-ASAN-ARMv7: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-ASAN-ARMv7-NOT: "-lc" // CHECK-ASAN-ARMv7: libclang_rt.asan_static.a" // CHECK-ASAN-ARMv7: libclang_rt.asan.a" @@ -357,7 +357,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-TYSAN-LINUX-CXX // -// CHECK-TYSAN-LINUX-CXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-TYSAN-LINUX-CXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-TYSAN-LINUX-CXX-NOT: stdc++ // CHECK-TYSAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.tysan{{[^.]*}}.a" "--no-whole-archive" // CHECK-TYSAN-LINUX-CXX: stdc++ @@ -368,7 +368,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-TYSAN-DARWIN-CXX -// CHECK-TYSAN-DARWIN-CXX: "{{.*}}ld" +// CHECK-TYSAN-DARWIN-CXX: "{{.*}}ld{{(.exe)?}}" // CHECK-TYSAN-DARWIN-CXX: libclang_rt.tysan_osx_dynamic.dylib // CHECK-TYSAN-DARWIN-CXX-NOT: -lc++abi @@ -379,7 +379,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-TSAN-LINUX-CXX // -// CHECK-TSAN-LINUX-CXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-TSAN-LINUX-CXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-TSAN-LINUX-CXX-NOT: stdc++ // CHECK-TSAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.tsan.a" "--no-whole-archive" // CHECK-TSAN-LINUX-CXX: "--dynamic-list={{.*}}libclang_rt.tsan.a.syms" @@ -398,7 +398,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-TSAN-NO-LINK-RUNTIME-LINUX // -// CHECK-TSAN-NO-LINK-RUNTIME-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-TSAN-NO-LINK-RUNTIME-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // RUN: not %clang -fsanitize=thread -fno-sanitize-link-runtime -### %s 2>&1 \ // RUN: --target=arm64e-apple-ios -fuse-ld=ld \ @@ -406,7 +406,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-TSAN-NO-LINK-RUNTIME-DARWIN // -// CHECK-TSAN-NO-LINK-RUNTIME-DARWIN: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-TSAN-NO-LINK-RUNTIME-DARWIN: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // RUN: %clangxx -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -fuse-ld=ld -stdlib=platform -lstdc++ \ @@ -415,7 +415,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-MSAN-LINUX-CXX // -// CHECK-MSAN-LINUX-CXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-MSAN-LINUX-CXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-MSAN-LINUX-CXX-NOT: stdc++ // CHECK-MSAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.msan.a" "--no-whole-archive" // CHECK-MSAN-LINUX-CXX: "--dynamic-list={{.*}}libclang_rt.msan.a.syms" @@ -434,7 +434,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-MSAN-NO-LINK-RUNTIME-LINUX // -// CHECK-MSAN-NO-LINK-RUNTIME-LINUX: "{{.*}}ld" +// CHECK-MSAN-NO-LINK-RUNTIME-LINUX: "{{.*}}ld{{(.exe)?}}" // RUN: %clang -fsanitize=undefined -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux-gnux32 -fuse-ld=ld \ @@ -455,7 +455,7 @@ // RUN: -static-libsan \ // RUN: | %{filecheck} --check-prefix=CHECK-UBSAN-LINUX -// CHECK-UBSAN-LINUX: "{{.*}}ld" +// CHECK-UBSAN-LINUX: "{{.*}}ld{{(.exe)?}}" // CHECK-UBSAN-LINUX: "--whole-archive" "{{.*}}libclang_rt.ubsan_standalone.a" "--no-whole-archive" // CHECK-UBSAN-LINUX-NOT: "-lstdc++" // CHECK-UBSAN-LINUX: "-lpthread" @@ -467,7 +467,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-UBSAN-NO-LINK-RUNTIME-LINUX // -// CHECK-UBSAN-NO-LINK-RUNTIME-LINUX: "{{.*}}ld" +// CHECK-UBSAN-NO-LINK-RUNTIME-LINUX: "{{.*}}ld{{(.exe)?}}" // RUN: %clang -fsanitize=undefined -fno-sanitize-link-runtime -### %s 2>&1 \ // RUN: --target=x86_64-apple-darwin -fuse-ld=ld \ @@ -475,7 +475,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-UBSAN-NO-LINK-RUNTIME-DARWIN // -// CHECK-UBSAN-NO-LINK-RUNTIME-DARWIN: "{{.*}}ld" +// CHECK-UBSAN-NO-LINK-RUNTIME-DARWIN: "{{.*}}ld{{(.exe)?}}" // RUN: %clang -fsanitize=fuzzer -fno-sanitize-link-runtime -### %s 2>&1 \ // RUN: --target=arm64e-apple-watchos -fuse-ld=ld \ @@ -483,7 +483,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-FUZZER-NO-LINK-RUNTIME-DARWIN // -// CHECK-FUZZER-NO-LINK-RUNTIME-DARWIN: "{{.*}}ld" +// CHECK-FUZZER-NO-LINK-RUNTIME-DARWIN: "{{.*}}ld{{(.exe)?}}" // RUN: %clang -fsanitize=undefined -### %s 2>&1 \ // RUN: --target=i386-unknown-linux -fuse-ld=ld \ @@ -506,7 +506,7 @@ // RUN: -shared -shared-libsan \ // RUN: | %{filecheck} --check-prefix=CHECK-UBSAN-LINUX-SHAREDLIBASAN -// CHECK-UBSAN-LINUX-SHAREDLIBASAN: "{{.*}}ld" +// CHECK-UBSAN-LINUX-SHAREDLIBASAN: "{{.*}}ld{{(.exe)?}}" // CHECK-UBSAN-LINUX-SHAREDLIBASAN: "{{.*}}libclang_rt.ubsan_standalone.so{{.*}}" // RUN: %clang -fsanitize=undefined -fsanitize-link-c++-runtime -### %s 2>&1 \ @@ -523,7 +523,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-UBSAN-LINUX-CXX -// CHECK-UBSAN-LINUX-CXX: "{{.*}}ld" +// CHECK-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}" // CHECK-UBSAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.ubsan_standalone.a" "--no-whole-archive" // CHECK-UBSAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.ubsan_standalone_cxx.a" "--no-whole-archive" // CHECK-UBSAN-LINUX-CXX: "-lstdc++" @@ -535,7 +535,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-UBSAN-MINIMAL-LINUX -// CHECK-UBSAN-MINIMAL-LINUX: "{{.*}}ld" +// CHECK-UBSAN-MINIMAL-LINUX: "{{.*}}ld{{(.exe)?}}" // CHECK-UBSAN-MINIMAL-LINUX: "--whole-archive" "{{.*}}libclang_rt.ubsan_minimal.a" "--no-whole-archive" // CHECK-UBSAN-MINIMAL-LINUX: "-lpthread" // CHECK-UBSAN-MINIMAL-LINUX: "-lresolv" @@ -544,7 +544,7 @@ // RUN: --target=x86_64-apple-darwin -fuse-ld=ld \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-UBSAN-MINIMAL-DARWIN -// CHECK-UBSAN-MINIMAL-DARWIN: "{{.*}}ld" +// CHECK-UBSAN-MINIMAL-DARWIN: "{{.*}}ld{{(.exe)?}}" // CHECK-UBSAN-MINIMAL-DARWIN: "{{.*}}libclang_rt.ubsan_minimal_osx_dynamic.dylib" // RUN: not %clang -fsanitize=undefined -### %s 2>&1 \ @@ -570,7 +570,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-ASAN-UBSAN-LINUX -// CHECK-ASAN-UBSAN-LINUX: "{{.*}}ld" +// CHECK-ASAN-UBSAN-LINUX: "{{.*}}ld{{(.exe)?}}" // CHECK-ASAN-UBSAN-LINUX: "--whole-archive" "{{.*}}libclang_rt.asan_static.a" "--no-whole-archive" // CHECK-ASAN-UBSAN-LINUX: "--whole-archive" "{{.*}}libclang_rt.asan.a" "--no-whole-archive" // CHECK-ASAN-UBSAN-LINUX: "--dynamic-list={{.*}}libclang_rt.asan.a.syms" @@ -583,7 +583,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-ASAN-UBSAN-LINUX-CXX -// CHECK-ASAN-UBSAN-LINUX-CXX: "{{.*}}ld" +// CHECK-ASAN-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}" // CHECK-ASAN-UBSAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.asan_static.a" "--no-whole-archive" // CHECK-ASAN-UBSAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.asan.a" "--no-whole-archive" // CHECK-ASAN-UBSAN-LINUX-CXX: "--dynamic-list={{.*}}libclang_rt.asan.a.syms" @@ -598,7 +598,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-ASAN-UBSAN-NOVPTR-LINUX-CXX -// CHECK-ASAN-UBSAN-NOVPTR-LINUX-CXX: "{{.*}}ld" +// CHECK-ASAN-UBSAN-NOVPTR-LINUX-CXX: "{{.*}}ld{{(.exe)?}}" // CHECK-ASAN-UBSAN-NOVPTR-LINUX-CXX-SAME: "--whole-archive" "{{.*}}libclang_rt.asan_static.a" "--no-whole-archive" // CHECK-ASAN-UBSAN-NOVPTR-LINUX-CXX-SAME: "--whole-archive" "{{.*}}libclang_rt.asan.a" "--no-whole-archive" // CHECK-ASAN-UBSAN-NOVPTR-LINUX-CXX-SAME: "--dynamic-list={{.*}}libclang_rt.asan.a.syms" @@ -612,7 +612,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-MSAN-UBSAN-LINUX-CXX -// CHECK-MSAN-UBSAN-LINUX-CXX: "{{.*}}ld" +// CHECK-MSAN-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}" // CHECK-MSAN-UBSAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.msan.a" "--no-whole-archive" // CHECK-MSAN-UBSAN-LINUX-CXX: "--dynamic-list={{.*}}libclang_rt.msan.a.syms" // CHECK-MSAN-UBSAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.msan_cxx.a" "--no-whole-archive" @@ -624,7 +624,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-TSAN-UBSAN-LINUX-CXX -// CHECK-TSAN-UBSAN-LINUX-CXX: "{{.*}}ld" +// CHECK-TSAN-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}" // CHECK-TSAN-UBSAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.tsan.a" "--no-whole-archive" // CHECK-TSAN-UBSAN-LINUX-CXX: "--dynamic-list={{.*}}libclang_rt.tsan.a.syms" // CHECK-TSAN-UBSAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.tsan_cxx.a" "--no-whole-archive" @@ -637,7 +637,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: -shared \ // RUN: | %{filecheck} --check-prefix=CHECK-UBSAN-LINUX-SHARED -// CHECK-UBSAN-LINUX-SHARED: "{{.*}}ld" +// CHECK-UBSAN-LINUX-SHARED: "{{.*}}ld{{(.exe)?}}" // CHECK-UBSAN-LINUX-SHARED-NOT: --export-dynamic // CHECK-UBSAN-LINUX-SHARED-NOT: --dynamic-list @@ -647,7 +647,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-LSAN-LINUX // -// CHECK-LSAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-LSAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-LSAN-LINUX-NOT: "-lc" // CHECK-LSAN-LINUX: libclang_rt.lsan.a" // CHECK-LSAN-LINUX: "-lpthread" @@ -660,7 +660,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-LSAN-NO-LINK-RUNTIME-LINUX // -// CHECK-LSAN-NO-LINK-RUNTIME-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-LSAN-NO-LINK-RUNTIME-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -fuse-ld=ld -fsanitize=leak -fsanitize-coverage=func \ @@ -668,7 +668,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-LSAN-COV-LINUX // -// CHECK-LSAN-COV-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-LSAN-COV-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-LSAN-COV-LINUX-NOT: "-lc" // CHECK-LSAN-COV-LINUX: libclang_rt.lsan.a // CHECK-LSAV-COV-LINUX: libclang_rt.lsan-x86_64.a" @@ -681,7 +681,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-LSAN-ASAN-LINUX -// CHECK-LSAN-ASAN-LINUX: "{{.*}}ld" +// CHECK-LSAN-ASAN-LINUX: "{{.*}}ld{{(.exe)?}}" // CHECK-LSAN-ASAN-LINUX: libclang_rt.asan_static // CHECK-LSAN-ASAN-LINUX: libclang_rt.asan // CHECK-LSAN-ASAN-LINUX: "--dynamic-list={{.*}}libclang_rt.asan.a.syms" @@ -691,7 +691,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-ASAN-COV-LINUX -// CHECK-ASAN-COV-LINUX: "{{.*}}ld" +// CHECK-ASAN-COV-LINUX: "{{.*}}ld{{(.exe)?}}" // CHECK-ASAN-COV-LINUX: libclang_rt.asan_static // CHECK-ASAN-COV-LINUX: libclang_rt.asan // CHECK-ASAN-COV-LINUX: "--dynamic-list={{.*}}libclang_rt.asan.a.syms" @@ -704,7 +704,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-MSAN-COV-LINUX -// CHECK-MSAN-COV-LINUX: "{{.*}}ld" +// CHECK-MSAN-COV-LINUX: "{{.*}}ld{{(.exe)?}}" // CHECK-MSAN-COV-LINUX: "--whole-archive" "{{.*}}libclang_rt.msan.a" "--no-whole-archive" // CHECK-MSAN-COV-LINUX: "--dynamic-list={{.*}}libclang_rt.msan.a.syms" // CHECK-MSAN-COV-LINUX-NOT: "-lstdc++" @@ -716,7 +716,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-DFSAN-COV-LINUX -// CHECK-DFSAN-COV-LINUX: "{{.*}}ld" +// CHECK-DFSAN-COV-LINUX: "{{.*}}ld{{(.exe)?}}" // CHECK-DFSAN-COV-LINUX: "--whole-archive" "{{.*}}libclang_rt.dfsan.a" "--no-whole-archive" // CHECK-DFSAN-COV-LINUX-NOT: "-lstdc++" // CHECK-DFSAN-COV-LINUX: "-lpthread" @@ -727,7 +727,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-UBSAN-COV-LINUX -// CHECK-UBSAN-COV-LINUX: "{{.*}}ld" +// CHECK-UBSAN-COV-LINUX: "{{.*}}ld{{(.exe)?}}" // CHECK-UBSAN-COV-LINUX: "--whole-archive" "{{.*}}libclang_rt.ubsan_standalone.a" "--no-whole-archive" // CHECK-UBSAN-COV-LINUX-NOT: "-lstdc++" // CHECK-UBSAN-COV-LINUX: "-lpthread" @@ -738,7 +738,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-COV-LINUX -// CHECK-COV-LINUX: "{{.*}}ld" +// CHECK-COV-LINUX: "{{.*}}ld{{(.exe)?}}" // CHECK-COV-LINUX: "--whole-archive" "{{.*}}libclang_rt.ubsan_standalone.a" "--no-whole-archive" // CHECK-COV-LINUX-NOT: "-lstdc++" // CHECK-COV-LINUX: "-lpthread" @@ -750,7 +750,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-NSAN-LINUX // -// CHECK-NSAN-LINUX: "{{.*}}ld" +// CHECK-NSAN-LINUX: "{{.*}}ld{{(.exe)?}}" // CHECK-NSAN-LINUX-NOT: "-lc" // CHECK-NSAN-LINUX: libclang_rt.nsan.a" // CHECK-NSAN-LINUX: "-lpthread" "-lrt" "-lm" "-ldl" "-lresolv" @@ -778,7 +778,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-CFI-LINUX -// CHECK-CFI-LINUX: "{{.*}}ld" +// CHECK-CFI-LINUX: "{{.*}}ld{{(.exe)?}}" // CFI with diagnostics links the UBSan runtime. // RUN: not %clang -fsanitize=cfi -fno-sanitize-trap=cfi -fsanitize-recover=cfi \ @@ -787,7 +787,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-CFI-DIAG-LINUX -// CHECK-CFI-DIAG-LINUX: "{{.*}}ld" +// CHECK-CFI-DIAG-LINUX: "{{.*}}ld{{(.exe)?}}" // CHECK-CFI-DIAG-LINUX: "--whole-archive" "{{[^"]*}}libclang_rt.ubsan_standalone.a" "--no-whole-archive" // Cross-DSO CFI links the CFI runtime. @@ -796,7 +796,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-CFI-CROSS-DSO-LINUX -// CHECK-CFI-CROSS-DSO-LINUX: "{{.*}}ld" +// CHECK-CFI-CROSS-DSO-LINUX: "{{.*}}ld{{(.exe)?}}" // CHECK-CFI-CROSS-DSO-LINUX: "--whole-archive" "{{[^"]*}}libclang_rt.cfi.a" "--no-whole-archive" // CHECK-CFI-CROSS-DSO-LINUX: -export-dynamic @@ -807,7 +807,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-CFI-CROSS-DSO-DIAG-LINUX -// CHECK-CFI-CROSS-DSO-DIAG-LINUX: "{{.*}}ld" +// CHECK-CFI-CROSS-DSO-DIAG-LINUX: "{{.*}}ld{{(.exe)?}}" // CHECK-CFI-CROSS-DSO-DIAG-LINUX: "--whole-archive" "{{[^"]*}}libclang_rt.cfi_diag.a" "--no-whole-archive" // CHECK-CFI-CROSS-DSO-DIAG-LINUX: -export-dynamic @@ -836,7 +836,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-ASAN-DARWIN106-CXX -// CHECK-ASAN-DARWIN106-CXX: "{{.*}}ld" +// CHECK-ASAN-DARWIN106-CXX: "{{.*}}ld{{(.exe)?}}" // CHECK-ASAN-DARWIN106-CXX: libclang_rt.asan_osx_dynamic.dylib // CHECK-ASAN-DARWIN106-CXX-NOT: -lc++abi @@ -846,7 +846,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-LSAN-DARWIN106-CXX -// CHECK-LSAN-DARWIN106-CXX: "{{.*}}ld" +// CHECK-LSAN-DARWIN106-CXX: "{{.*}}ld{{(.exe)?}}" // CHECK-LSAN-DARWIN106-CXX: libclang_rt.lsan_osx_dynamic.dylib // CHECK-LSAN-DARWIN106-CXX-NOT: -lc++abi @@ -856,7 +856,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-SAFESTACK-LINUX // -// CHECK-SAFESTACK-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-SAFESTACK-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-SAFESTACK-LINUX-NOT: "-lc" // CHECK-SAFESTACK-LINUX-NOT: whole-archive // CHECK-SAFESTACK-LINUX: "-u" "__safestack_init" @@ -869,7 +869,7 @@ // RUN: --target=x86_64-unknown-linux -fuse-ld=ld \ // RUN: | %{filecheck} --check-prefix=CHECK-SHADOWCALLSTACK-LINUX-X86-64 // CHECK-SHADOWCALLSTACK-LINUX-X86-64-NOT: error: -// CHECK-SHADOWCALLSTACK-LINUX-X86-64: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-SHADOWCALLSTACK-LINUX-X86-64: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // RUN: not %clang -fsanitize=shadow-call-stack -### %s 2>&1 \ // RUN: --target=aarch64-unknown-linux -fuse-ld=ld \ @@ -886,7 +886,7 @@ // RUN: --target=riscv64-unknown-linux -fuse-ld=ld \ // RUN: | %{filecheck} --check-prefix=CHECK-SHADOWCALLSTACK-LINUX-RISCV64 // CHECK-SHADOWCALLSTACK-LINUX-RISCV64-NOT: error: -// CHECK-SHADOWCALLSTACK-LINUX-RISCV64: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-SHADOWCALLSTACK-LINUX-RISCV64: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // RUN: %clang -target riscv64-linux-android -fsanitize=shadow-call-stack %s -### 2>&1 \ // RUN: | %{filecheck} --check-prefix=CHECK-SHADOWCALLSTACK-ANDROID-RISCV64 @@ -906,7 +906,7 @@ // RUN: --target=arm64-unknown-ios -fuse-ld=ld \ // RUN: | %{filecheck} --check-prefix=CHECK-SHADOWCALLSTACK-LINUX-AARCH64-X18 // CHECK-SHADOWCALLSTACK-LINUX-AARCH64-X18-NOT: error: -// CHECK-SHADOWCALLSTACK-LINUX-AARCH64-X18: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-SHADOWCALLSTACK-LINUX-AARCH64-X18: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // RUN: %clang -fsanitize=shadow-call-stack -### %s 2>&1 \ // RUN: --target=aarch64-unknown-linux-android -fuse-ld=ld \ @@ -923,15 +923,15 @@ // RUN: -fsanitize=safe-stack --target=x86_64-unknown-linux -fuse-ld=ld \ // RUN: | %{filecheck} --check-prefix=CHECK-SHADOWCALLSTACK-SAFESTACK // CHECK-SHADOWCALLSTACK-SAFESTACK-NOT: error: -// CHECK-SHADOWCALLSTACK-SAFESTACK: "{{(.*[^-.0-9A-Z_a-z])?}}ld" -// CHECK-SHADOWCALLSTACK-SAFESTACK: libclang_rt.safestack-x86_64.a +// CHECK-SHADOWCALLSTACK-SAFESTACK: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" +// CHECK-SHADOWCALLSTACK-SAFESTACK: libclang_rt.safestack{{.*}}.a // RUN: not %clang -fsanitize=cfi -fsanitize-stats -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -fuse-ld=ld \ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-CFI-STATS-LINUX -// CHECK-CFI-STATS-LINUX: "{{.*}}ld" +// CHECK-CFI-STATS-LINUX: "{{.*}}ld{{(.exe)?}}" // CHECK-CFI-STATS-LINUX: "--whole-archive" "{{[^"]*}}libclang_rt.stats_client.a" "--no-whole-archive" // CHECK-CFI-STATS-LINUX-NOT: "--whole-archive" // CHECK-CFI-STATS-LINUX: "{{[^"]*}}libclang_rt.stats.a" @@ -940,7 +940,7 @@ // RUN: --target=x86_64-apple-darwin -fuse-ld=ld \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-CFI-STATS-DARWIN -// CHECK-CFI-STATS-DARWIN: "{{.*}}ld" +// CHECK-CFI-STATS-DARWIN: "{{.*}}ld{{(.exe)?}}" // CHECK-CFI-STATS-DARWIN: "{{[^"]*}}libclang_rt.stats_client_osx.a" // CHECK-CFI-STATS-DARWIN: "{{[^"]*}}libclang_rt.stats_osx_dynamic.dylib" @@ -1066,7 +1066,7 @@ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-SCUDO-LINUX -// CHECK-SCUDO-LINUX: "{{.*}}ld" +// CHECK-SCUDO-LINUX: "{{.*}}ld{{(.exe)?}}" // CHECK-SCUDO-LINUX: "--whole-archive" "{{.*}}libclang_rt.scudo_standalone.a" "--no-whole-archive" // CHECK-SCUDO-LINUX-NOT: "-lstdc++" // CHECK-SCUDO-LINUX: "-lpthread" @@ -1079,7 +1079,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-SCUDO-SHARED-LINUX // -// CHECK-SCUDO-SHARED-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-SCUDO-SHARED-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-SCUDO-SHARED-LINUX-NOT: "-lc" // CHECK-SCUDO-SHARED-LINUX: libclang_rt.scudo_standalone.so" // CHECK-SCUDO-SHARED-LINUX-NOT: "-lpthread" @@ -1122,7 +1122,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-HWASAN-X86-64-LINUX // -// CHECK-HWASAN-X86-64-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-HWASAN-X86-64-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-HWASAN-X86-64-LINUX-NOT: "-lc" // CHECK-HWASAN-X86-64-LINUX: libclang_rt.hwasan.a" // CHECK-HWASAN-X86-64-LINUX-NOT: "--export-dynamic" @@ -1139,7 +1139,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-SHARED-HWASAN-X86-64-LINUX // -// CHECK-SHARED-HWASAN-X86-64-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-SHARED-HWASAN-X86-64-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-SHARED-HWASAN-X86-64-LINUX-NOT: "-lc" // CHECK-SHARED-HWASAN-X86-64-LINUX: libclang_rt.hwasan.so" // CHECK-SHARED-HWASAN-X86-64-LINUX: libclang_rt.hwasan-preinit.a" @@ -1156,7 +1156,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-DSO-SHARED-HWASAN-X86-64-LINUX // -// CHECK-DSO-SHARED-HWASAN-X86-64-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-DSO-SHARED-HWASAN-X86-64-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-DSO-SHARED-HWASAN-X86-64-LINUX-NOT: "-lc" // CHECK-DSO-SHARED-HWASAN-X86-64-LINUX: libclang_rt.hwasan.so" // CHECK-DSO-SHARED-HWASAN-X86-64-LINUX-NOT: "-lpthread" @@ -1172,7 +1172,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-HWASAN-AARCH64-LINUX // -// CHECK-HWASAN-AARCH64-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-HWASAN-AARCH64-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-HWASAN-AARCH64-LINUX-NOT: "-lc" // CHECK-HWASAN-AARCH64-LINUX: libclang_rt.hwasan.a" // CHECK-HWASAN-AARCH64-LINUX-NOT: "--export-dynamic" @@ -1190,7 +1190,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-SHARED-HWASAN-AARCH64-LINUX // -// CHECK-SHARED-HWASAN-AARCH64-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-SHARED-HWASAN-AARCH64-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-SHARED-HWASAN-AARCH64-LINUX-NOT: "-lc" // CHECK-SHARED-HWASAN-AARCH64-LINUX: libclang_rt.hwasan.so" // CHECK-SHARED-HWASAN-AARCH64-LINUX: libclang_rt.hwasan-preinit.a" @@ -1207,7 +1207,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | %{filecheck} --check-prefix=CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX // -// CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld" +// CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX-NOT: "-lc" // CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX: libclang_rt.hwasan.so" // CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX-NOT: "-lpthread" diff --git a/compiler-rt/test/profile/ContinuousSyncMode/basic.c b/compiler-rt/test/profile/ContinuousSyncMode/basic.c index e8bd087a0f59d8..531877b78a1a29 100644 --- a/compiler-rt/test/profile/ContinuousSyncMode/basic.c +++ b/compiler-rt/test/profile/ContinuousSyncMode/basic.c @@ -1,4 +1,4 @@ -// REQUIRES: target={{.*(darwin|aix).*}} +// REQUIRES: continuous-mode // RUN: %clang_profgen_cont -fcoverage-mapping -o %t.exe %s // RUN: echo "garbage" > %t.profraw diff --git a/compiler-rt/test/profile/ContinuousSyncMode/get-filename.c b/compiler-rt/test/profile/ContinuousSyncMode/get-filename.c index 40a0cc5ffd6886..e341dd429eb84d 100644 --- a/compiler-rt/test/profile/ContinuousSyncMode/get-filename.c +++ b/compiler-rt/test/profile/ContinuousSyncMode/get-filename.c @@ -1,4 +1,4 @@ -// REQUIRES: target={{.*(darwin|aix).*}} +// REQUIRES: continuous-mode // RUN: %clang_pgogen_cont -o %t.exe %s // RUN: env LLVM_PROFILE_FILE="%c%t.profraw" %run %t.exe %t.profraw diff --git a/compiler-rt/test/profile/ContinuousSyncMode/image-with-mcdc.c b/compiler-rt/test/profile/ContinuousSyncMode/image-with-mcdc.c index d171badbf4d332..fa24e26c4c53b8 100644 --- a/compiler-rt/test/profile/ContinuousSyncMode/image-with-mcdc.c +++ b/compiler-rt/test/profile/ContinuousSyncMode/image-with-mcdc.c @@ -1,4 +1,4 @@ -// REQUIRES: target={{.*(darwin|aix).*}} +// REQUIRES: continuous-mode // RUN: %clang_profgen_cont -fcoverage-mapping -fcoverage-mcdc -O3 -o %t.exe %s // RUN: env LLVM_PROFILE_FILE="%c%t.profraw" %run %t.exe 3 3 diff --git a/compiler-rt/test/profile/ContinuousSyncMode/multi-threaded.cpp b/compiler-rt/test/profile/ContinuousSyncMode/multi-threaded.cpp index ff05a69a5e7d4d..aa0a46e0fc396d 100644 --- a/compiler-rt/test/profile/ContinuousSyncMode/multi-threaded.cpp +++ b/compiler-rt/test/profile/ContinuousSyncMode/multi-threaded.cpp @@ -1,4 +1,4 @@ -// REQUIRES: target={{.*(darwin|aix).*}} +// REQUIRES: continuous-mode // RUN: rm -f %t.profraw // RUN: %clangxx_pgogen_cont -lpthread %s -o %t.exe -mllvm -disable-vp -fprofile-update=atomic diff --git a/compiler-rt/test/profile/ContinuousSyncMode/online-merging.c b/compiler-rt/test/profile/ContinuousSyncMode/online-merging.c index 54346487a5c795..c1931410f8c760 100644 --- a/compiler-rt/test/profile/ContinuousSyncMode/online-merging.c +++ b/compiler-rt/test/profile/ContinuousSyncMode/online-merging.c @@ -1,4 +1,4 @@ -// REQUIRES: target={{.*(darwin|aix).*}} +// REQUIRES: continuous-mode // Test the online merging mode (%m) along with continuous mode (%c). // diff --git a/compiler-rt/test/profile/ContinuousSyncMode/pid-substitution.c b/compiler-rt/test/profile/ContinuousSyncMode/pid-substitution.c index 309b685a95c5bc..8a00b28825cae6 100644 --- a/compiler-rt/test/profile/ContinuousSyncMode/pid-substitution.c +++ b/compiler-rt/test/profile/ContinuousSyncMode/pid-substitution.c @@ -1,4 +1,4 @@ -// REQUIRES: target={{.*(darwin|aix).*}} +// REQUIRES: continuous-mode // RUN: rm -rf %t.dir && mkdir -p %t.dir // RUN: %clang_pgogen_cont -o %t.exe %s diff --git a/compiler-rt/test/profile/ContinuousSyncMode/set-filename.c b/compiler-rt/test/profile/ContinuousSyncMode/set-filename.c index 106e12e4e3b6eb..abc72646d16b42 100644 --- a/compiler-rt/test/profile/ContinuousSyncMode/set-filename.c +++ b/compiler-rt/test/profile/ContinuousSyncMode/set-filename.c @@ -1,4 +1,4 @@ -// REQUIRES: target={{.*(darwin|aix).*}} +// REQUIRES: continuous-mode // RUN: %clang_pgogen_cont -o %t.exe %s // RUN: env LLVM_PROFILE_FILE="%c%t.profraw" %run %t.exe %t.profraw %t.bad diff --git a/compiler-rt/test/profile/lit.cfg.py b/compiler-rt/test/profile/lit.cfg.py index 72a389eaf0dfb2..fc2baf7c40b8fc 100644 --- a/compiler-rt/test/profile/lit.cfg.py +++ b/compiler-rt/test/profile/lit.cfg.py @@ -31,7 +31,7 @@ def get_required_attr(config, attr_name): target_is_msvc = bool(re.match(r".*-windows-msvc$", config.target_triple)) # Whether continous profile collection (%c) requires runtime counter relocation on this platform -runtime_reloc = bool(config.host_os in ["AIX"]) +runtime_reloc = bool(config.host_os in ["AIX", "Linux"]) if config.host_os in ["Linux"]: extra_link_flags = ["-ldl"] @@ -210,3 +210,6 @@ def exclude_unsupported_files_for_aix(dirname): if config.have_curl: config.available_features.add("curl") + +if config.host_os in ("AIX", "Darwin", "Linux"): + config.available_features.add("continuous-mode") diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index a4d6b94812d937..ae5b095fba7729 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -2824,6 +2824,7 @@ void LinkerDriver::linkerMain(ArrayRef argsArr) { if (ctx.symtabEC) ctx.symtabEC->initializeECThunks(); + ctx.forEachSymtab([](SymbolTable &symtab) { symtab.initializeLoadConfig(); }); // Identify unreferenced COMDAT sections. if (config->doGC) { diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index b1d375b2265835..fc78afb4c9e400 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -27,6 +27,7 @@ #include using namespace llvm; +using namespace llvm::support; namespace lld::coff { @@ -596,6 +597,52 @@ std::pair SymbolTable::insert(StringRef name, InputFile *file) { return result; } +void SymbolTable::initializeLoadConfig() { + auto sym = + dyn_cast_or_null(findUnderscore("_load_config_used")); + if (!sym) { + if (ctx.config.guardCF != GuardCFLevel::Off) + Warn(ctx) + << "Control Flow Guard is enabled but '_load_config_used' is missing"; + if (ctx.config.dependentLoadFlags) + Warn(ctx) << "_load_config_used not found, /dependentloadflag will have " + "no effect"; + return; + } + + SectionChunk *sc = sym->getChunk(); + if (!sc->hasData) { + Err(ctx) << "_load_config_used points to uninitialized data"; + return; + } + uint64_t offsetInChunk = sym->getValue(); + if (offsetInChunk + 4 > sc->getSize()) { + Err(ctx) << "_load_config_used section chunk is too small"; + return; + } + + ArrayRef secContents = sc->getContents(); + loadConfigSize = + *reinterpret_cast(&secContents[offsetInChunk]); + if (offsetInChunk + loadConfigSize > sc->getSize()) { + Err(ctx) << "_load_config_used specifies a size larger than its containing " + "section chunk"; + return; + } + + uint32_t expectedAlign = ctx.config.is64() ? 8 : 4; + if (sc->getAlignment() < expectedAlign) + Warn(ctx) << "'_load_config_used' is misaligned (expected alignment to be " + << expectedAlign << " bytes, got " << sc->getAlignment() + << " instead)"; + else if (!isAligned(Align(expectedAlign), offsetInChunk)) + Warn(ctx) << "'_load_config_used' is misaligned (section offset is 0x" + << Twine::utohexstr(sym->getValue()) << " not aligned to " + << expectedAlign << " bytes)"; + + loadConfigSym = sym; +} + void SymbolTable::addEntryThunk(Symbol *from, Symbol *to) { entryThunks.push_back({from, to}); } diff --git a/lld/COFF/SymbolTable.h b/lld/COFF/SymbolTable.h index b694893b903aa3..8548a6d036a9db 100644 --- a/lld/COFF/SymbolTable.h +++ b/lld/COFF/SymbolTable.h @@ -138,6 +138,10 @@ class SymbolTable { callback(pair.second); } + DefinedRegular *loadConfigSym = nullptr; + uint32_t loadConfigSize = 0; + void initializeLoadConfig(); + private: /// Given a name without "__imp_" prefix, returns a defined symbol /// with the "__imp_" prefix, if it exists. diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 3c6112b7fc89ad..e6b239c83dd4a2 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -1837,22 +1837,10 @@ template void Writer::writeHeader() { dir[DEBUG_DIRECTORY].RelativeVirtualAddress = debugDirectory->getRVA(); dir[DEBUG_DIRECTORY].Size = debugDirectory->getSize(); } - if (Symbol *sym = ctx.symtab.findUnderscore("_load_config_used")) { - if (auto *b = dyn_cast(sym)) { - SectionChunk *sc = b->getChunk(); - assert(b->getRVA() >= sc->getRVA()); - uint64_t offsetInChunk = b->getRVA() - sc->getRVA(); - if (!sc->hasData || offsetInChunk + 4 > sc->getSize()) - Fatal(ctx) << "_load_config_used is malformed"; - - ArrayRef secContents = sc->getContents(); - uint32_t loadConfigSize = - *reinterpret_cast(&secContents[offsetInChunk]); - if (offsetInChunk + loadConfigSize > sc->getSize()) - Fatal(ctx) << "_load_config_used is too large"; - dir[LOAD_CONFIG_TABLE].RelativeVirtualAddress = b->getRVA(); - dir[LOAD_CONFIG_TABLE].Size = loadConfigSize; - } + if (ctx.symtab.loadConfigSym) { + dir[LOAD_CONFIG_TABLE].RelativeVirtualAddress = + ctx.symtab.loadConfigSym->getRVA(); + dir[LOAD_CONFIG_TABLE].Size = ctx.symtab.loadConfigSize; } if (!delayIdata.empty()) { dir[DELAY_IMPORT_DESCRIPTOR].RelativeVirtualAddress = @@ -2649,31 +2637,14 @@ void Writer::fixTlsAlignment() { } void Writer::prepareLoadConfig() { - Symbol *sym = ctx.symtab.findUnderscore("_load_config_used"); - auto *b = cast_if_present(sym); - if (!b) { - if (ctx.config.guardCF != GuardCFLevel::Off) - Warn(ctx) - << "Control Flow Guard is enabled but '_load_config_used' is missing"; - if (ctx.config.dependentLoadFlags) - Warn(ctx) << "_load_config_used not found, /dependentloadflag will have " - "no effect"; + if (!ctx.symtab.loadConfigSym) return; - } - OutputSection *sec = ctx.getOutputSection(b->getChunk()); - uint8_t *buf = buffer->getBufferStart(); - uint8_t *secBuf = buf + sec->getFileOff(); - uint8_t *symBuf = secBuf + (b->getRVA() - sec->getRVA()); - uint32_t expectedAlign = ctx.config.is64() ? 8 : 4; - if (b->getChunk()->getAlignment() < expectedAlign) - Warn(ctx) << "'_load_config_used' is misaligned (expected alignment to be " - << expectedAlign << " bytes, got " - << b->getChunk()->getAlignment() << " instead)"; - else if (!isAligned(Align(expectedAlign), b->getRVA())) - Warn(ctx) << "'_load_config_used' is misaligned (RVA is 0x" - << Twine::utohexstr(b->getRVA()) << " not aligned to " - << expectedAlign << " bytes)"; + OutputSection *sec = + ctx.getOutputSection(ctx.symtab.loadConfigSym->getChunk()); + uint8_t *secBuf = buffer->getBufferStart() + sec->getFileOff(); + uint8_t *symBuf = + secBuf + (ctx.symtab.loadConfigSym->getRVA() - sec->getRVA()); if (ctx.config.is64()) prepareLoadConfig(reinterpret_cast(symBuf)); diff --git a/lld/test/COFF/guard-warnings.s b/lld/test/COFF/guard-warnings.s index 77448ee95c0095..092871597d1f80 100644 --- a/lld/test/COFF/guard-warnings.s +++ b/lld/test/COFF/guard-warnings.s @@ -38,7 +38,7 @@ # RUN: llvm-mc -triple x86_64-windows-msvc %t/loadcfg-misaligned2.s -filetype=obj -o %t/loadcfg-misaligned2.obj # RUN: lld-link %t/main.obj %t/loadcfg-misaligned2.obj -guard:cf,longjmp,ehcont -out:%t-misaligned2.exe -entry:main %basename_t-exp.lib 2>&1 | FileCheck %s --check-prefix=WARN_ALIGN2 -# WARN_ALIGN2: warning: '_load_config_used' is misaligned (RVA is 0x{{[0-9A-F]*}}2 not aligned to 8 bytes) +# WARN_ALIGN2: warning: '_load_config_used' is misaligned (section offset is 0x{{[0-9A-F]*}}2 not aligned to 8 bytes) # RUN: llvm-mc -triple x86_64-windows-msvc %t/loadcfg-full.s -filetype=obj -o %t/loadcfg-full.obj # RUN: lld-link %t/main.obj %t/loadcfg-full.obj -guard:cf,longjmp,ehcont -out:%t.exe -entry:main %basename_t-exp.lib 2>&1 | FileCheck %s --check-prefix=NOWARN --allow-empty diff --git a/lld/test/COFF/loadcfg-short.test b/lld/test/COFF/loadcfg-short.test new file mode 100644 index 00000000000000..dd4d4389ddc1cc --- /dev/null +++ b/lld/test/COFF/loadcfg-short.test @@ -0,0 +1,33 @@ +# RUN: yaml2obj %s -o %t.obj +# RUN: not lld-link -out:%t.dll %t.obj -dll -noentry 2>&1 | FileCheck %s +# CHECK: lld-link: error: _load_config_used section chunk is too small + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [] +sections: + - Name: .rdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: '030000' +symbols: + - Name: .rdata + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 112 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 3 + - Name: _load_config_used + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... diff --git a/lld/test/COFF/loadcfg-size.test b/lld/test/COFF/loadcfg-size.test new file mode 100644 index 00000000000000..871590f2328b63 --- /dev/null +++ b/lld/test/COFF/loadcfg-size.test @@ -0,0 +1,33 @@ +# RUN: yaml2obj %s -o %t.obj +# RUN: not lld-link -out:%t.dll %t.obj -dll -noentry 2>&1 | FileCheck %s +# CHECK: lld-link: error: _load_config_used specifies a size larger than its containing section chunk + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [] +sections: + - Name: .rdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: '0c00000000000000' +symbols: + - Name: .rdata + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 112 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 3 + - Name: _load_config_used + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... diff --git a/lld/test/COFF/loadcfg-uninitialized.test b/lld/test/COFF/loadcfg-uninitialized.test new file mode 100644 index 00000000000000..5f956bc7224bc9 --- /dev/null +++ b/lld/test/COFF/loadcfg-uninitialized.test @@ -0,0 +1,33 @@ +# RUN: yaml2obj %s -o %t.obj +# RUN: not lld-link -out:%t.dll %t.obj -dll -noentry 2>&1 | FileCheck %s +# CHECK: lld-link: error: _load_config_used points to uninitialized data + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [] +sections: + - Name: .rdata + Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + Alignment: 16 + VirtualSize: 0x140 +symbols: + - Name: .rdata + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 112 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 3 + - Name: _load_config_used + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst index f6a0dd4bf2383c..22600f5720553e 100644 --- a/llvm/docs/RISCVUsage.rst +++ b/llvm/docs/RISCVUsage.rst @@ -429,6 +429,9 @@ The current vendor extensions supported are: ``experimental-Xqcia`` LLVM implements `version 0.2 of the Qualcomm uC Arithmetic extension specification `__ by Qualcomm. All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32. +``experimental-Xqciac`` + LLVM implements `version 0.2 of the Qualcomm uC Load-Store Address Calculation extension specification `__ by Qualcomm. All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32. + ``experimental-Xqcics`` LLVM implements `version 0.2 of the Qualcomm uC Conditional Select extension specification `__ by Qualcomm. All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32. diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index c1b3f2f719611e..0d1d097eefc1cf 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -226,6 +226,8 @@ Changes to the RISC-V Backend extension. * Adds experimental assembler support for the Qualcomm uC 'Xqcia` (Arithmetic) extension. +* Adds experimental assembler support for the Qualcomm uC 'Xqciac` (Load-Store Address Calculation) + extension. * Adds experimental assembler support for the Qualcomm uC 'Xqcics` (Conditonal Select) extension. * Adds experimental assembler support for the Qualcomm uC 'Xqcilsm` (Load Store Multiple) diff --git a/llvm/lib/CodeGen/PostRASchedulerList.cpp b/llvm/lib/CodeGen/PostRASchedulerList.cpp index 2f7cfdd275b4fd..badfd9a68d6a01 100644 --- a/llvm/lib/CodeGen/PostRASchedulerList.cpp +++ b/llvm/lib/CodeGen/PostRASchedulerList.cpp @@ -98,12 +98,6 @@ namespace { } bool runOnMachineFunction(MachineFunction &Fn) override; - - private: - bool enablePostRAScheduler( - const TargetSubtargetInfo &ST, CodeGenOptLevel OptLevel, - TargetSubtargetInfo::AntiDepBreakMode &Mode, - TargetSubtargetInfo::RegClassVector &CriticalPathRCs) const; }; char PostRAScheduler::ID = 0; @@ -259,13 +253,8 @@ LLVM_DUMP_METHOD void SchedulePostRATDList::dumpSchedule() const { } #endif -bool PostRAScheduler::enablePostRAScheduler( - const TargetSubtargetInfo &ST, CodeGenOptLevel OptLevel, - TargetSubtargetInfo::AntiDepBreakMode &Mode, - TargetSubtargetInfo::RegClassVector &CriticalPathRCs) const { - Mode = ST.getAntiDepBreakMode(); - ST.getCriticalPathRCs(CriticalPathRCs); - +static bool enablePostRAScheduler(const TargetSubtargetInfo &ST, + CodeGenOptLevel OptLevel) { // Check for explicit enable/disable of post-ra scheduling. if (EnablePostRAScheduler.getPosition() > 0) return EnablePostRAScheduler; @@ -278,24 +267,17 @@ bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) { if (skipFunction(Fn.getFunction())) return false; - TII = Fn.getSubtarget().getInstrInfo(); - MachineLoopInfo &MLI = getAnalysis().getLI(); - AliasAnalysis *AA = &getAnalysis().getAAResults(); + const auto &Subtarget = Fn.getSubtarget(); TargetPassConfig *PassConfig = &getAnalysis(); - - RegClassInfo.runOnMachineFunction(Fn); - - TargetSubtargetInfo::AntiDepBreakMode AntiDepMode = - TargetSubtargetInfo::ANTIDEP_NONE; - SmallVector CriticalPathRCs; - // Check that post-RA scheduling is enabled for this target. - // This may upgrade the AntiDepMode. - if (!enablePostRAScheduler(Fn.getSubtarget(), PassConfig->getOptLevel(), - AntiDepMode, CriticalPathRCs)) + if (!enablePostRAScheduler(Subtarget, PassConfig->getOptLevel())) return false; - // Check for antidep breaking override... + TII = Subtarget.getInstrInfo(); + MachineLoopInfo &MLI = getAnalysis().getLI(); + AliasAnalysis *AA = &getAnalysis().getAAResults(); + TargetSubtargetInfo::AntiDepBreakMode AntiDepMode = + Subtarget.getAntiDepBreakMode(); if (EnableAntiDepBreaking.getPosition() > 0) { AntiDepMode = (EnableAntiDepBreaking == "all") ? TargetSubtargetInfo::ANTIDEP_ALL @@ -303,6 +285,9 @@ bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) { ? TargetSubtargetInfo::ANTIDEP_CRITICAL : TargetSubtargetInfo::ANTIDEP_NONE); } + SmallVector CriticalPathRCs; + Subtarget.getCriticalPathRCs(CriticalPathRCs); + RegClassInfo.runOnMachineFunction(Fn); LLVM_DEBUG(dbgs() << "PostRAScheduler\n"); diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 9dcf2e973e6c58..4c1fd5aa41e2b7 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -734,6 +734,16 @@ struct RISCVOperand final : public MCParsedAsmOperand { VK == RISCVMCExpr::VK_RISCV_None; } + bool isUImm5GT3() const { + if (!isImm()) + return false; + RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; + int64_t Imm; + bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); + return IsConstantImm && isUInt<5>(Imm) && (Imm > 3) && + VK == RISCVMCExpr::VK_RISCV_None; + } + bool isUImm8GE32() const { int64_t Imm; RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; @@ -1520,6 +1530,8 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); case Match_InvalidUImm5NonZero: return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1); + case Match_InvalidUImm5GT3: + return generateImmOutOfRangeError(Operands, ErrorInfo, 4, (1 << 5) - 1); case Match_InvalidUImm6: return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); case Match_InvalidUImm7: diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 99017195185fd3..57443d3f38e3cb 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -692,6 +692,9 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size, "Qualcomm uC Conditional Select custom opcode table"); TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcilsm, DecoderTableXqcilsm32, "Qualcomm uC Load Store Multiple custom opcode table"); + TRY_TO_DECODE_FEATURE( + RISCV::FeatureVendorXqciac, DecoderTableXqciac32, + "Qualcomm uC Load-Store Address Calculation custom opcode table"); TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table"); return MCDisassembler::Fail; @@ -718,6 +721,9 @@ DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size, TRY_TO_DECODE_FEATURE( RISCV::FeatureStdExtZcmp, DecoderTableRVZcmp16, "Zcmp table (16-bit Push/Pop & Double Move Instructions)"); + TRY_TO_DECODE_FEATURE( + RISCV::FeatureVendorXqciac, DecoderTableXqciac16, + "Qualcomm uC Load-Store Address Calculation custom 16bit opcode table"); TRY_TO_DECODE_AND_ADD_SP(STI.hasFeature(RISCV::FeatureVendorXwchc), DecoderTableXwchc16, "WCH QingKe XW custom opcode table"); diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index b9f4db065f2159..7fb5fc7a831308 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -302,6 +302,7 @@ enum OperandType : unsigned { OPERAND_UIMM4, OPERAND_UIMM5, OPERAND_UIMM5_NONZERO, + OPERAND_UIMM5_GT3, OPERAND_UIMM5_LSB0, OPERAND_UIMM6, OPERAND_UIMM6_LSB0, diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index dfc5658806abb8..916b140c5bde75 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -1274,6 +1274,14 @@ def HasVendorXqcilsm AssemblerPredicate<(all_of FeatureVendorXqcilsm), "'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)">; +def FeatureVendorXqciac + : RISCVExperimentalExtension<0, 2, "Qualcomm uC Load-Store Address Calculation Extension", + [FeatureStdExtZca]>; +def HasVendorXqciac + : Predicate<"Subtarget->hasVendorXqciac()">, + AssemblerPredicate<(all_of FeatureVendorXqciac), + "'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension)">; + //===----------------------------------------------------------------------===// // LLVM specific features and extensions //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td index 05b559178bfe63..ca73fbccd9d2d2 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td @@ -21,6 +21,13 @@ def uimm5nonzero : RISCVOp, let OperandType = "OPERAND_UIMM5_NONZERO"; } +def uimm5gt3 : RISCVOp, ImmLeaf 3) && isUInt<5>(Imm);}]> { + let ParserMatchClass = UImmAsmOperand<5, "GT3">; + let DecoderMethod = "decodeUImmOperand<5>"; + let OperandType = "OPERAND_UIMM5_GT3"; +} + def uimm11 : RISCVUImmLeafOp<11>; //===----------------------------------------------------------------------===// @@ -184,6 +191,37 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { } // hasSideEffects = 0, mayLoad = 0, mayStore = 0 } // Predicates = [HasVendorXqcia, IsRV32], DecoderNamespace = "Xqcia" +let Predicates = [HasVendorXqciac, IsRV32], DecoderNamespace = "Xqciac" in { +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { + def QC_C_MULADDI : RVInst16CL<0b001, 0b10, (outs GPRC:$rd_wb), + (ins GPRC:$rd, GPRC:$rs1, uimm5:$uimm), + "qc.c.muladdi", "$rd, $rs1, $uimm"> { + let Constraints = "$rd = $rd_wb"; + bits<5> uimm; + + let Inst{12-10} = uimm{3-1}; + let Inst{6} = uimm{0}; + let Inst{5} = uimm{4}; + } + + def QC_MULADDI : RVInstI<0b110, OPC_CUSTOM_0, (outs GPRNoX0:$rd_wb), + (ins GPRNoX0:$rd, GPRNoX0:$rs1, simm12:$imm12), + "qc.muladdi", "$rd, $rs1, $imm12"> { + let Constraints = "$rd = $rd_wb"; + } + + def QC_SHLADD : RVInstRBase<0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd), + (ins GPRNoX0:$rs1, GPRNoX0:$rs2, uimm5gt3:$shamt), + "qc.shladd", "$rd, $rs1, $rs2, $shamt"> { + bits<5> shamt; + + let Inst{31-30} = 0b01; + let Inst{29-25} = shamt; + } + +} // hasSideEffects = 0, mayLoad = 0, mayStore = 0 +} // Predicates = [HasVendorXqciac, IsRV32], DecoderNamespace = "Xqciac" + let Predicates = [HasVendorXqcics, IsRV32], DecoderNamespace = "Xqcics" in { def QC_SELECTIIEQ : QCISELECTIICC <0b010, "qc.selectiieq">; def QC_SELECTIINE : QCISELECTIICC <0b011, "qc.selectiine">; diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp index cafc9d304e83a7..e4e459a77b5f8f 100644 --- a/llvm/lib/TargetParser/RISCVISAInfo.cpp +++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp @@ -742,7 +742,7 @@ Error RISCVISAInfo::checkDependency() { bool HasZvl = MinVLen != 0; bool HasZcmt = Exts.count("zcmt") != 0; static constexpr StringLiteral XqciExts[] = { - {"xqcia"}, {"xqcics"}, {"xqcicsr"}, {"xqcilsm"}, {"xqcisls"}}; + {"xqcia"}, {"xqciac"}, {"xqcics"}, {"xqcicsr"}, {"xqcilsm"}, {"xqcisls"}}; if (HasI && HasE) return getIncompatibleError("i", "e"); diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll index f63bc944ccf22e..3f2b2c94707835 100644 --- a/llvm/test/CodeGen/RISCV/attributes.ll +++ b/llvm/test/CodeGen/RISCV/attributes.ll @@ -82,6 +82,7 @@ ; RUN: llc -mtriple=riscv32 -mattr=+xtheadsync %s -o - | FileCheck --check-prefix=RV32XTHEADSYNC %s ; RUN: llc -mtriple=riscv32 -mattr=+xwchc %s -o - | FileCheck --check-prefix=RV32XWCHC %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcia %s -o - | FileCheck --check-prefix=RV32XQCIA %s +; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqciac %s -o - | FileCheck --check-prefix=RV32XQCIAC %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcics %s -o - | FileCheck --check-prefix=RV32XQCICS %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck --check-prefix=RV32XQCICSR %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilsm %s -o - | FileCheck --check-prefix=RV32XQCILSM %s @@ -391,6 +392,7 @@ ; RV32XTHEADSYNC: .attribute 5, "rv32i2p1_xtheadsync1p0" ; RV32XWCHC: .attribute 5, "rv32i2p1_xwchc2p2" ; RV32XQCIA: .attribute 5, "rv32i2p1_xqcia0p2" +; RV32XQCIAC: .attribute 5, "rv32i2p1_zca1p0_xqciac0p2" ; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2" ; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2" ; RV32XQCILSM: .attribute 5, "rv32i2p1_xqcilsm0p2" diff --git a/llvm/test/MC/RISCV/xqciac-invalid.s b/llvm/test/MC/RISCV/xqciac-invalid.s new file mode 100644 index 00000000000000..4e0182aff9cc2c --- /dev/null +++ b/llvm/test/MC/RISCV/xqciac-invalid.s @@ -0,0 +1,43 @@ +# Xqciac - Qualcomm uC Load-Store Address Calculation Extension +# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqciac < %s 2>&1 \ +# RUN: | FileCheck -check-prefixes=CHECK,CHECK-IMM %s +# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqciac < %s 2>&1 \ +# RUN: | FileCheck -check-prefixes=CHECK,CHECK-EXT %s + +# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction +qc.c.muladdi x5, x10, 4 + +# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction +qc.c.muladdi x15 + +# CHECK-IMM: :[[@LINE+1]]:24: error: immediate must be an integer in the range [0, 31] +qc.c.muladdi x10, x15, 32 + +# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension) +qc.c.muladdi x10, x15, 20 + + +# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction +qc.muladdi x0, x10, 1048577 + +# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction +qc.muladdi x10 + +# CHECK-IMM: :[[@LINE+1]]:22: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +qc.muladdi x10, x15, 8589934592 + +# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension) +qc.muladdi x10, x15, 577 + + +# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction +qc.shladd 0, x10, 1048577 + +# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction +qc.shladd x10 + +# CHECK-IMM: :[[@LINE+1]]:26: error: immediate must be an integer in the range [4, 31] +qc.shladd x10, x15, x11, 2 + +# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension) +qc.shladd x10, x15, x11, 5 diff --git a/llvm/test/MC/RISCV/xqciac-valid.s b/llvm/test/MC/RISCV/xqciac-valid.s new file mode 100644 index 00000000000000..6e97d8cc447e14 --- /dev/null +++ b/llvm/test/MC/RISCV/xqciac-valid.s @@ -0,0 +1,49 @@ +# Xqciac - Qualcomm uC Load-Store Address Calculation Extension +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciac -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciac < %s \ +# RUN: | llvm-objdump --mattr=+experimental-xqciac -M no-aliases --no-print-imm-hex -d - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciac -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciac < %s \ +# RUN: | llvm-objdump --mattr=+experimental-xqciac --no-print-imm-hex -d - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s + +# CHECK-INST: qc.c.muladdi a0, a1, 0 +# CHECK-ENC: encoding: [0x8a,0x21] +qc.c.muladdi x10, x11, 0 + +# CHECK-INST: qc.c.muladdi a0, a1, 31 +# CHECK-ENC: encoding: [0xea,0x3d] +qc.c.muladdi x10, x11, 31 + +# CHECK-INST: qc.c.muladdi a0, a1, 16 +# CHECK-ENC: encoding: [0xaa,0x21] +qc.c.muladdi x10, x11, 16 + + +# CHECK-INST: qc.muladdi tp, t0, 1234 +# CHECK-ENC: encoding: [0x0b,0xe2,0x22,0x4d] +qc.muladdi x4, x5, 1234 + +# CHECK-INST: qc.muladdi a0, a1, -2048 +# CHECK-ENC: encoding: [0x0b,0xe5,0x05,0x80] +qc.muladdi x10, x11, -2048 + +# CHECK-INST: qc.muladdi a0, a1, 2047 +# CHECK-ENC: encoding: [0x0b,0xe5,0xf5,0x7f] +qc.muladdi x10, x11, 2047 + + +# CHECK-INST: qc.shladd tp, t0, t1, 12 +# CHECK-ENC: encoding: [0x0b,0xb2,0x62,0x58] +qc.shladd x4, x5, x6, 12 + +# CHECK-INST: qc.shladd a0, a1, a2, 4 +# CHECK-ENC: encoding: [0x0b,0xb5,0xc5,0x48] +qc.shladd x10, x11, x12, 4 + +# CHECK-INST: qc.shladd a0, a1, a2, 31 +# CHECK-ENC: encoding: [0x0b,0xb5,0xc5,0x7e] +qc.shladd x10, x11, x12, 31 diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp index ed334f00eb93a4..176cf82ac34b13 100644 --- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp +++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp @@ -654,8 +654,8 @@ TEST(ParseArchString, RejectsConflictingExtensions) { } for (StringRef Input : - {"rv64i_xqcisls0p2", "rv64i_xqcia0p2", "rv64i_xqcicsr0p2", - "rv64i_xqcilsm0p2", "rv64i_xqcics0p2"}) { + {"rv64i_xqcisls0p2", "rv64i_xqcia0p2", "rv64i_xqciac0p2", + "rv64i_xqcicsr0p2", "rv64i_xqcilsm0p2", "rv64i_xqcics0p2"}) { EXPECT_THAT( toString(RISCVISAInfo::parseArchString(Input, true).takeError()), ::testing::EndsWith(" is only supported for 'rv32'")); @@ -1113,6 +1113,7 @@ Experimental extensions ssctr 1.0 svukte 0.3 xqcia 0.2 + xqciac 0.2 xqcics 0.2 xqcicsr 0.2 xqcilsm 0.2 diff --git a/mlir/include/mlir/Dialect/SCF/IR/SCF.h b/mlir/include/mlir/Dialect/SCF/IR/SCF.h index b62c9417979478..ba648181daecb4 100644 --- a/mlir/include/mlir/Dialect/SCF/IR/SCF.h +++ b/mlir/include/mlir/Dialect/SCF/IR/SCF.h @@ -40,12 +40,6 @@ void buildTerminatedBody(OpBuilder &builder, Location loc); namespace mlir { namespace scf { -// Insert `loop.yield` at the end of the only region's only block if it -// does not have a terminator already. If a new `loop.yield` is inserted, -// the location is specified by `loc`. If the region is empty, insert a new -// block first. -void ensureLoopTerminator(Region ®ion, Builder &builder, Location loc); - /// Returns the loop parent of an induction variable. If the provided value is /// not an induction variable, then return nullptr. ForOp getForInductionVarOwner(Value val); diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp index c7ddc1b36f4d4f..28e8b81a055768 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp @@ -48,6 +48,7 @@ void LLVMDialect::registerAttributes() { addAttributes< #define GET_ATTRDEF_LIST #include "mlir/Dialect/LLVMIR/LLVMOpsAttrDefs.cpp.inc" + >(); } @@ -288,6 +289,16 @@ TargetFeaturesAttr TargetFeaturesAttr::get(MLIRContext *context, })); } +TargetFeaturesAttr +TargetFeaturesAttr::getChecked(function_ref emitError, + MLIRContext *context, + llvm::ArrayRef features) { + return Base::getChecked(emitError, context, + llvm::map_to_vector(features, [&](StringRef feature) { + return StringAttr::get(context, feature); + })); +} + TargetFeaturesAttr TargetFeaturesAttr::get(MLIRContext *context, StringRef targetFeatures) { SmallVector features; @@ -296,6 +307,16 @@ TargetFeaturesAttr TargetFeaturesAttr::get(MLIRContext *context, return get(context, features); } +TargetFeaturesAttr +TargetFeaturesAttr::getChecked(function_ref emitError, + MLIRContext *context, StringRef targetFeatures) { + SmallVector features; + targetFeatures.split(features, ',', /*MaxSplit=*/-1, + /*KeepEmpty=*/false); + ArrayRef featuresRef(features); + return getChecked(emitError, context, featuresRef); +} + LogicalResult TargetFeaturesAttr::verify(function_ref emitError, llvm::ArrayRef features) { diff --git a/mlir/test/Transforms/test-legalizer.mlir b/mlir/test/Transforms/test-legalizer.mlir index 2ca5f49637523f..297eb5acef21b7 100644 --- a/mlir/test/Transforms/test-legalizer.mlir +++ b/mlir/test/Transforms/test-legalizer.mlir @@ -450,7 +450,7 @@ func.func @fold_legalization() -> i32 { // ----- // CHECK-LABEL: func @convert_detached_signature() -// CHECK: "test.legal_op_with_region"() ({ +// CHECK: "test.legal_op"() ({ // CHECK: ^bb0(%arg0: f64): // CHECK: "test.return"() : () -> () // CHECK: }) : () -> () @@ -483,3 +483,25 @@ func.func @test_1_to_n_block_signature_conversion() { "test.return"() : () -> () } +// ----- + +// CHECK: notifyOperationInserted: test.step_1 +// CHECK: notifyOperationReplaced: test.multiple_1_to_n_replacement +// CHECK: notifyOperationErased: test.multiple_1_to_n_replacement +// CHECK: notifyOperationInserted: test.legal_op +// CHECK: notifyOperationReplaced: test.step_1 +// CHECK: notifyOperationErased: test.step_1 + +// CHECK-LABEL: func @test_multiple_1_to_n_replacement() +// CHECK: %[[legal_op:.*]]:4 = "test.legal_op"() : () -> (f16, f16, f16, f16) +// TODO: There should be a single cast (i.e., a single target materialization). +// This is currently not possible due to 1:N limitations of the conversion +// mapping. Instead, we have 3 argument materializations. +// CHECK: %[[cast1:.*]] = "test.cast"(%[[legal_op]]#2, %[[legal_op]]#3) : (f16, f16) -> f16 +// CHECK: %[[cast2:.*]] = "test.cast"(%[[legal_op]]#0, %[[legal_op]]#1) : (f16, f16) -> f16 +// CHECK: %[[cast3:.*]] = "test.cast"(%[[cast2]], %[[cast1]]) : (f16, f16) -> f16 +// CHECK: "test.valid"(%[[cast3]]) : (f16) -> () +func.func @test_multiple_1_to_n_replacement() { + %0 = "test.multiple_1_to_n_replacement"() : () -> (f16) + "test.invalid"(%0) : (f16) -> () +} diff --git a/mlir/test/lib/Dialect/Test/TestPatterns.cpp b/mlir/test/lib/Dialect/Test/TestPatterns.cpp index a470497fdbb560..826c222990be4f 100644 --- a/mlir/test/lib/Dialect/Test/TestPatterns.cpp +++ b/mlir/test/lib/Dialect/Test/TestPatterns.cpp @@ -785,7 +785,7 @@ struct TestDetachedSignatureConversion : public ConversionPattern { ConversionPatternRewriter &rewriter) const final { if (op->getNumRegions() != 1) return failure(); - OperationState state(op->getLoc(), "test.legal_op_with_region", operands, + OperationState state(op->getLoc(), "test.legal_op", operands, op->getResultTypes(), {}, BlockRange()); Region *newRegion = state.addRegion(); rewriter.inlineRegionBefore(op->getRegion(0), *newRegion, @@ -1234,6 +1234,49 @@ class TestRepetitive1ToNConsumer : public ConversionPattern { } }; +/// A pattern that tests two back-to-back 1 -> 2 op replacements. +class TestMultiple1ToNReplacement : public ConversionPattern { +public: + TestMultiple1ToNReplacement(MLIRContext *ctx, const TypeConverter &converter) + : ConversionPattern(converter, "test.multiple_1_to_n_replacement", 1, + ctx) {} + LogicalResult + matchAndRewrite(Operation *op, ArrayRef operands, + ConversionPatternRewriter &rewriter) const final { + // Helper function that replaces the given op with a new op of the given + // name and doubles each result (1 -> 2 replacement of each result). + auto replaceWithDoubleResults = [&](Operation *op, StringRef name) { + SmallVector types; + for (Type t : op->getResultTypes()) { + types.push_back(t); + types.push_back(t); + } + OperationState state(op->getLoc(), name, + /*operands=*/{}, types, op->getAttrs()); + auto *newOp = rewriter.create(state); + SmallVector repls; + for (size_t i = 0, e = op->getNumResults(); i < e; ++i) + repls.push_back(newOp->getResults().slice(2 * i, 2)); + rewriter.replaceOpWithMultiple(op, repls); + return newOp; + }; + + // Replace test.multiple_1_to_n_replacement with test.step_1. + Operation *repl1 = replaceWithDoubleResults(op, "test.step_1"); + // Now replace test.step_1 with test.legal_op. + // TODO: Ideally, it should not be necessary to reset the insertion point + // here. Based on the API calls, it looks like test.step_1 is entirely + // erased. But that's not the case: an argument materialization will + // survive. And that argument materialization will be used by the users of + // `op`. If we don't reset the insertion point here, we get dominance + // errors. This will be fixed when we have 1:N support in the conversion + // value mapping. + rewriter.setInsertionPoint(repl1); + replaceWithDoubleResults(repl1, "test.legal_op"); + return success(); + } +}; + } // namespace namespace { @@ -1319,7 +1362,8 @@ struct TestLegalizePatternDriver TestUndoPropertiesModification, TestEraseOp, TestRepetitive1ToNConsumer>(&getContext()); patterns.add(&getContext(), converter); + TestPassthroughInvalidOp, TestMultiple1ToNReplacement>( + &getContext(), converter); patterns.add(converter, &getContext()); mlir::populateAnyFunctionOpInterfaceTypeConversionPattern(patterns, converter); @@ -1330,8 +1374,7 @@ struct TestLegalizePatternDriver target.addLegalOp(); target.addLegalOp(); - target.addLegalOp( - OperationName("test.legal_op_with_region", &getContext())); + target.addLegalOp(OperationName("test.legal_op", &getContext())); target .addIllegalOp(); target.addDynamicallyLegalOp([](TestReturnOp op) {