diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp index e5c6d551e42a7a..af982fd60b17e7 100644 --- a/bolt/lib/Core/BinaryFunction.cpp +++ b/bolt/lib/Core/BinaryFunction.cpp @@ -2502,7 +2502,7 @@ void BinaryFunction::annotateCFIState() { } } - if (!StateStack.empty()) { + if (opts::Verbosity >= 1 && !StateStack.empty()) { BC.errs() << "BOLT-WARNING: non-empty CFI stack at the end of " << *this << '\n'; } diff --git a/clang/docs/InternalsManual.rst b/clang/docs/InternalsManual.rst index 3d21e37784b363..b70ec35f3da229 100644 --- a/clang/docs/InternalsManual.rst +++ b/clang/docs/InternalsManual.rst @@ -3200,7 +3200,7 @@ are similar. always involve two functions: an ``ActOnXXX`` function that will be called directly from the parser, and a ``BuildXXX`` function that performs the actual semantic analysis and will (eventually!) build the AST node. It's - fairly common for the ``ActOnCXX`` function to do very little (often just + fairly common for the ``ActOnXXX`` function to do very little (often just some minor translation from the parser's representation to ``Sema``'s representation of the same thing), but the separation is still important: C++ template instantiation, for example, should always call the ``BuildXXX`` diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 5b50ad615d2c99..62903fc3744cad 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -3987,7 +3987,7 @@ ellipsis (``...``) in the function signature. Alternatively, in C23 mode or later, it may be the integer literal ``0`` if there is no parameter preceding the ellipsis. This function initializes the given ``__builtin_va_list`` object. It is undefined behavior to call this function on an already initialized -``__builin_va_list`` object. +``__builtin_va_list`` object. * ``void __builtin_va_end(__builtin_va_list list)`` @@ -4321,7 +4321,7 @@ an appropriate value during the emission. Note that there is no builtin matching the `llvm.coro.save` intrinsic. LLVM automatically will insert one if the first argument to `llvm.coro.suspend` is -token `none`. If a user calls `__builin_suspend`, clang will insert `token none` +token `none`. If a user calls `__builtin_suspend`, clang will insert `token none` as the first argument to the intrinsic. Source location builtins diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 249249971dec7c..1df3f0e7e75ca3 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -149,6 +149,9 @@ Resolutions to C++ Defect Reports of the target type, even if the type of the bit-field is larger. (`CWG2627: Bit-fields and narrowing conversions `_) +- ``nullptr`` is now promoted to ``void*`` when passed to a C-style variadic function. + (`CWG722: Can nullptr be passed to an ellipsis? `_) + C Language Changes ------------------ @@ -176,6 +179,14 @@ Modified Compiler Flags - The compiler flag `-fbracket-depth` default value is increased from 256 to 2048. +- The ``-ffp-model`` option has been updated to enable a more limited set of + optimizations when the ``fast`` argument is used and to accept a new argument, + ``aggressive``. The behavior of ``-ffp-model=aggressive`` is equivalent + to the previous behavior of ``-ffp-model=fast``. The updated + ``-ffp-model=fast`` behavior no longer assumes finite math only and uses + the ``promoted`` algorithm for complex division when possible rather than the + less basic (limited range) algorithm. + Removed Compiler Flags ------------------------- @@ -380,6 +391,9 @@ AST Matchers - Fixed an issue with the `hasName` and `hasAnyName` matcher when matching inline namespaces with an enclosing namespace of the same name. +- Fixed an ordering issue with the `hasOperands` matcher occuring when setting a + binding in the first matcher and using it in the second matcher. + clang-format ------------ @@ -424,6 +438,36 @@ Moved checkers Sanitizers ---------- +- Added the ``-fsanitize-undefined-ignore-overflow-pattern`` flag which can be + used to disable specific overflow-dependent code patterns. The supported + patterns are: ``add-overflow-test``, ``negated-unsigned-const``, and + ``post-decr-while``. The sanitizer instrumentation can be toggled off for all + available patterns by specifying ``all``. Conversely, you can disable all + exclusions with ``none``. + + .. code-block:: c++ + + /// specified with ``-fsanitize-undefined-ignore-overflow-pattern=add-overflow-test`` + int common_overflow_check_pattern(unsigned base, unsigned offset) { + if (base + offset < base) { /* ... */ } // The pattern of `a + b < a`, and other re-orderings, won't be instrumented + } + + /// specified with ``-fsanitize-undefined-ignore-overflow-pattern=negated-unsigned-const`` + void negation_overflow() { + unsigned long foo = -1UL; // No longer causes a negation overflow warning + unsigned long bar = -2UL; // and so on... + } + + /// specified with ``-fsanitize-undefined-ignore-overflow-pattern=post-decr-while`` + void while_post_decrement() { + unsigned char count = 16; + while (count--) { /* ... */} // No longer causes unsigned-integer-overflow sanitizer to trip + } + + Many existing projects have a large amount of these code patterns present. + This new flag should allow those projects to enable integer sanitizers with + less noise. + Python Binding Changes ---------------------- - Fixed an issue that led to crashes when calling ``Type.get_exception_specification_kind``. diff --git a/clang/docs/UndefinedBehaviorSanitizer.rst b/clang/docs/UndefinedBehaviorSanitizer.rst index 531d56e313826c..1c92907372f83c 100644 --- a/clang/docs/UndefinedBehaviorSanitizer.rst +++ b/clang/docs/UndefinedBehaviorSanitizer.rst @@ -293,6 +293,48 @@ To silence reports from unsigned integer overflow, you can set ``-fsanitize-recover=unsigned-integer-overflow``, is particularly useful for providing fuzzing signal without blowing up logs. +Disabling instrumentation for common overflow patterns +------------------------------------------------------ + +There are certain overflow-dependent or overflow-prone code patterns which +produce a lot of noise for integer overflow/truncation sanitizers. Negated +unsigned constants, post-decrements in a while loop condition and simple +overflow checks are accepted and pervasive code patterns. However, the signal +received from sanitizers instrumenting these code patterns may be too noisy for +some projects. To disable instrumentation for these common patterns one should +use ``-fsanitize-undefined-ignore-overflow-pattern=``. + +Currently, this option supports three overflow-dependent code idioms: + +``negated-unsigned-const`` + +.. code-block:: c++ + + /// -fsanitize-undefined-ignore-overflow-pattern=negated-unsigned-const + unsigned long foo = -1UL; // No longer causes a negation overflow warning + unsigned long bar = -2UL; // and so on... + +``post-decr-while`` + +.. code-block:: c++ + + /// -fsanitize-undefined-ignore-overflow-pattern=post-decr-while + unsigned char count = 16; + while (count--) { /* ... */ } // No longer causes unsigned-integer-overflow sanitizer to trip + +``add-overflow-test`` + +.. code-block:: c++ + + /// -fsanitize-undefined-ignore-overflow-pattern=add-overflow-test + if (base + offset < base) { /* ... */ } // The pattern of `a + b < a`, and other re-orderings, + // won't be instrumented (same for signed types) + +You can enable all exclusions with +``-fsanitize-undefined-ignore-overflow-pattern=all`` or disable all exclusions +with ``-fsanitize-undefined-ignore-overflow-pattern=none``. Specifying ``none`` +has precedence over other values. + Issue Suppression ================= diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 64e991451bf703..d19b77ae40b0d7 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -1452,28 +1452,30 @@ describes the various floating point semantic modes and the corresponding option "fhonor-infinities", "{on, off}" "fsigned-zeros", "{on, off}" "freciprocal-math", "{on, off}" - "allow_approximate_fns", "{on, off}" + "fallow-approximate-fns", "{on, off}" "fassociative-math", "{on, off}" + "fcomplex-arithmetic", "{basic, improved, full, promoted}" This table describes the option settings that correspond to the three floating point semantic models: precise (the default), strict, and fast. .. csv-table:: Floating Point Models - :header: "Mode", "Precise", "Strict", "Fast" - :widths: 25, 15, 15, 15 - - "except_behavior", "ignore", "strict", "ignore" - "fenv_access", "off", "on", "off" - "rounding_mode", "tonearest", "dynamic", "tonearest" - "contract", "on", "off", "fast" - "support_math_errno", "on", "on", "off" - "no_honor_nans", "off", "off", "on" - "no_honor_infinities", "off", "off", "on" - "no_signed_zeros", "off", "off", "on" - "allow_reciprocal", "off", "off", "on" - "allow_approximate_fns", "off", "off", "on" - "allow_reassociation", "off", "off", "on" + :header: "Mode", "Precise", "Strict", "Fast", "Aggressive" + :widths: 25, 25, 25, 25, 25 + + "except_behavior", "ignore", "strict", "ignore", "ignore" + "fenv_access", "off", "on", "off", "off" + "rounding_mode", "tonearest", "dynamic", "tonearest", "tonearest" + "contract", "on", "off", "fast", "fast" + "support_math_errno", "on", "on", "off", "off" + "no_honor_nans", "off", "off", "off", "on" + "no_honor_infinities", "off", "off", "off", "on" + "no_signed_zeros", "off", "off", "on", "on" + "allow_reciprocal", "off", "off", "on", "on" + "allow_approximate_fns", "off", "off", "on", "on" + "allow_reassociation", "off", "off", "on", "on" + "complex_arithmetic", "full", "full", "promoted", "basic" The ``-ffp-model`` option does not modify the ``fdenormal-fp-math`` setting, but it does have an impact on whether ``crtfastmath.o`` is @@ -1492,9 +1494,9 @@ for more details. * Floating-point math obeys regular algebraic rules for real numbers (e.g. ``+`` and ``*`` are associative, ``x/y == x * (1/y)``, and ``(a + b) * c == a * c + b * c``), - * Operands to floating-point operations are not equal to ``NaN`` and - ``Inf``, and - * ``+0`` and ``-0`` are interchangeable. + * No ``NaN`` or infinite values will be operands or results of + floating-point operations, + * ``+0`` and ``-0`` may be treated as interchangeable. ``-ffast-math`` also defines the ``__FAST_MATH__`` preprocessor macro. Some math libraries recognize this macro and change their behavior. @@ -1753,7 +1755,7 @@ for more details. Specify floating point behavior. ``-ffp-model`` is an umbrella option that encompasses functionality provided by other, single purpose, floating point options. Valid values are: ``precise``, ``strict``, - and ``fast``. + ``fast``, and ``aggressive``. Details: * ``precise`` Disables optimizations that are not value-safe on @@ -1766,7 +1768,10 @@ for more details. ``STDC FENV_ACCESS``: by default ``FENV_ACCESS`` is disabled. This option setting behaves as though ``#pragma STDC FENV_ACCESS ON`` appeared at the top of the source file. - * ``fast`` Behaves identically to specifying both ``-ffast-math`` and + * ``fast`` Behaves identically to specifying ``-funsafe-math-optimizations``, + ``-fno-math-errno`` and ``-fcomplex-arithmetic=promoted`` + ``ffp-contract=fast`` + * ``aggressive`` Behaves identically to specifying both ``-ffast-math`` and ``ffp-contract=fast`` Note: If your command line specifies multiple instances diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 5b813bfc2faf90..7bacf028192c65 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -3888,6 +3888,7 @@ class BinaryOperator : public Expr { /// Construct an empty binary operator. explicit BinaryOperator(EmptyShell Empty) : Expr(BinaryOperatorClass, Empty) { BinaryOperatorBits.Opc = BO_Comma; + BinaryOperatorBits.ExcludedOverflowPattern = false; } public: @@ -4043,6 +4044,15 @@ class BinaryOperator : public Expr { void setHasStoredFPFeatures(bool B) { BinaryOperatorBits.HasFPFeatures = B; } bool hasStoredFPFeatures() const { return BinaryOperatorBits.HasFPFeatures; } + /// Set and get the bit that informs arithmetic overflow sanitizers whether + /// or not they should exclude certain BinaryOperators from instrumentation + void setExcludedOverflowPattern(bool B) { + BinaryOperatorBits.ExcludedOverflowPattern = B; + } + bool hasExcludedOverflowPattern() const { + return BinaryOperatorBits.ExcludedOverflowPattern; + } + /// Get FPFeatures from trailing storage FPOptionsOverride getStoredFPFeatures() const { assert(hasStoredFPFeatures()); diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index c1b9e0dbafb6c3..3a1d6852d2a708 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -191,7 +191,7 @@ class OMPOneStmtClause : public Base { }; /// Class that handles pre-initialization statement for some clauses, like -/// 'shedule', 'firstprivate' etc. +/// 'schedule', 'firstprivate' etc. class OMPClauseWithPreInit { friend class OMPClauseReader; diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index bbd7634bcc3bfb..f1a2aac0a8b2f8 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -650,6 +650,11 @@ class alignas(void *) Stmt { LLVM_PREFERRED_TYPE(bool) unsigned HasFPFeatures : 1; + /// Whether or not this BinaryOperator should be excluded from integer + /// overflow sanitization. + LLVM_PREFERRED_TYPE(bool) + unsigned ExcludedOverflowPattern : 1; + SourceLocation OpLoc; }; diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index ca44c3ee085654..f1c72efc238784 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -6027,7 +6027,7 @@ AST_POLYMORPHIC_MATCHER_P2( internal::Matcher, Matcher1, internal::Matcher, Matcher2) { return internal::VariadicDynCastAllOfMatcher()( anyOf(allOf(hasLHS(Matcher1), hasRHS(Matcher2)), - allOf(hasLHS(Matcher2), hasRHS(Matcher1)))) + allOf(hasRHS(Matcher1), hasLHS(Matcher2)))) .matches(Node, Finder, Builder); } diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 036366cdadf4aa..ac33672a32b336 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4745,6 +4745,12 @@ def HLSLRSqrt : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } +def HLSLSaturate : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_saturate"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index 09e892d6d4defe..ecea476abe3232 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -176,6 +176,7 @@ CODEGENOPT(MergeAllConstants , 1, 1) ///< Merge identical constants. CODEGENOPT(MergeFunctions , 1, 0) ///< Set when -fmerge-functions is enabled. CODEGENOPT(NoCommon , 1, 0) ///< Set when -fno-common or C++ is enabled. CODEGENOPT(NoExecStack , 1, 0) ///< Set when -Wa,--noexecstack is enabled. +CODEGENOPT(MipsMsa , 1, 0) ///< Set when -Wa,-mmsa is enabled. CODEGENOPT(FatalWarnings , 1, 0) ///< Set when -Wa,--fatal-warnings is ///< enabled. CODEGENOPT(NoWarn , 1, 0) ///< Set when -Wa,--no-warn is enabled. diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 91f1c2f2e6239e..eb4cb4b5a7e93f 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -367,6 +367,21 @@ class LangOptionsBase { PerThread, }; + /// Exclude certain code patterns from being instrumented by arithmetic + /// overflow sanitizers + enum OverflowPatternExclusionKind { + /// Don't exclude any overflow patterns from sanitizers + None = 1 << 0, + /// Exclude all overflow patterns (below) + All = 1 << 1, + /// if (a + b < a) + AddOverflowTest = 1 << 2, + /// -1UL + NegUnsignedConst = 1 << 3, + /// while (count--) + PostDecrInWhile = 1 << 4, + }; + enum class DefaultVisiblityExportMapping { None, /// map only explicit default visibilities to exported @@ -555,6 +570,11 @@ class LangOptions : public LangOptionsBase { /// The default stream kind used for HIP kernel launching. GPUDefaultStreamKind GPUDefaultStream; + /// Which overflow patterns should be excluded from sanitizer instrumentation + unsigned OverflowPatternExclusionMask = 0; + + std::vector OverflowPatternExclusionValues; + /// The seed used by the randomize structure layout feature. std::string RandstructSeed; @@ -630,6 +650,14 @@ class LangOptions : public LangOptionsBase { return MSCompatibilityVersion >= MajorVersion * 100000U; } + bool isOverflowPatternExcluded(OverflowPatternExclusionKind Kind) const { + if (OverflowPatternExclusionMask & OverflowPatternExclusionKind::None) + return false; + if (OverflowPatternExclusionMask & OverflowPatternExclusionKind::All) + return true; + return OverflowPatternExclusionMask & Kind; + } + /// Reset all of the options that are not considered when building a /// module. void resetNonModularOptions(); diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index c66e035a259b3f..c204062b4f7353 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2565,6 +2565,11 @@ defm sanitize_stats : BoolOption<"f", "sanitize-stats", "Disable">, BothFlags<[], [ClangOption], " sanitizer statistics gathering.">>, Group; +def fsanitize_undefined_ignore_overflow_pattern_EQ : CommaJoined<["-"], "fsanitize-undefined-ignore-overflow-pattern=">, + HelpText<"Specify the overflow patterns to exclude from artihmetic sanitizer instrumentation">, + Visibility<[ClangOption, CC1Option]>, + Values<"none,all,add-overflow-test,negated-unsigned-const,post-decr-while">, + MarshallingInfoStringVector>; def fsanitize_thread_memory_access : Flag<["-"], "fsanitize-thread-memory-access">, Group, HelpText<"Enable memory access instrumentation in ThreadSanitizer (default)">; @@ -5383,7 +5388,9 @@ def mmadd4 : Flag<["-"], "mmadd4">, Group, def mno_madd4 : Flag<["-"], "mno-madd4">, Group, HelpText<"Disable the generation of 4-operand madd.s, madd.d and related instructions.">; def mmsa : Flag<["-"], "mmsa">, Group, - HelpText<"Enable MSA ASE (MIPS only)">; + Visibility<[ClangOption, CC1Option, CC1AsOption]>, + HelpText<"Enable MSA ASE (MIPS only)">, + MarshallingInfoFlag>; def mno_msa : Flag<["-"], "mno-msa">, Group, HelpText<"Disable MSA ASE (MIPS only)">; def mmt : Flag<["-"], "mmt">, Group, diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h index 47ef175302679f..e64ec463ca8907 100644 --- a/clang/include/clang/Driver/SanitizerArgs.h +++ b/clang/include/clang/Driver/SanitizerArgs.h @@ -33,6 +33,7 @@ class SanitizerArgs { std::vector BinaryMetadataIgnorelistFiles; int CoverageFeatures = 0; int BinaryMetadataFeatures = 0; + int OverflowPatternExclusions = 0; int MsanTrackOrigins = 0; bool MsanUseAfterDtor = true; bool MsanParamRetval = true; diff --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h index bf291074fd0614..188e35b72117b5 100644 --- a/clang/include/clang/ExtractAPI/API.h +++ b/clang/include/clang/ExtractAPI/API.h @@ -19,21 +19,13 @@ #define LLVM_CLANG_EXTRACTAPI_API_H #include "clang/AST/Availability.h" -#include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" -#include "clang/AST/DeclObjC.h" #include "clang/AST/RawCommentList.h" #include "clang/Basic/SourceLocation.h" -#include "clang/Basic/Specifiers.h" #include "clang/ExtractAPI/DeclarationFragments.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/MapVector.h" -#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Casting.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Triple.h" #include #include @@ -328,6 +320,8 @@ class RecordContext { /// chain. void stealRecordChain(RecordContext &Other); + void removeFromRecordChain(APIRecord *Record); + APIRecord::RecordKind getKind() const { return Kind; } struct record_iterator { @@ -1426,10 +1420,15 @@ class APISet { typename std::enable_if_t, RecordTy> * createRecord(StringRef USR, StringRef Name, CtorArgsContTy &&...CtorArgs); - ArrayRef getTopLevelRecords() const { - return TopLevelRecords; + auto getTopLevelRecords() const { + return llvm::iterator_range( + TopLevelRecords); } + void removeRecord(StringRef USR); + + void removeRecord(APIRecord *Record); + APISet(const llvm::Triple &Target, Language Lang, const std::string &ProductName) : Target(Target), Lang(Lang), ProductName(ProductName) {} @@ -1456,7 +1455,7 @@ class APISet { // lives in the BumpPtrAllocator. using APIRecordStoredPtr = std::unique_ptr; llvm::DenseMap USRBasedLookupTable; - std::vector TopLevelRecords; + llvm::SmallPtrSet TopLevelRecords; public: const std::string ProductName; @@ -1482,7 +1481,7 @@ APISet::createRecord(StringRef USR, StringRef Name, dyn_cast_if_present(Record->Parent.Record)) ParentContext->addToRecordChain(Record); else - TopLevelRecords.push_back(Record); + TopLevelRecords.insert(Record); } else { Record = dyn_cast(Result.first->second.get()); } diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h index 1b27027621666a..67659f5a25037c 100644 --- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h +++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h @@ -40,6 +40,8 @@ namespace impl { template class ExtractAPIVisitorBase : public RecursiveASTVisitor { + using Base = RecursiveASTVisitor; + protected: ExtractAPIVisitorBase(ASTContext &Context, APISet &API) : Context(Context), API(API) {} @@ -81,8 +83,10 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor { bool VisitNamespaceDecl(const NamespaceDecl *Decl); + bool TraverseRecordDecl(RecordDecl *Decl); bool VisitRecordDecl(const RecordDecl *Decl); + bool TraverseCXXRecordDecl(CXXRecordDecl *Decl); bool VisitCXXRecordDecl(const CXXRecordDecl *Decl); bool VisitCXXMethodDecl(const CXXMethodDecl *Decl); @@ -240,7 +244,7 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor { bool isEmbeddedInVarDeclarator(const TagDecl &D) { return D.getName().empty() && getTypedefName(&D).empty() && - D.isEmbeddedInDeclarator(); + D.isEmbeddedInDeclarator() && !D.isFreeStanding(); } void maybeMergeWithAnonymousTag(const DeclaratorDecl &D, @@ -252,8 +256,10 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor { clang::index::generateUSRForDecl(Tag, TagUSR); if (auto *Record = llvm::dyn_cast_if_present( API.findRecordForUSR(TagUSR))) { - if (Record->IsEmbeddedInVarDeclarator) + if (Record->IsEmbeddedInVarDeclarator) { NewRecordContext->stealRecordChain(*Record); + API.removeRecord(Record); + } } } }; @@ -548,6 +554,19 @@ bool ExtractAPIVisitorBase::VisitNamespaceDecl( return true; } +template +bool ExtractAPIVisitorBase::TraverseRecordDecl(RecordDecl *Decl) { + bool Ret = Base::TraverseRecordDecl(Decl); + + if (!isEmbeddedInVarDeclarator(*Decl) && Decl->isAnonymousStructOrUnion()) { + SmallString<128> USR; + index::generateUSRForDecl(Decl, USR); + API.removeRecord(USR); + } + + return Ret; +} + template bool ExtractAPIVisitorBase::VisitRecordDecl(const RecordDecl *Decl) { if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) @@ -588,6 +607,20 @@ bool ExtractAPIVisitorBase::VisitRecordDecl(const RecordDecl *Decl) { return true; } +template +bool ExtractAPIVisitorBase::TraverseCXXRecordDecl( + CXXRecordDecl *Decl) { + bool Ret = Base::TraverseCXXRecordDecl(Decl); + + if (!isEmbeddedInVarDeclarator(*Decl) && Decl->isAnonymousStructOrUnion()) { + SmallString<128> USR; + index::generateUSRForDecl(Decl, USR); + API.removeRecord(USR); + } + + return Ret; +} + template bool ExtractAPIVisitorBase::VisitCXXRecordDecl( const CXXRecordDecl *Decl) { diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 0af473f9bd0802..590087e04b7474 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -2325,6 +2325,9 @@ bool Compiler::VisitCXXBindTemporaryExpr( template bool Compiler::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { const Expr *Init = E->getInitializer(); + if (DiscardResult) + return this->discard(Init); + if (Initializing) { // We already have a value, just initialize that. return this->visitInitializer(Init) && this->emitFinishInit(E); @@ -2378,9 +2381,6 @@ bool Compiler::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { if (!this->visitInitializer(Init) || !this->emitFinishInit(E)) return false; } - - if (DiscardResult) - return this->emitPopPtr(E); return true; } diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 9d5b8167d0ee62..25ab6f3b2addfb 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -4759,6 +4759,53 @@ ParenListExpr *ParenListExpr::CreateEmpty(const ASTContext &Ctx, return new (Mem) ParenListExpr(EmptyShell(), NumExprs); } +/// Certain overflow-dependent code patterns can have their integer overflow +/// sanitization disabled. Check for the common pattern `if (a + b < a)` and +/// return the resulting BinaryOperator responsible for the addition so we can +/// elide overflow checks during codegen. +static std::optional +getOverflowPatternBinOp(const BinaryOperator *E) { + Expr *Addition, *ComparedTo; + if (E->getOpcode() == BO_LT) { + Addition = E->getLHS(); + ComparedTo = E->getRHS(); + } else if (E->getOpcode() == BO_GT) { + Addition = E->getRHS(); + ComparedTo = E->getLHS(); + } else { + return {}; + } + + const Expr *AddLHS = nullptr, *AddRHS = nullptr; + BinaryOperator *BO = dyn_cast(Addition); + + if (BO && BO->getOpcode() == clang::BO_Add) { + // now store addends for lookup on other side of '>' + AddLHS = BO->getLHS(); + AddRHS = BO->getRHS(); + } + + if (!AddLHS || !AddRHS) + return {}; + + const Decl *LHSDecl, *RHSDecl, *OtherDecl; + + LHSDecl = AddLHS->IgnoreParenImpCasts()->getReferencedDeclOfCallee(); + RHSDecl = AddRHS->IgnoreParenImpCasts()->getReferencedDeclOfCallee(); + OtherDecl = ComparedTo->IgnoreParenImpCasts()->getReferencedDeclOfCallee(); + + if (!OtherDecl) + return {}; + + if (!LHSDecl && !RHSDecl) + return {}; + + if ((LHSDecl && LHSDecl == OtherDecl && LHSDecl != RHSDecl) || + (RHSDecl && RHSDecl == OtherDecl && RHSDecl != LHSDecl)) + return BO; + return {}; +} + BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, @@ -4768,8 +4815,15 @@ BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, assert(!isCompoundAssignmentOp() && "Use CompoundAssignOperator for compound assignments"); BinaryOperatorBits.OpLoc = opLoc; + BinaryOperatorBits.ExcludedOverflowPattern = false; SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; + if (Ctx.getLangOpts().isOverflowPatternExcluded( + LangOptions::OverflowPatternExclusionKind::AddOverflowTest)) { + std::optional Result = getOverflowPatternBinOp(this); + if (Result.has_value()) + Result.value()->BinaryOperatorBits.ExcludedOverflowPattern = true; + } BinaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage(); if (hasStoredFPFeatures()) setStoredFPFeatures(FPFeatures); @@ -4782,6 +4836,7 @@ BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, FPOptionsOverride FPFeatures, bool dead2) : Expr(CompoundAssignOperatorClass, ResTy, VK, OK) { BinaryOperatorBits.Opc = opc; + BinaryOperatorBits.ExcludedOverflowPattern = false; assert(isCompoundAssignmentOp() && "Use CompoundAssignOperator for compound assignments"); BinaryOperatorBits.OpLoc = opLoc; diff --git a/clang/lib/AST/FormatString.cpp b/clang/lib/AST/FormatString.cpp index da8164bad518ec..e892c1592df986 100644 --- a/clang/lib/AST/FormatString.cpp +++ b/clang/lib/AST/FormatString.cpp @@ -520,33 +520,18 @@ ArgType::matchesType(ASTContext &C, QualType argTy) const { return NoMatch; } - case CStrTy: { - const PointerType *PT = argTy->getAs(); - if (!PT) - return NoMatch; - QualType pointeeTy = PT->getPointeeType(); - if (const BuiltinType *BT = pointeeTy->getAs()) - switch (BT->getKind()) { - case BuiltinType::Char_U: - case BuiltinType::UChar: - case BuiltinType::Char_S: - case BuiltinType::SChar: - return Match; - default: - break; - } - + case CStrTy: + if (const auto *PT = argTy->getAs(); + PT && PT->getPointeeType()->isCharType()) + return Match; return NoMatch; - } - case WCStrTy: { - const PointerType *PT = argTy->getAs(); - if (!PT) - return NoMatch; - QualType pointeeTy = - C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType(); - return pointeeTy == C.getWideCharType() ? Match : NoMatch; - } + case WCStrTy: + if (const auto *PT = argTy->getAs(); + PT && + C.hasSameUnqualifiedType(PT->getPointeeType(), C.getWideCharType())) + return Match; + return NoMatch; case WIntTy: { QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType(); @@ -569,15 +554,25 @@ ArgType::matchesType(ASTContext &C, QualType argTy) const { } case CPointerTy: - if (argTy->isVoidPointerType()) { - return Match; - } if (argTy->isPointerType() || argTy->isObjCObjectPointerType() || - argTy->isBlockPointerType() || argTy->isNullPtrType()) { + if (const auto *PT = argTy->getAs()) { + QualType PointeeTy = PT->getPointeeType(); + if (PointeeTy->isVoidType() || (!Ptr && PointeeTy->isCharType())) + return Match; return NoMatchPedantic; - } else { - return NoMatch; } + // nullptr_t* is not a double pointer, so reject when something like + // void** is expected. + // In C++, nullptr is promoted to void*. In C23, va_arg(ap, void*) is not + // undefined when the next argument is of type nullptr_t. + if (!Ptr && argTy->isNullPtrType()) + return C.getLangOpts().CPlusPlus ? MatchPromotion : Match; + + if (argTy->isObjCObjectPointerType() || argTy->isBlockPointerType()) + return NoMatchPedantic; + + return NoMatch; + case ObjCPointerTy: { if (argTy->getAs() || argTy->getAs()) diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index 3fb3587eb59140..a9cbdb7b10dff8 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -186,14 +186,14 @@ bool X86TargetInfo::initFeatureMap( llvm::append_range(UpdatedFeaturesVec, UpdatedAVX10FeaturesVec); // HasEVEX512 is a three-states flag. We need to turn it into [+-]evex512 // according to other features. - if (HasAVX512F) { + if (!HasAVX10_512 && HasAVX512F) { UpdatedFeaturesVec.push_back(HasEVEX512 == FE_FALSE ? "-evex512" : "+evex512"); - if (HasAVX10 && !HasAVX10_512 && HasEVEX512 != FE_FALSE) + if (HasAVX10 && HasEVEX512 != FE_FALSE) Diags.Report(diag::warn_invalid_feature_combination) << LastAVX512 + " " + LastAVX10 + "; will be promoted to avx10.1-512"; } else if (HasAVX10) { - if (HasEVEX512 != FE_NOSET) + if (!HasAVX512F && HasEVEX512 != FE_NOSET) Diags.Report(diag::warn_invalid_feature_combination) << LastAVX10 + (HasEVEX512 == FE_TRUE ? " +evex512" : " -evex512"); UpdatedFeaturesVec.push_back(HasAVX10_512 ? "+evex512" : "-evex512"); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index f424ddaa175400..3e787cad6e82fa 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18667,6 +18667,15 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { /*ReturnType=*/Op0->getType(), CGM.getHLSLRuntime().getRsqrtIntrinsic(), ArrayRef{Op0}, nullptr, "hlsl.rsqrt"); } + case Builtin::BI__builtin_hlsl_elementwise_saturate: { + Value *Op0 = EmitScalarExpr(E->getArg(0)); + assert(E->getArg(0)->getType()->hasFloatingRepresentation() && + "saturate operand must have a float representation"); + return Builder.CreateIntrinsic( + /*ReturnType=*/Op0->getType(), + CGM.getHLSLRuntime().getSaturateIntrinsic(), ArrayRef{Op0}, + nullptr, "hlsl.saturate"); + } case Builtin::BI__builtin_hlsl_wave_get_lane_index: { return EmitRuntimeCall(CGM.CreateRuntimeFunction( llvm::FunctionType::get(IntTy, {}, false), "__hlsl_wave_get_lane_index", @@ -18920,69 +18929,6 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, Function *F = CGM.getIntrinsic(Intrin, { Src0->getType() }); return Builder.CreateCall(F, { Src0, Builder.getFalse() }); } - case AMDGPU::BI__builtin_amdgcn_global_atomic_fadd_v2f16: - case AMDGPU::BI__builtin_amdgcn_global_atomic_fmin_f64: - case AMDGPU::BI__builtin_amdgcn_global_atomic_fmax_f64: - case AMDGPU::BI__builtin_amdgcn_flat_atomic_fadd_f64: - case AMDGPU::BI__builtin_amdgcn_flat_atomic_fmin_f64: - case AMDGPU::BI__builtin_amdgcn_flat_atomic_fmax_f64: - case AMDGPU::BI__builtin_amdgcn_flat_atomic_fadd_f32: - case AMDGPU::BI__builtin_amdgcn_flat_atomic_fadd_v2f16: { - Intrinsic::ID IID; - llvm::Type *ArgTy = llvm::Type::getDoubleTy(getLLVMContext()); - switch (BuiltinID) { - case AMDGPU::BI__builtin_amdgcn_global_atomic_fadd_v2f16: - ArgTy = llvm::FixedVectorType::get( - llvm::Type::getHalfTy(getLLVMContext()), 2); - IID = Intrinsic::amdgcn_global_atomic_fadd; - break; - case AMDGPU::BI__builtin_amdgcn_global_atomic_fmin_f64: - IID = Intrinsic::amdgcn_global_atomic_fmin; - break; - case AMDGPU::BI__builtin_amdgcn_global_atomic_fmax_f64: - IID = Intrinsic::amdgcn_global_atomic_fmax; - break; - case AMDGPU::BI__builtin_amdgcn_flat_atomic_fadd_f64: - IID = Intrinsic::amdgcn_flat_atomic_fadd; - break; - case AMDGPU::BI__builtin_amdgcn_flat_atomic_fmin_f64: - IID = Intrinsic::amdgcn_flat_atomic_fmin; - break; - case AMDGPU::BI__builtin_amdgcn_flat_atomic_fmax_f64: - IID = Intrinsic::amdgcn_flat_atomic_fmax; - break; - case AMDGPU::BI__builtin_amdgcn_flat_atomic_fadd_f32: - ArgTy = llvm::Type::getFloatTy(getLLVMContext()); - IID = Intrinsic::amdgcn_flat_atomic_fadd; - break; - case AMDGPU::BI__builtin_amdgcn_flat_atomic_fadd_v2f16: - ArgTy = llvm::FixedVectorType::get( - llvm::Type::getHalfTy(getLLVMContext()), 2); - IID = Intrinsic::amdgcn_flat_atomic_fadd; - break; - } - llvm::Value *Addr = EmitScalarExpr(E->getArg(0)); - llvm::Value *Val = EmitScalarExpr(E->getArg(1)); - llvm::Function *F = - CGM.getIntrinsic(IID, {ArgTy, Addr->getType(), Val->getType()}); - return Builder.CreateCall(F, {Addr, Val}); - } - case AMDGPU::BI__builtin_amdgcn_global_atomic_fadd_v2bf16: - case AMDGPU::BI__builtin_amdgcn_flat_atomic_fadd_v2bf16: { - Intrinsic::ID IID; - switch (BuiltinID) { - case AMDGPU::BI__builtin_amdgcn_global_atomic_fadd_v2bf16: - IID = Intrinsic::amdgcn_global_atomic_fadd_v2bf16; - break; - case AMDGPU::BI__builtin_amdgcn_flat_atomic_fadd_v2bf16: - IID = Intrinsic::amdgcn_flat_atomic_fadd_v2bf16; - break; - } - llvm::Value *Addr = EmitScalarExpr(E->getArg(0)); - llvm::Value *Val = EmitScalarExpr(E->getArg(1)); - llvm::Function *F = CGM.getIntrinsic(IID, {Addr->getType()}); - return Builder.CreateCall(F, {Addr, Val}); - } case AMDGPU::BI__builtin_amdgcn_global_load_tr_b64_i32: case AMDGPU::BI__builtin_amdgcn_global_load_tr_b64_v2i32: case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v4i16: @@ -19360,7 +19306,17 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, case AMDGPU::BI__builtin_amdgcn_ds_fminf: case AMDGPU::BI__builtin_amdgcn_ds_fmaxf: case AMDGPU::BI__builtin_amdgcn_global_atomic_fadd_f32: - case AMDGPU::BI__builtin_amdgcn_global_atomic_fadd_f64: { + case AMDGPU::BI__builtin_amdgcn_global_atomic_fadd_f64: + case AMDGPU::BI__builtin_amdgcn_global_atomic_fadd_v2f16: + case AMDGPU::BI__builtin_amdgcn_flat_atomic_fadd_v2f16: + case AMDGPU::BI__builtin_amdgcn_flat_atomic_fadd_f32: + case AMDGPU::BI__builtin_amdgcn_flat_atomic_fadd_f64: + case AMDGPU::BI__builtin_amdgcn_global_atomic_fadd_v2bf16: + case AMDGPU::BI__builtin_amdgcn_flat_atomic_fadd_v2bf16: + case AMDGPU::BI__builtin_amdgcn_global_atomic_fmin_f64: + case AMDGPU::BI__builtin_amdgcn_global_atomic_fmax_f64: + case AMDGPU::BI__builtin_amdgcn_flat_atomic_fmin_f64: + case AMDGPU::BI__builtin_amdgcn_flat_atomic_fmax_f64: { llvm::AtomicRMWInst::BinOp BinOp; switch (BuiltinID) { case AMDGPU::BI__builtin_amdgcn_atomic_inc32: @@ -19378,11 +19334,21 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, case AMDGPU::BI__builtin_amdgcn_ds_atomic_fadd_v2bf16: case AMDGPU::BI__builtin_amdgcn_global_atomic_fadd_f32: case AMDGPU::BI__builtin_amdgcn_global_atomic_fadd_f64: + case AMDGPU::BI__builtin_amdgcn_global_atomic_fadd_v2f16: + case AMDGPU::BI__builtin_amdgcn_flat_atomic_fadd_v2f16: + case AMDGPU::BI__builtin_amdgcn_flat_atomic_fadd_f32: + case AMDGPU::BI__builtin_amdgcn_flat_atomic_fadd_f64: + case AMDGPU::BI__builtin_amdgcn_global_atomic_fadd_v2bf16: + case AMDGPU::BI__builtin_amdgcn_flat_atomic_fadd_v2bf16: BinOp = llvm::AtomicRMWInst::FAdd; break; case AMDGPU::BI__builtin_amdgcn_ds_fminf: + case AMDGPU::BI__builtin_amdgcn_global_atomic_fmin_f64: + case AMDGPU::BI__builtin_amdgcn_flat_atomic_fmin_f64: BinOp = llvm::AtomicRMWInst::FMin; break; + case AMDGPU::BI__builtin_amdgcn_global_atomic_fmax_f64: + case AMDGPU::BI__builtin_amdgcn_flat_atomic_fmax_f64: case AMDGPU::BI__builtin_amdgcn_ds_fmaxf: BinOp = llvm::AtomicRMWInst::FMax; break; @@ -19422,7 +19388,9 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, AO = AtomicOrdering::Monotonic; // The v2bf16 builtin uses i16 instead of a natural bfloat type. - if (BuiltinID == AMDGPU::BI__builtin_amdgcn_ds_atomic_fadd_v2bf16) { + if (BuiltinID == AMDGPU::BI__builtin_amdgcn_ds_atomic_fadd_v2bf16 || + BuiltinID == AMDGPU::BI__builtin_amdgcn_global_atomic_fadd_v2bf16 || + BuiltinID == AMDGPU::BI__builtin_amdgcn_flat_atomic_fadd_v2bf16) { llvm::Type *V2BF16Ty = FixedVectorType::get( llvm::Type::getBFloatTy(Builder.getContext()), 2); Val = Builder.CreateBitCast(Val, V2BF16Ty); diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 84392745ea6144..3bda254c86adf6 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -24,6 +24,7 @@ #include "clang/AST/Attr.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" +#include "clang/AST/ParentMapContext.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/StmtVisitor.h" #include "clang/Basic/CodeGenOptions.h" @@ -195,13 +196,24 @@ static bool CanElideOverflowCheck(const ASTContext &Ctx, const BinOpInfo &Op) { if (!Op.mayHaveIntegerOverflow()) return true; + const UnaryOperator *UO = dyn_cast(Op.E); + + if (UO && UO->getOpcode() == UO_Minus && + Ctx.getLangOpts().isOverflowPatternExcluded( + LangOptions::OverflowPatternExclusionKind::NegUnsignedConst) && + UO->isIntegerConstantExpr(Ctx)) + return true; + // If a unary op has a widened operand, the op cannot overflow. - if (const auto *UO = dyn_cast(Op.E)) + if (UO) return !UO->canOverflow(); // We usually don't need overflow checks for binops with widened operands. // Multiplication with promoted unsigned operands is a special case. const auto *BO = cast(Op.E); + if (BO->hasExcludedOverflowPattern()) + return true; + auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS()); if (!OptionalLHSTy) return false; @@ -2766,6 +2778,26 @@ llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior( llvm_unreachable("Unknown SignedOverflowBehaviorTy"); } +/// For the purposes of overflow pattern exclusion, does this match the +/// "while(i--)" pattern? +static bool matchesPostDecrInWhile(const UnaryOperator *UO, bool isInc, + bool isPre, ASTContext &Ctx) { + if (isInc || isPre) + return false; + + // -fsanitize-undefined-ignore-overflow-pattern=post-decr-while + if (!Ctx.getLangOpts().isOverflowPatternExcluded( + LangOptions::OverflowPatternExclusionKind::PostDecrInWhile)) + return false; + + // all Parents (usually just one) must be a WhileStmt + for (const auto &Parent : Ctx.getParentMapContext().getParents(*UO)) + if (!Parent.get()) + return false; + + return true; +} + namespace { /// Handles check and update for lastprivate conditional variables. class OMPLastprivateConditionalUpdateRAII { @@ -2877,6 +2909,10 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, } else if (type->isIntegerType()) { QualType promotedType; bool canPerformLossyDemotionCheck = false; + + bool excludeOverflowPattern = + matchesPostDecrInWhile(E, isInc, isPre, CGF.getContext()); + if (CGF.getContext().isPromotableIntegerType(type)) { promotedType = CGF.getContext().getPromotedIntegerType(type); assert(promotedType != type && "Shouldn't promote to the same type."); @@ -2936,7 +2972,8 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, } else if (E->canOverflow() && type->isSignedIntegerOrEnumerationType()) { value = EmitIncDecConsiderOverflowBehavior(E, value, isInc); } else if (E->canOverflow() && type->isUnsignedIntegerType() && - CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) { + CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) && + !excludeOverflowPattern) { value = EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec( E, value, isInc, E->getFPFeaturesInEffect(CGF.getLangOpts()))); } else { diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index cd604bea2e763d..b1455b5779acf9 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -79,6 +79,7 @@ class CGHLSLRuntime { GENERATE_HLSL_INTRINSIC_FUNCTION(Lerp, lerp) GENERATE_HLSL_INTRINSIC_FUNCTION(Normalize, normalize) GENERATE_HLSL_INTRINSIC_FUNCTION(Rsqrt, rsqrt) + GENERATE_HLSL_INTRINSIC_FUNCTION(Saturate, saturate) GENERATE_HLSL_INTRINSIC_FUNCTION(ThreadId, thread_id) //===----------------------------------------------------------------------===// diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp index 8965a14d88a6fb..9e095a37552196 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp @@ -2048,14 +2048,12 @@ Address CGOpenMPRuntimeGPU::getAddressOfLocalVariable(CodeGenFunction &CGF, const auto *A = VD->getAttr(); auto AS = LangAS::Default; switch (A->getAllocatorType()) { - // Use the default allocator here as by default local vars are - // threadlocal. case OMPAllocateDeclAttr::OMPNullMemAlloc: case OMPAllocateDeclAttr::OMPDefaultMemAlloc: - case OMPAllocateDeclAttr::OMPThreadMemAlloc: case OMPAllocateDeclAttr::OMPHighBWMemAlloc: case OMPAllocateDeclAttr::OMPLowLatMemAlloc: - // Follow the user decision - use default allocation. + break; + case OMPAllocateDeclAttr::OMPThreadMemAlloc: return Address::invalid(); case OMPAllocateDeclAttr::OMPUserDefinedMemAlloc: // TODO: implement aupport for user-defined allocators. @@ -2208,11 +2206,11 @@ bool CGOpenMPRuntimeGPU::hasAllocateAttributeForGlobalVar(const VarDecl *VD, case OMPAllocateDeclAttr::OMPNullMemAlloc: case OMPAllocateDeclAttr::OMPDefaultMemAlloc: // Not supported, fallback to the default mem space. - case OMPAllocateDeclAttr::OMPThreadMemAlloc: case OMPAllocateDeclAttr::OMPLargeCapMemAlloc: case OMPAllocateDeclAttr::OMPCGroupMemAlloc: case OMPAllocateDeclAttr::OMPHighBWMemAlloc: case OMPAllocateDeclAttr::OMPLowLatMemAlloc: + case OMPAllocateDeclAttr::OMPThreadMemAlloc: AS = LangAS::Default; return true; case OMPAllocateDeclAttr::OMPConstMemAlloc: diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 0b61ef0f89989c..0d3b896af8aa39 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1134,6 +1134,11 @@ void CodeGenModule::Release() { CodeGenOpts.SanitizeCfiCanonicalJumpTables); } + if (CodeGenOpts.SanitizeCfiICallNormalizeIntegers) { + getModule().addModuleFlag(llvm::Module::Override, "cfi-normalize-integers", + 1); + } + if (LangOpts.Sanitize.has(SanitizerKind::KCFI)) { getModule().addModuleFlag(llvm::Module::Override, "kcfi", 1); // KCFI assumes patchable-function-prefix is the same for all indirectly diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 1fd870b72286e5..9d9ad79d51d7f8 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -119,6 +119,12 @@ static SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A, static int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A, bool DiagnoseErrors); +/// Parse -fsanitize-undefined-ignore-overflow-pattern= flag values, diagnosing +/// any invalid values. Returns a mask of excluded overflow patterns. +static int parseOverflowPatternExclusionValues(const Driver &D, + const llvm::opt::Arg *A, + bool DiagnoseErrors); + /// Parse -f(no-)?sanitize-metadata= flag values, diagnosing any invalid /// components. Returns OR of members of \c BinaryMetadataFeature enumeration. static int parseBinaryMetadataFeatures(const Driver &D, const llvm::opt::Arg *A, @@ -788,6 +794,13 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, << "fsanitize-trap=cfi"; } + for (const auto *Arg : Args.filtered( + options::OPT_fsanitize_undefined_ignore_overflow_pattern_EQ)) { + Arg->claim(); + OverflowPatternExclusions |= + parseOverflowPatternExclusionValues(D, Arg, DiagnoseErrors); + } + // Parse -f(no-)?sanitize-coverage flags if coverage is supported by the // enabled sanitizers. for (const auto *Arg : Args) { @@ -1241,6 +1254,10 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, addSpecialCaseListOpt(Args, CmdArgs, "-fsanitize-system-ignorelist=", SystemIgnorelistFiles); + if (OverflowPatternExclusions) + Args.AddAllArgs( + CmdArgs, options::OPT_fsanitize_undefined_ignore_overflow_pattern_EQ); + if (MsanTrackOrigins) CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins=" + Twine(MsanTrackOrigins))); @@ -1426,6 +1443,28 @@ SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A, return Kinds; } +static int parseOverflowPatternExclusionValues(const Driver &D, + const llvm::opt::Arg *A, + bool DiagnoseErrors) { + int Exclusions = 0; + for (int i = 0, n = A->getNumValues(); i != n; ++i) { + const char *Value = A->getValue(i); + int E = + llvm::StringSwitch(Value) + .Case("none", LangOptionsBase::None) + .Case("all", LangOptionsBase::All) + .Case("add-overflow-test", LangOptionsBase::AddOverflowTest) + .Case("negated-unsigned-const", LangOptionsBase::NegUnsignedConst) + .Case("post-decr-while", LangOptionsBase::PostDecrInWhile) + .Default(0); + if (E == 0) + D.Diag(clang::diag::err_drv_unsupported_option_argument) + << A->getSpelling() << Value; + Exclusions |= E; + } + return Exclusions; +} + int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A, bool DiagnoseErrors) { assert(A->getOption().matches(options::OPT_fsanitize_coverage) || diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 0e8577b1115e38..c93c97146b6104 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -1366,7 +1366,7 @@ bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args, Default = false; if (A && A->getOption().getID() == options::OPT_ffp_model_EQ) { StringRef Model = A->getValue(); - if (Model != "fast") + if (Model != "fast" && Model != "aggressive") Default = false; } } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index a8606a866bdff6..f7c2f485d3fc11 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2556,6 +2556,7 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, bool Crel = false, ExperimentalCrel = false; bool UseRelaxRelocations = C.getDefaultToolChain().useRelaxRelocations(); bool UseNoExecStack = false; + bool Msa = false; const char *MipsTargetFeature = nullptr; StringRef ImplicitIt; for (const Arg *A : @@ -2665,7 +2666,14 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, CmdArgs.push_back("-soft-float"); continue; } - + if (Value == "-mmsa") { + Msa = true; + continue; + } + if (Value == "-mno-msa") { + Msa = false; + continue; + } MipsTargetFeature = llvm::StringSwitch(Value) .Case("-mips1", "+mips1") .Case("-mips2", "+mips2") @@ -2685,6 +2693,7 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, .Default(nullptr); if (MipsTargetFeature) continue; + break; } if (Value == "-force_cpusubtype_ALL") { @@ -2777,6 +2786,8 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, << "-Wa,--crel" << D.getTargetTriple(); } } + if (Msa) + CmdArgs.push_back("-mmsa"); if (!UseRelaxRelocations) CmdArgs.push_back("-mrelax-relocations=no"); if (UseNoExecStack) @@ -2885,10 +2896,29 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, std::string ComplexRangeStr = ""; std::string GccRangeComplexOption = ""; + auto setComplexRange = [&](LangOptions::ComplexRangeKind NewRange) { + // Warn if user expects to perform full implementation of complex + // multiplication or division in the presence of nnan or ninf flags. + if (Range != NewRange) + EmitComplexRangeDiag(D, + !GccRangeComplexOption.empty() + ? GccRangeComplexOption + : ComplexArithmeticStr(Range), + ComplexArithmeticStr(NewRange)); + Range = NewRange; + }; + // Lambda to set fast-math options. This is also used by -ffp-model=fast - auto applyFastMath = [&]() { - HonorINFs = false; - HonorNaNs = false; + auto applyFastMath = [&](bool Aggressive) { + if (Aggressive) { + HonorINFs = false; + HonorNaNs = false; + setComplexRange(LangOptions::ComplexRangeKind::CX_Basic); + } else { + HonorINFs = true; + HonorNaNs = true; + setComplexRange(LangOptions::ComplexRangeKind::CX_Promoted); + } MathErrno = false; AssociativeMath = true; ReciprocalMath = true; @@ -2897,21 +2927,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, TrappingMath = false; RoundingFPMath = false; FPExceptionBehavior = ""; - // If fast-math is set then set the fp-contract mode to fast. FPContract = "fast"; - // ffast-math enables basic range rules for complex multiplication and - // division. - // Warn if user expects to perform full implementation of complex - // multiplication or division in the presence of nan or ninf flags. - if (Range == LangOptions::ComplexRangeKind::CX_Full || - Range == LangOptions::ComplexRangeKind::CX_Improved || - Range == LangOptions::ComplexRangeKind::CX_Promoted) - EmitComplexRangeDiag( - D, ComplexArithmeticStr(Range), - !GccRangeComplexOption.empty() - ? GccRangeComplexOption - : ComplexArithmeticStr(LangOptions::ComplexRangeKind::CX_Basic)); - Range = LangOptions::ComplexRangeKind::CX_Basic; SeenUnsafeMathModeOption = true; }; @@ -3039,8 +3055,8 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, SignedZeros = true; StringRef Val = A->getValue(); - if (OFastEnabled && Val != "fast") { - // Only -ffp-model=fast is compatible with OFast, ignore. + if (OFastEnabled && Val != "aggressive") { + // Only -ffp-model=aggressive is compatible with -OFast, ignore. D.Diag(clang::diag::warn_drv_overriding_option) << Args.MakeArgString("-ffp-model=" + Val) << "-Ofast"; break; @@ -3052,13 +3068,19 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, << Args.MakeArgString("-ffp-model=" + Val); if (Val == "fast") { FPModel = Val; - applyFastMath(); + applyFastMath(false); // applyFastMath sets fp-contract="fast" LastFpContractOverrideOption = "-ffp-model=fast"; + } else if (Val == "aggressive") { + FPModel = Val; + applyFastMath(true); + // applyFastMath sets fp-contract="fast" + LastFpContractOverrideOption = "-ffp-model=aggressive"; } else if (Val == "precise") { FPModel = Val; FPContract = "on"; LastFpContractOverrideOption = "-ffp-model=precise"; + setComplexRange(LangOptions::ComplexRangeKind::CX_Full); } else if (Val == "strict") { StrictFPModel = true; FPExceptionBehavior = "strict"; @@ -3067,6 +3089,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, LastFpContractOverrideOption = "-ffp-model=strict"; TrappingMath = true; RoundingFPMath = true; + setComplexRange(LangOptions::ComplexRangeKind::CX_Full); } else D.Diag(diag::err_drv_unsupported_option_argument) << A->getSpelling() << Val; @@ -3247,7 +3270,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, continue; [[fallthrough]]; case options::OPT_ffast_math: - applyFastMath(); + applyFastMath(true); if (A->getOption().getID() == options::OPT_Ofast) LastFpContractOverrideOption = "-Ofast"; else @@ -7752,6 +7775,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fgpu_default_stream_EQ); } + Args.AddAllArgs(CmdArgs, + options::OPT_fsanitize_undefined_ignore_overflow_pattern_EQ); + Args.AddLastArg(CmdArgs, options::OPT_foffload_uniform_block, options::OPT_fno_offload_uniform_block); diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index ee6890d5b98f0e..2550541a438481 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -2953,7 +2953,15 @@ static bool sdkSupportsBuiltinModules( case Darwin::MacOS: return SDKVersion >= VersionTuple(15U); case Darwin::IPhoneOS: - return SDKVersion >= VersionTuple(18U); + switch (TargetEnvironment) { + case Darwin::MacCatalyst: + // Mac Catalyst uses `-target arm64-apple-ios18.0-macabi` so the platform + // is iOS, but it builds with the macOS SDK, so it's the macOS SDK version + // that's relevant. + return SDKVersion >= VersionTuple(15U); + default: + return SDKVersion >= VersionTuple(18U); + } case Darwin::TvOS: return SDKVersion >= VersionTuple(18U); case Darwin::WatchOS: diff --git a/clang/lib/ExtractAPI/API.cpp b/clang/lib/ExtractAPI/API.cpp index ab1108f663deac..9dbc023885c37f 100644 --- a/clang/lib/ExtractAPI/API.cpp +++ b/clang/lib/ExtractAPI/API.cpp @@ -13,8 +13,6 @@ //===----------------------------------------------------------------------===// #include "clang/ExtractAPI/API.h" -#include "clang/AST/RawCommentList.h" -#include "clang/Index/USRGeneration.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/ErrorHandling.h" #include @@ -60,6 +58,10 @@ bool RecordContext::IsWellFormed() const { void RecordContext::stealRecordChain(RecordContext &Other) { assert(IsWellFormed()); + // Other's record chain is empty, nothing to do + if (Other.First == nullptr && Other.Last == nullptr) + return; + // If we don't have an empty chain append Other's chain into ours. if (First) Last->NextInContext = Other.First; @@ -68,6 +70,10 @@ void RecordContext::stealRecordChain(RecordContext &Other) { Last = Other.Last; + for (auto *StolenRecord = Other.First; StolenRecord != nullptr; + StolenRecord = StolenRecord->getNextInContext()) + StolenRecord->Parent = SymbolReference(cast(this)); + // Delete Other's chain to ensure we don't accidentally traverse it. Other.First = nullptr; Other.Last = nullptr; @@ -85,6 +91,22 @@ void RecordContext::addToRecordChain(APIRecord *Record) const { Last = Record; } +void RecordContext::removeFromRecordChain(APIRecord *Record) { + APIRecord *Prev = nullptr; + for (APIRecord *Curr = First; Curr != Record; Curr = Curr->NextInContext) + Prev = Curr; + + if (Prev) + Prev->NextInContext = Record->NextInContext; + else + First = Record->NextInContext; + + if (Last == Record) + Last = Prev; + + Record->NextInContext = nullptr; +} + APIRecord *APISet::findRecordForUSR(StringRef USR) const { if (USR.empty()) return nullptr; @@ -114,6 +136,33 @@ SymbolReference APISet::createSymbolReference(StringRef Name, StringRef USR, return SymbolReference(copyString(Name), copyString(USR), copyString(Source)); } +void APISet::removeRecord(StringRef USR) { + auto Result = USRBasedLookupTable.find(USR); + if (Result != USRBasedLookupTable.end()) { + auto *Record = Result->getSecond().get(); + auto &ParentReference = Record->Parent; + auto *ParentRecord = const_cast(ParentReference.Record); + if (!ParentRecord) + ParentRecord = findRecordForUSR(ParentReference.USR); + + if (auto *ParentCtx = llvm::cast_if_present(ParentRecord)) { + ParentCtx->removeFromRecordChain(Record); + if (auto *RecordAsCtx = llvm::dyn_cast(Record)) + ParentCtx->stealRecordChain(*RecordAsCtx); + } else { + TopLevelRecords.erase(Record); + if (auto *RecordAsCtx = llvm::dyn_cast(Record)) { + for (const auto *Child = RecordAsCtx->First; Child != nullptr; + Child = Child->getNextInContext()) + TopLevelRecords.insert(Child); + } + } + USRBasedLookupTable.erase(Result); + } +} + +void APISet::removeRecord(APIRecord *Record) { removeRecord(Record->USR); } + APIRecord::~APIRecord() {} TagRecord::~TagRecord() {} RecordRecord::~RecordRecord() {} diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index 1f8029cbd39ad2..1bce9c59b19791 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -673,14 +673,6 @@ bool SymbolGraphSerializer::shouldSkip(const APIRecord *Record) const { if (Record->Availability.isUnconditionallyUnavailable()) return true; - // Filter out symbols without a name as we can generate correct symbol graphs - // for them. In practice these are anonymous record types that aren't attached - // to a declaration. - if (auto *Tag = dyn_cast(Record)) { - if (Tag->IsEmbeddedInVarDeclarator) - return true; - } - // Filter out symbols prefixed with an underscored as they are understood to // be symbols clients should not use. if (Record->Name.starts_with("_")) diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index e3911c281985b7..f510d3067d4d58 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -4267,6 +4267,20 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val; } + if (auto *A = + Args.getLastArg(OPT_fsanitize_undefined_ignore_overflow_pattern_EQ)) { + for (int i = 0, n = A->getNumValues(); i != n; ++i) { + Opts.OverflowPatternExclusionMask |= + llvm::StringSwitch(A->getValue(i)) + .Case("none", LangOptionsBase::None) + .Case("all", LangOptionsBase::All) + .Case("add-overflow-test", LangOptionsBase::AddOverflowTest) + .Case("negated-unsigned-const", LangOptionsBase::NegUnsignedConst) + .Case("post-decr-while", LangOptionsBase::PostDecrInWhile) + .Default(0); + } + } + // Parse -fsanitize= arguments. parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ), Diags, Opts.Sanitize); diff --git a/clang/lib/Headers/avx2intrin.h b/clang/lib/Headers/avx2intrin.h index 096cae01b57d01..dc9fc073143236 100644 --- a/clang/lib/Headers/avx2intrin.h +++ b/clang/lib/Headers/avx2intrin.h @@ -15,12 +15,21 @@ #define __AVX2INTRIN_H /* Define the default attributes for the functions in this file. */ +#if defined(__EVEX512__) && !defined(__AVX10_1_512__) #define __DEFAULT_FN_ATTRS256 \ __attribute__((__always_inline__, __nodebug__, \ __target__("avx2,no-evex512"), __min_vector_width__(256))) #define __DEFAULT_FN_ATTRS128 \ __attribute__((__always_inline__, __nodebug__, \ __target__("avx2,no-evex512"), __min_vector_width__(128))) +#else +#define __DEFAULT_FN_ATTRS256 \ + __attribute__((__always_inline__, __nodebug__, __target__("avx2"), \ + __min_vector_width__(256))) +#define __DEFAULT_FN_ATTRS128 \ + __attribute__((__always_inline__, __nodebug__, __target__("avx2"), \ + __min_vector_width__(128))) +#endif /* SSE4 Multiple Packed Sums of Absolute Difference. */ /// Computes sixteen sum of absolute difference (SAD) operations on sets of diff --git a/clang/lib/Headers/avxintrin.h b/clang/lib/Headers/avxintrin.h index 4983f331137001..73707c623065e7 100644 --- a/clang/lib/Headers/avxintrin.h +++ b/clang/lib/Headers/avxintrin.h @@ -50,12 +50,21 @@ typedef __bf16 __m256bh __attribute__((__vector_size__(32), __aligned__(32))); #endif /* Define the default attributes for the functions in this file. */ +#if defined(__EVEX512__) && !defined(__AVX10_1_512__) #define __DEFAULT_FN_ATTRS \ __attribute__((__always_inline__, __nodebug__, __target__("avx,no-evex512"), \ __min_vector_width__(256))) #define __DEFAULT_FN_ATTRS128 \ __attribute__((__always_inline__, __nodebug__, __target__("avx,no-evex512"), \ __min_vector_width__(128))) +#else +#define __DEFAULT_FN_ATTRS \ + __attribute__((__always_inline__, __nodebug__, __target__("avx"), \ + __min_vector_width__(256))) +#define __DEFAULT_FN_ATTRS128 \ + __attribute__((__always_inline__, __nodebug__, __target__("avx"), \ + __min_vector_width__(128))) +#endif /* Arithmetic */ /// Adds two 256-bit vectors of [4 x double]. diff --git a/clang/lib/Headers/emmintrin.h b/clang/lib/Headers/emmintrin.h index a3176570a468f7..72a32f953e0118 100644 --- a/clang/lib/Headers/emmintrin.h +++ b/clang/lib/Headers/emmintrin.h @@ -49,9 +49,15 @@ typedef __bf16 __m128bh __attribute__((__vector_size__(16), __aligned__(16))); #endif /* Define the default attributes for the functions in this file. */ +#if defined(__EVEX512__) && !defined(__AVX10_1_512__) #define __DEFAULT_FN_ATTRS \ __attribute__((__always_inline__, __nodebug__, \ __target__("sse2,no-evex512"), __min_vector_width__(128))) +#else +#define __DEFAULT_FN_ATTRS \ + __attribute__((__always_inline__, __nodebug__, __target__("sse2"), \ + __min_vector_width__(128))) +#endif #define __trunc64(x) \ (__m64) __builtin_shufflevector((__v2di)(x), __extension__(__v2di){}, 0) @@ -1774,7 +1780,7 @@ static __inline__ __m128d __DEFAULT_FN_ATTRS _mm_undefined_pd(void) { /// lower 64 bits contain the value of the parameter. The upper 64 bits are /// set to zero. static __inline__ __m128d __DEFAULT_FN_ATTRS _mm_set_sd(double __w) { - return __extension__(__m128d){__w, 0}; + return __extension__(__m128d){__w, 0.0}; } /// Constructs a 128-bit floating-point vector of [2 x double], with each diff --git a/clang/lib/Headers/gfniintrin.h b/clang/lib/Headers/gfniintrin.h index 73b04a824aba8e..9a5743d4b673bc 100644 --- a/clang/lib/Headers/gfniintrin.h +++ b/clang/lib/Headers/gfniintrin.h @@ -14,6 +14,7 @@ #ifndef __GFNIINTRIN_H #define __GFNIINTRIN_H +#if defined(__EVEX512__) && !defined(__AVX10_1_512__) /* Default attributes for simple form (no masking). */ #define __DEFAULT_FN_ATTRS \ __attribute__((__always_inline__, __nodebug__, \ @@ -25,26 +26,47 @@ __target__("avx,gfni,no-evex512"), \ __min_vector_width__(256))) -/* Default attributes for ZMM unmasked forms. */ -#define __DEFAULT_FN_ATTRS_Z \ +/* Default attributes for VLX masked forms. */ +#define __DEFAULT_FN_ATTRS_VL128 \ __attribute__((__always_inline__, __nodebug__, \ - __target__("avx512f,evex512,gfni"), \ - __min_vector_width__(512))) -/* Default attributes for ZMM masked forms. */ -#define __DEFAULT_FN_ATTRS_Z_MASK \ + __target__("avx512bw,avx512vl,gfni,no-evex512"), \ + __min_vector_width__(128))) +#define __DEFAULT_FN_ATTRS_VL256 \ __attribute__((__always_inline__, __nodebug__, \ - __target__("avx512bw,evex512,gfni"), \ - __min_vector_width__(512))) + __target__("avx512bw,avx512vl,gfni,no-evex512"), \ + __min_vector_width__(256))) +#else +/* Default attributes for simple form (no masking). */ +#define __DEFAULT_FN_ATTRS \ + __attribute__((__always_inline__, __nodebug__, __target__("gfni"), \ + __min_vector_width__(128))) + +/* Default attributes for YMM unmasked form. */ +#define __DEFAULT_FN_ATTRS_Y \ + __attribute__((__always_inline__, __nodebug__, __target__("avx,gfni"), \ + __min_vector_width__(256))) /* Default attributes for VLX masked forms. */ #define __DEFAULT_FN_ATTRS_VL128 \ __attribute__((__always_inline__, __nodebug__, \ - __target__("avx512bw,avx512vl,gfni,no-evex512"), \ + __target__("avx512bw,avx512vl,gfni"), \ __min_vector_width__(128))) #define __DEFAULT_FN_ATTRS_VL256 \ __attribute__((__always_inline__, __nodebug__, \ - __target__("avx512bw,avx512vl,gfni,no-evex512"), \ + __target__("avx512bw,avx512vl,gfni"), \ __min_vector_width__(256))) +#endif + +/* Default attributes for ZMM unmasked forms. */ +#define __DEFAULT_FN_ATTRS_Z \ + __attribute__((__always_inline__, __nodebug__, \ + __target__("avx512f,evex512,gfni"), \ + __min_vector_width__(512))) +/* Default attributes for ZMM masked forms. */ +#define __DEFAULT_FN_ATTRS_Z_MASK \ + __attribute__((__always_inline__, __nodebug__, \ + __target__("avx512bw,evex512,gfni"), \ + __min_vector_width__(512))) #define _mm_gf2p8affineinv_epi64_epi8(A, B, I) \ ((__m128i)__builtin_ia32_vgf2p8affineinvqb_v16qi((__v16qi)(__m128i)(A), \ diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 678cdc77f8a71b..6d38b668fe770e 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -916,7 +916,7 @@ float4 lerp(float4, float4, float4); /// \brief Returns the length of the specified floating-point vector. /// \param x [in] The vector of floats, or a scalar float. /// -/// Length is based on the following formula: sqrt(x[0]^2 + x[1]^2 + …). +/// Length is based on the following formula: sqrt(x[0]^2 + x[1]^2 + ...). _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) _HLSL_BUILTIN_ALIAS(__builtin_hlsl_length) @@ -1564,6 +1564,45 @@ float3 round(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_roundeven) float4 round(float4); +//===----------------------------------------------------------------------===// +// saturate builtins +//===----------------------------------------------------------------------===// + +/// \fn T saturate(T Val) +/// \brief Returns input value, \a Val, clamped within the range of 0.0f +/// to 1.0f. \param Val The input value. + +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_saturate) +half saturate(half); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_saturate) +half2 saturate(half2); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_saturate) +half3 saturate(half3); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_saturate) +half4 saturate(half4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_saturate) +float saturate(float); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_saturate) +float2 saturate(float2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_saturate) +float3 saturate(float3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_saturate) +float4 saturate(float4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_saturate) +double saturate(double); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_saturate) +double2 saturate(double2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_saturate) +double3 saturate(double3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_saturate) +double4 saturate(double4); + //===----------------------------------------------------------------------===// // sin builtins //===----------------------------------------------------------------------===// diff --git a/clang/lib/Headers/mmintrin.h b/clang/lib/Headers/mmintrin.h index 9d1e135be63be6..0347c5ccf8254a 100644 --- a/clang/lib/Headers/mmintrin.h +++ b/clang/lib/Headers/mmintrin.h @@ -39,9 +39,15 @@ typedef short __v8hi __attribute__((__vector_size__(16))); typedef char __v16qi __attribute__((__vector_size__(16))); /* Define the default attributes for the functions in this file. */ +#if defined(__EVEX512__) && !defined(__AVX10_1_512__) #define __DEFAULT_FN_ATTRS_SSE2 \ __attribute__((__always_inline__, __nodebug__, \ __target__("sse2,no-evex512"), __min_vector_width__(128))) +#else +#define __DEFAULT_FN_ATTRS_SSE2 \ + __attribute__((__always_inline__, __nodebug__, __target__("sse2"), \ + __min_vector_width__(128))) +#endif #define __trunc64(x) \ (__m64) __builtin_shufflevector((__v2di)(x), __extension__(__v2di){}, 0) diff --git a/clang/lib/Headers/pmmintrin.h b/clang/lib/Headers/pmmintrin.h index 91cee1edda3067..9ad76579668b35 100644 --- a/clang/lib/Headers/pmmintrin.h +++ b/clang/lib/Headers/pmmintrin.h @@ -17,9 +17,15 @@ #include /* Define the default attributes for the functions in this file. */ +#if defined(__EVEX512__) && !defined(__AVX10_1_512__) #define __DEFAULT_FN_ATTRS \ __attribute__((__always_inline__, __nodebug__, \ __target__("sse3,no-evex512"), __min_vector_width__(128))) +#else +#define __DEFAULT_FN_ATTRS \ + __attribute__((__always_inline__, __nodebug__, __target__("sse3"), \ + __min_vector_width__(128))) +#endif /// Loads data from an unaligned memory location to elements in a 128-bit /// vector. diff --git a/clang/lib/Headers/smmintrin.h b/clang/lib/Headers/smmintrin.h index b3fec474e35a1e..bc6fe4c801d7ea 100644 --- a/clang/lib/Headers/smmintrin.h +++ b/clang/lib/Headers/smmintrin.h @@ -17,9 +17,15 @@ #include /* Define the default attributes for the functions in this file. */ +#if defined(__EVEX512__) && !defined(__AVX10_1_512__) #define __DEFAULT_FN_ATTRS \ __attribute__((__always_inline__, __nodebug__, \ __target__("sse4.1,no-evex512"), __min_vector_width__(128))) +#else +#define __DEFAULT_FN_ATTRS \ + __attribute__((__always_inline__, __nodebug__, __target__("sse4.1"), \ + __min_vector_width__(128))) +#endif /* SSE4 Rounding macros. */ #define _MM_FROUND_TO_NEAREST_INT 0x00 diff --git a/clang/lib/Headers/tmmintrin.h b/clang/lib/Headers/tmmintrin.h index bd832ce8dddfdf..371cc82e3dc9da 100644 --- a/clang/lib/Headers/tmmintrin.h +++ b/clang/lib/Headers/tmmintrin.h @@ -17,9 +17,15 @@ #include /* Define the default attributes for the functions in this file. */ +#if defined(__EVEX512__) && !defined(__AVX10_1_512__) #define __DEFAULT_FN_ATTRS \ __attribute__((__always_inline__, __nodebug__, \ __target__("ssse3,no-evex512"), __min_vector_width__(128))) +#else +#define __DEFAULT_FN_ATTRS \ + __attribute__((__always_inline__, __nodebug__, __target__("ssse3"), \ + __min_vector_width__(128))) +#endif #define __trunc64(x) \ (__m64) __builtin_shufflevector((__v2di)(x), __extension__(__v2di){}, 0) diff --git a/clang/lib/Headers/xmmintrin.h b/clang/lib/Headers/xmmintrin.h index 5b9e90e8f061c1..9958e91bfceaa9 100644 --- a/clang/lib/Headers/xmmintrin.h +++ b/clang/lib/Headers/xmmintrin.h @@ -32,12 +32,21 @@ typedef unsigned int __v4su __attribute__((__vector_size__(16))); #endif /* Define the default attributes for the functions in this file. */ +#if defined(__EVEX512__) && !defined(__AVX10_1_512__) #define __DEFAULT_FN_ATTRS \ __attribute__((__always_inline__, __nodebug__, __target__("sse,no-evex512"), \ __min_vector_width__(128))) #define __DEFAULT_FN_ATTRS_SSE2 \ __attribute__((__always_inline__, __nodebug__, \ __target__("sse2,no-evex512"), __min_vector_width__(128))) +#else +#define __DEFAULT_FN_ATTRS \ + __attribute__((__always_inline__, __nodebug__, __target__("sse"), \ + __min_vector_width__(128))) +#define __DEFAULT_FN_ATTRS_SSE2 \ + __attribute__((__always_inline__, __nodebug__, __target__("sse2"), \ + __min_vector_width__(128))) +#endif #define __trunc64(x) \ (__m64) __builtin_shufflevector((__v2di)(x), __extension__(__v2di){}, 0) @@ -1925,7 +1934,7 @@ _mm_undefined_ps(void) static __inline__ __m128 __DEFAULT_FN_ATTRS _mm_set_ss(float __w) { - return __extension__ (__m128){ __w, 0, 0, 0 }; + return __extension__ (__m128){ __w, 0.0f, 0.0f, 0.0f }; } /// Constructs a 128-bit floating-point vector of [4 x float], with each diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index f495658fe58641..c67183df335dd5 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -923,6 +923,13 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) { E = Temp.get(); } + // C++ [expr.call]p7, per CWG722: + // An argument that has (possibly cv-qualified) type std::nullptr_t is + // converted to void* ([conv.ptr]). + // (This does not apply to C23 nullptr) + if (getLangOpts().CPlusPlus && E->getType()->isNullPtrType()) + E = ImpCastExprToType(E, Context.VoidPtrTy, CK_NullToPointer).get(); + return E; } @@ -933,9 +940,9 @@ Sema::VarArgKind Sema::isValidVarArgType(const QualType &Ty) { // enumeration, pointer, pointer to member, or class type, the program // is ill-formed. // - // Since we've already performed array-to-pointer and function-to-pointer - // decay, the only such type in C++ is cv void. This also handles - // initializer lists as variadic arguments. + // Since we've already performed null pointer conversion, array-to-pointer + // decay and function-to-pointer decay, the only such type in C++ is cv + // void. This also handles initializer lists as variadic arguments. if (Ty->isVoidType()) return VAK_Invalid; diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index e3e926465e799e..df01549cc2eeb6 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -356,7 +356,7 @@ static bool isLegalTypeForHLSLSV_DispatchThreadID(QualType T) { return true; } -void SemaHLSL::handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL) { +void SemaHLSL::handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL) { auto *VD = cast(D); if (!isLegalTypeForHLSLSV_DispatchThreadID(VD->getType())) { Diag(AL.getLoc(), diag::err_hlsl_attr_invalid_type) @@ -1045,6 +1045,7 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; break; } + case Builtin::BI__builtin_hlsl_elementwise_saturate: case Builtin::BI__builtin_hlsl_elementwise_rcp: { if (CheckAllArgsHaveFloatRepresentation(&SemaRef, TheCall)) return true; diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index a33f2a41a65497..8ae07907a04aba 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -1128,6 +1128,7 @@ void ASTStmtReader::VisitBinaryOperator(BinaryOperator *E) { (BinaryOperator::Opcode)CurrentUnpackingBits->getNextBits(/*Width=*/6)); bool hasFP_Features = CurrentUnpackingBits->getNextBit(); E->setHasStoredFPFeatures(hasFP_Features); + E->setExcludedOverflowPattern(CurrentUnpackingBits->getNextBit()); E->setLHS(Record.readSubExpr()); E->setRHS(Record.readSubExpr()); E->setOperatorLoc(readSourceLocation()); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 038616a675b727..c292d0a789c7cd 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -1063,6 +1063,7 @@ void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) { CurrentPackingBits.addBits(E->getOpcode(), /*Width=*/6); bool HasFPFeatures = E->hasStoredFPFeatures(); CurrentPackingBits.addBit(HasFPFeatures); + CurrentPackingBits.addBit(E->hasExcludedOverflowPattern()); Record.AddStmt(E->getLHS()); Record.AddStmt(E->getRHS()); Record.AddSourceLocation(E->getOperatorLoc()); diff --git a/clang/test/AST/ByteCode/c23.c b/clang/test/AST/ByteCode/c23.c index e839fc716f5b52..f9157e40610cc3 100644 --- a/clang/test/AST/ByteCode/c23.c +++ b/clang/test/AST/ByteCode/c23.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -std=c23 -fexperimental-new-constant-interpreter -verify=expected,both %s // RUN: %clang_cc1 -std=c23 -verify=ref,both %s - +typedef typeof(nullptr) nullptr_t; const _Bool inf1 = (1.0/0.0 == __builtin_inf()); constexpr _Bool inf2 = (1.0/0.0 == __builtin_inf()); // both-error {{must be initialized by a constant expression}} \ @@ -22,3 +22,6 @@ char bar() { ((struct S *)buffer)->c = 'a'; return ((struct S *)buffer)->c; } + + +static_assert((nullptr_t){} == 0); diff --git a/clang/test/CXX/drs/cwg722.cpp b/clang/test/CXX/drs/cwg722.cpp new file mode 100644 index 00000000000000..e90d9af360d9d0 --- /dev/null +++ b/clang/test/CXX/drs/cwg722.cpp @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -std=c++98 %s -verify -pedantic-errors +// RUN: %clang_cc1 -std=c++11 %s -verify -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++14 %s -verify -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++17 %s -verify -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++20 %s -verify -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++23 %s -verify -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++26 %s -verify -pedantic-errors -ast-dump | FileCheck %s + +// expected-no-diagnostics +// cwg722: 20 + +#if __cplusplus >= 201103L +namespace std { + using nullptr_t = decltype(nullptr); +} + +void f(std::nullptr_t...); +std::nullptr_t g(); +void h() { + std::nullptr_t np; + const std::nullptr_t cnp = nullptr; + extern int i; + f( + nullptr, + nullptr, np, cnp, + static_cast(np), + g(), + __builtin_bit_cast(std::nullptr_t, static_cast(&i)) + ); +// CHECK: `-CallExpr {{.+}} 'void' +// CHECK-NEXT: |-ImplicitCastExpr {{.+}} 'void (*)(std::nullptr_t, ...)' +// CHECK-NEXT: | `-DeclRefExpr {{.+}} 'void (std::nullptr_t, ...)' lvalue Function {{.+}} 'f' 'void (std::nullptr_t, ...)' +// CHECK-NEXT: |-CXXNullPtrLiteralExpr {{.+}} 'std::nullptr_t' +// CHECK-NEXT: |-ImplicitCastExpr {{.+}} 'void *' +// CHECK-NEXT: | `-CXXNullPtrLiteralExpr {{.+}} 'std::nullptr_t' +// CHECK-NEXT: |-ImplicitCastExpr {{.+}} 'void *' +// CHECK-NEXT: | `-DeclRefExpr {{.+}} 'std::nullptr_t' lvalue Var {{.+}} 'np' 'std::nullptr_t' +// CHECK-NEXT: |-ImplicitCastExpr {{.+}} 'void *' +// CHECK-NEXT: | `-DeclRefExpr {{.+}} 'const std::nullptr_t' lvalue Var {{.+}} 'cnp' 'const std::nullptr_t' +// CHECK-NEXT: |-ImplicitCastExpr {{.+}} 'void *' +// CHECK-NEXT: | `-CXXStaticCastExpr {{.+}} 'std::nullptr_t' static_cast +// CHECK-NEXT: | `-ImplicitCastExpr {{.+}} 'std::nullptr_t' part_of_explicit_cast +// CHECK-NEXT: | `-DeclRefExpr {{.+}} 'std::nullptr_t' lvalue Var {{.+}} 'np' 'std::nullptr_t' +// CHECK-NEXT: |-ImplicitCastExpr {{.+}} 'void *' +// CHECK-NEXT: | `-CallExpr {{.+}} 'std::nullptr_t' +// CHECK-NEXT: | `-ImplicitCastExpr {{.+}} 'std::nullptr_t (*)()' +// CHECK-NEXT: | `-DeclRefExpr {{.+}} 'std::nullptr_t ()' lvalue Function {{.+}} 'g' 'std::nullptr_t ()' +// CHECK-NEXT: `-ImplicitCastExpr {{.+}} 'void *' +// CHECK-NEXT: `-BuiltinBitCastExpr {{.+}} 'std::nullptr_t' +// CHECK-NEXT: `-MaterializeTemporaryExpr {{.+}} 'void *' xvalue +// CHECK-NEXT: `-CXXStaticCastExpr {{.+}} 'void *' static_cast +// CHECK-NEXT: `-ImplicitCastExpr {{.+}} 'void *' part_of_explicit_cast +// CHECK-NEXT: `-UnaryOperator {{.+}} 'int *' prefix '&' cannot overflow +// CHECK-NEXT: `-DeclRefExpr {{.+}} 'int' lvalue Var {{.+}} 'i' 'int' +} +#endif diff --git a/clang/test/CXX/drs/cwg7xx.cpp b/clang/test/CXX/drs/cwg7xx.cpp index d120eb2487aff3..507eb8fb714350 100644 --- a/clang/test/CXX/drs/cwg7xx.cpp +++ b/clang/test/CXX/drs/cwg7xx.cpp @@ -96,6 +96,8 @@ static_assert(!is_volatile::value, ""); #endif } // namespace cwg713 +// cwg722 is in cwg722.cpp + namespace cwg727 { // cwg727: partial struct A { template struct C; // #cwg727-C diff --git a/clang/test/CodeGen/X86/avx512vlbw-builtins.c b/clang/test/CodeGen/X86/avx512vlbw-builtins.c index e2ce348d0e077f..4ec499caabf04e 100644 --- a/clang/test/CodeGen/X86/avx512vlbw-builtins.c +++ b/clang/test/CodeGen/X86/avx512vlbw-builtins.c @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx512bw -target-feature +avx512vl -emit-llvm -o - -Wall -Werror -Wsign-conversion | FileCheck %s // RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx512bw -target-feature +avx512vl -fno-signed-char -emit-llvm -o - -Wall -Werror -Wsign-conversion | FileCheck %s +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx10.1-512 -emit-llvm -o - -Wall -Werror -Wsign-conversion | FileCheck %s #include diff --git a/clang/test/CodeGen/X86/strictfp_patterns.c b/clang/test/CodeGen/X86/strictfp_patterns.c new file mode 100644 index 00000000000000..55d85f22c3ba3d --- /dev/null +++ b/clang/test/CodeGen/X86/strictfp_patterns.c @@ -0,0 +1,26 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 %s -O2 -emit-llvm -o - -triple x86_64-unknown-unknown -ffreestanding -ffp-exception-behavior=maytrap -Wall -Werror | FileCheck %s + +#include + +// PR104848 - ensure the _mm_set_ss/d headers don't implicity promote any integer/fp values. + +// CHECK-LABEL: @test_mm_set_ss( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x float> , float [[NUM:%.*]], i64 0 +// CHECK-NEXT: ret <4 x float> [[VECINIT3_I]] +// +__m128 test_mm_set_ss(float num) +{ + return _mm_set_ss(num); +} + +// CHECK-LABEL: @test_mm_set_sd( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x double> , double [[NUM:%.*]], i64 0 +// CHECK-NEXT: ret <2 x double> [[VECINIT1_I]] +// +__m128d test_mm_set_sd(double num) +{ + return _mm_set_sd(num); +} diff --git a/clang/test/CodeGen/ffp-model.c b/clang/test/CodeGen/ffp-model.c index 4ed9b9dc0a780c..5516ccb218b03f 100644 --- a/clang/test/CodeGen/ffp-model.c +++ b/clang/test/CodeGen/ffp-model.c @@ -3,6 +3,9 @@ // RUN: %clang -S -emit-llvm -fenable-matrix -ffp-model=fast %s -o - \ // RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-FAST +// RUN: %clang -S -emit-llvm -fenable-matrix -ffp-model=aggressive %s -o - \ +// RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-AGGRESSIVE + // RUN: %clang -S -emit-llvm -fenable-matrix -ffp-model=precise %s -o - \ // RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-PRECISE @@ -20,9 +23,13 @@ float mymuladd(float x, float y, float z) { // CHECK: define{{.*}} float @mymuladd return x * y + z; - // CHECK-FAST: fmul fast float + // CHECK-AGGRESSIVE: fmul fast float + // CHECK-AGGRESSIVE: load float, ptr + // CHECK-AGGRESSIVE: fadd fast float + + // CHECK-FAST: fmul reassoc nsz arcp contract afn float // CHECK-FAST: load float, ptr - // CHECK-FAST: fadd fast float + // CHECK-FAST: fadd reassoc nsz arcp contract afn float // CHECK-PRECISE: load float, ptr // CHECK-PRECISE: load float, ptr @@ -54,9 +61,13 @@ void my_vec_muladd(v2f x, float y, v2f z, v2f *res) { // CHECK: define{{.*}}@my_vec_muladd *res = x * y + z; - // CHECK-FAST: fmul fast <2 x float> + // CHECK-AGGRESSIVE: fmul fast <2 x float> + // CHECK-AGGRESSIVE: load <2 x float>, ptr + // CHECK-AGGRESSIVE: fadd fast <2 x float> + + // CHECK-FAST: fmul reassoc nsz arcp contract afn <2 x float> // CHECK-FAST: load <2 x float>, ptr - // CHECK-FAST: fadd fast <2 x float> + // CHECK-FAST: fadd reassoc nsz arcp contract afn <2 x float> // CHECK-PRECISE: load <2 x float>, ptr // CHECK-PRECISE: load float, ptr @@ -88,9 +99,13 @@ void my_m21_muladd(m21f x, float y, m21f z, m21f *res) { // CHECK: define{{.*}}@my_m21_muladd *res = x * y + z; - // CHECK-FAST: fmul fast <2 x float> + // CHECK-AGGRESSIVE: fmul fast <2 x float> + // CHECK-AGGRESSIVE: load <2 x float>, ptr + // CHECK-AGGRESSIVE: fadd fast <2 x float> + + // CHECK-FAST: fmul reassoc nsz arcp contract afn <2 x float> // CHECK-FAST: load <2 x float>, ptr - // CHECK-FAST: fadd fast <2 x float> + // CHECK-FAST: fadd reassoc nsz arcp contract afn <2 x float> // CHECK-PRECISE: load <2 x float>, ptr // CHECK-PRECISE: load float, ptr @@ -122,9 +137,13 @@ void my_m22_muladd(m22f x, float y, m22f z, m22f *res) { // CHECK: define{{.*}}@my_m22_muladd *res = x * y + z; - // CHECK-FAST: fmul fast <4 x float> + // CHECK-AGGRESSIVE: fmul fast <4 x float> + // CHECK-AGGRESSIVE: load <4 x float>, ptr + // CHECK-AGGRESSIVE: fadd fast <4 x float> + + // CHECK-FAST: fmul reassoc nsz arcp contract afn <4 x float> // CHECK-FAST: load <4 x float>, ptr - // CHECK-FAST: fadd fast <4 x float> + // CHECK-FAST: fadd reassoc nsz arcp contract afn <4 x float> // CHECK-PRECISE: load <4 x float>, ptr // CHECK-PRECISE: load float, ptr diff --git a/clang/test/CodeGen/ignore-overflow-pattern-false-pos.c b/clang/test/CodeGen/ignore-overflow-pattern-false-pos.c new file mode 100644 index 00000000000000..40193e0c3e2671 --- /dev/null +++ b/clang/test/CodeGen/ignore-overflow-pattern-false-pos.c @@ -0,0 +1,63 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsanitize=signed-integer-overflow,unsigned-integer-overflow -fsanitize-undefined-ignore-overflow-pattern=all %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsanitize=signed-integer-overflow,unsigned-integer-overflow -fsanitize-undefined-ignore-overflow-pattern=all -fwrapv %s -emit-llvm -o - | FileCheck %s + +// Check for potential false positives from patterns that _almost_ match classic overflow-dependent or overflow-prone code patterns +extern unsigned a, b, c; +extern int u, v, w; + +extern unsigned some(void); + +// Make sure all these still have handler paths, we shouldn't be excluding +// instrumentation of any "near" patterns. +// CHECK-LABEL: close_but_not_quite +void close_but_not_quite(void) { + // CHECK: br i1{{.*}}handler. + if (a + b > a) + c = 9; + + // CHECK: br i1{{.*}}handler. + if (a - b < a) + c = 9; + + // CHECK: br i1{{.*}}handler. + if (a + b < a) + c = 9; + + // CHECK: br i1{{.*}}handler. + if (a + b + 1 < a) + c = 9; + + // CHECK: br i1{{.*}}handler. + // CHECK: br i1{{.*}}handler. + if (a + b < a + 1) + c = 9; + + // CHECK: br i1{{.*}}handler. + if (b >= a + b) + c = 9; + + // CHECK: br i1{{.*}}handler. + if (a + a < a) + c = 9; + + // CHECK: br i1{{.*}}handler. + if (a + b == a) + c = 9; + + // CHECK: br i1{{.*}}handler + while (--a) + some(); +} + +// CHECK-LABEL: function_calls +void function_calls(void) { + // CHECK: br i1{{.*}}handler + if (some() + b < some()) + c = 9; +} + +// CHECK-LABEL: not_quite_a_negated_unsigned_const +void not_quite_a_negated_unsigned_const(void) { + // CHECK: br i1{{.*}}handler + a = -b; +} diff --git a/clang/test/CodeGen/ignore-overflow-pattern.c b/clang/test/CodeGen/ignore-overflow-pattern.c new file mode 100644 index 00000000000000..b7d700258f8538 --- /dev/null +++ b/clang/test/CodeGen/ignore-overflow-pattern.c @@ -0,0 +1,181 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsanitize=signed-integer-overflow,unsigned-integer-overflow -fsanitize-undefined-ignore-overflow-pattern=all %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsanitize=signed-integer-overflow,unsigned-integer-overflow -fsanitize-undefined-ignore-overflow-pattern=all -fwrapv %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsanitize=signed-integer-overflow,unsigned-integer-overflow -fsanitize-undefined-ignore-overflow-pattern=add-overflow-test %s -emit-llvm -o - | FileCheck %s --check-prefix=ADD +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsanitize=signed-integer-overflow,unsigned-integer-overflow -fsanitize-undefined-ignore-overflow-pattern=negated-unsigned-const %s -emit-llvm -o - | FileCheck %s --check-prefix=NEGATE +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsanitize=signed-integer-overflow,unsigned-integer-overflow -fsanitize-undefined-ignore-overflow-pattern=post-decr-while %s -emit-llvm -o - | FileCheck %s --check-prefix=WHILE + +// Ensure some common overflow-dependent or overflow-prone code patterns don't +// trigger the overflow sanitizers. In many cases, overflow warnings caused by +// these patterns are seen as "noise" and result in users turning off +// sanitization all together. + +// A pattern like "if (a + b < a)" simply checks for overflow and usually means +// the user is trying to handle it gracefully. + +// Similarly, a pattern resembling "while (i--)" is extremely common and +// warning on its inevitable overflow can be seen as superfluous. Do note that +// using "i" in future calculations can be tricky because it will still +// wrap-around. + +// Another common pattern that, in some cases, is found to be too noisy is +// unsigned negation, for example: +// unsigned long A = -1UL; + + +// CHECK-NOT: handle{{.*}}overflow + +extern unsigned a, b, c; +extern unsigned some(void); + +// ADD-LABEL: @basic_commutativity +// WHILE-LABEL: @basic_commutativity +// NEGATE-LABEL: @basic_commutativity +// WHILE: handler.add_overflow +// NEGATE: handler.add_overflow +// ADD-NOT: handler.add_overflow +void basic_commutativity(void) { + if (a + b < a) + c = 9; + if (a + b < b) + c = 9; + if (b + a < b) + c = 9; + if (b + a < a) + c = 9; + if (a > a + b) + c = 9; + if (a > b + a) + c = 9; + if (b > a + b) + c = 9; + if (b > b + a) + c = 9; +} + +// ADD-LABEL: @arguments_and_commutativity +// WHILE-LABEL: @arguments_and_commutativity +// NEGATE-LABEL: @arguments_and_commutativity +// WHILE: handler.add_overflow +// NEGATE: handler.add_overflow +// ADD-NOT: handler.add_overflow +void arguments_and_commutativity(unsigned V1, unsigned V2) { + if (V1 + V2 < V1) + c = 9; + if (V1 + V2 < V2) + c = 9; + if (V2 + V1 < V2) + c = 9; + if (V2 + V1 < V1) + c = 9; + if (V1 > V1 + V2) + c = 9; + if (V1 > V2 + V1) + c = 9; + if (V2 > V1 + V2) + c = 9; + if (V2 > V2 + V1) + c = 9; +} + +// ADD-LABEL: @pointers +// WHILE-LABEL: @pointers +// NEGATE-LABEL: @pointers +// WHILE: handler.add_overflow +// NEGATE: handler.add_overflow +// ADD-NOT: handler.add_overflow +void pointers(unsigned *P1, unsigned *P2, unsigned V1) { + if (*P1 + *P2 < *P1) + c = 9; + if (*P1 + V1 < V1) + c = 9; + if (V1 + *P2 < *P2) + c = 9; +} + +struct OtherStruct { + unsigned foo, bar; +}; + +struct MyStruct { + unsigned base, offset; + struct OtherStruct os; +}; + +extern struct MyStruct ms; + +// ADD-LABEL: @structs +// WHILE-LABEL: @structs +// NEGATE-LABEL: @structs +// WHILE: handler.add_overflow +// NEGATE: handler.add_overflow +// ADD-NOT: handler.add_overflow +void structs(void) { + if (ms.base + ms.offset < ms.base) + c = 9; +} + +// ADD-LABEL: @nestedstructs +// WHILE-LABEL: @nestedstructs +// NEGATE-LABEL: @nestedstructs +// WHILE: handler.add_overflow +// NEGATE: handler.add_overflow +// ADD-NOT: handler.add_overflow +void nestedstructs(void) { + if (ms.os.foo + ms.os.bar < ms.os.foo) + c = 9; +} + +// ADD-LABEL: @constants +// WHILE-LABEL: @constants +// NEGATE-LABEL: @constants +// WHILE: handler.add_overflow +// NEGATE: handler.add_overflow +// ADD-NOT: handler.add_overflow +// Normally, this would be folded into a simple call to the overflow handler +// and a store. Excluding this pattern results in just a store. +void constants(void) { + unsigned base = 4294967295; + unsigned offset = 1; + if (base + offset < base) + c = 9; +} +// ADD-LABEL: @common_while +// NEGATE-LABEL: @common_while +// WHILE-LABEL: @common_while +// ADD: usub.with.overflow +// NEGATE: usub.with.overflow +// WHILE: %dec = add i32 %0, -1 +void common_while(unsigned i) { + // This post-decrement usually causes overflow sanitizers to trip on the very + // last operation. + while (i--) { + some(); + } +} + +// ADD-LABEL: @negation +// NEGATE-LABEL: @negation +// WHILE-LABEL @negation +// ADD: negate_overflow +// NEGATE-NOT: negate_overflow +// WHILE: negate_overflow +// Normally, these assignments would trip the unsigned overflow sanitizer. +void negation(void) { +#define SOME -1UL + unsigned long A = -1UL; + unsigned long B = -2UL; + unsigned long C = -SOME; + (void)A;(void)B;(void)C; +} + + +// ADD-LABEL: @function_call +// WHILE-LABEL: @function_call +// NEGATE-LABEL: @function_call +// WHILE: handler.add_overflow +// NEGATE: handler.add_overflow +// ADD-NOT: handler.add_overflow +void function_call(void) { + if (b + some() < b) + c = 9; +} diff --git a/clang/test/CodeGen/kcfi-normalize.c b/clang/test/CodeGen/kcfi-normalize.c index 7660c908a7bdd5..b9150e88f6ab5f 100644 --- a/clang/test/CodeGen/kcfi-normalize.c +++ b/clang/test/CodeGen/kcfi-normalize.c @@ -28,6 +28,7 @@ void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) { fn(arg1, arg2, arg3); } +// CHECK: ![[#]] = !{i32 4, !"cfi-normalize-integers", i32 1} // CHECK: ![[TYPE1]] = !{i32 -1143117868} // CHECK: ![[TYPE2]] = !{i32 -460921415} // CHECK: ![[TYPE3]] = !{i32 -333839615} diff --git a/clang/test/CodeGenHLSL/builtins/saturate.hlsl b/clang/test/CodeGenHLSL/builtins/saturate.hlsl new file mode 100644 index 00000000000000..65a3cd74621cc0 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/saturate.hlsl @@ -0,0 +1,95 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ +// RUN: --check-prefixes=CHECK,NATIVE_HALF +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ +// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF + +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-unknown-vulkan-library %s -fnative-half-type \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ +// RUN: --check-prefixes=SPIRV,SPIRV_HALF +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-unknown-vulkan-library %s \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ +// RUN: --check-prefixes=SPIRV,SPIRV_NO_HALF + +// NATIVE_HALF: define noundef half @ +// NATIVE_HALF: call half @llvm.dx.saturate.f16( +// NO_HALF: define noundef float @"?test_saturate_half +// NO_HALF: call float @llvm.dx.saturate.f32( +// SPIRV_HALF: define spir_func noundef half @_Z18test_saturate_halfDh(half +// SPIRV_HALF: call half @llvm.spv.saturate.f16(half +// SPIRV_NO_HALF: define spir_func noundef float @_Z18test_saturate_halfDh(float +// SPIRV_NO_HALF: call float @llvm.spv.saturate.f32(float +half test_saturate_half(half p0) { return saturate(p0); } +// NATIVE_HALF: define noundef <2 x half> @ +// NATIVE_HALF: call <2 x half> @llvm.dx.saturate.v2f16 +// NO_HALF: define noundef <2 x float> @"?test_saturate_half2 +// NO_HALF: call <2 x float> @llvm.dx.saturate.v2f32( +// SPIRV_HALF: define spir_func noundef <2 x half> @_Z19test_saturate_half2Dv2_Dh( +// SPIRV_HALF: call <2 x half> @llvm.spv.saturate.v2f16(<2 x half> +// SPIRV_NO_HALF: define spir_func noundef <2 x float> @_Z19test_saturate_half2Dv2_Dh(<2 x float> +// SPIRV_NO_HALF: call <2 x float> @llvm.spv.saturate.v2f32(<2 x float> +half2 test_saturate_half2(half2 p0) { return saturate(p0); } +// NATIVE_HALF: define noundef <3 x half> @ +// NATIVE_HALF: call <3 x half> @llvm.dx.saturate.v3f16 +// NO_HALF: define noundef <3 x float> @"?test_saturate_half3 +// NO_HALF: call <3 x float> @llvm.dx.saturate.v3f32( +// SPIRV_HALF: define spir_func noundef <3 x half> @_Z19test_saturate_half3Dv3_Dh( +// SPIRV_HALF: call <3 x half> @llvm.spv.saturate.v3f16(<3 x half> +// SPIRV_NO_HALF: define spir_func noundef <3 x float> @_Z19test_saturate_half3Dv3_Dh(<3 x float> +// SPIRV_NO_HALF: call <3 x float> @llvm.spv.saturate.v3f32(<3 x float> +half3 test_saturate_half3(half3 p0) { return saturate(p0); } +// NATIVE_HALF: define noundef <4 x half> @ +// NATIVE_HALF: call <4 x half> @llvm.dx.saturate.v4f16 +// NO_HALF: define noundef <4 x float> @"?test_saturate_half4 +// NO_HALF: call <4 x float> @llvm.dx.saturate.v4f32( +// SPIRV_HALF: define spir_func noundef <4 x half> @_Z19test_saturate_half4Dv4_Dh( +// SPIRV_HALF: call <4 x half> @llvm.spv.saturate.v4f16(<4 x half> +// SPIRV_NO_HALF: define spir_func noundef <4 x float> @_Z19test_saturate_half4Dv4_Dh(<4 x float> +// SPIRV_NO_HALF: call <4 x float> @llvm.spv.saturate.v4f32(<4 x float> +half4 test_saturate_half4(half4 p0) { return saturate(p0); } + +// CHECK: define noundef float @"?test_saturate_float +// CHECK: call float @llvm.dx.saturate.f32( +// SPIRV: define spir_func noundef float @_Z19test_saturate_floatf(float +// SPIRV: call float @llvm.spv.saturate.f32(float +float test_saturate_float(float p0) { return saturate(p0); } +// CHECK: define noundef <2 x float> @"?test_saturate_float2 +// CHECK: call <2 x float> @llvm.dx.saturate.v2f32 +// SPIRV: define spir_func noundef <2 x float> @_Z20test_saturate_float2Dv2_f(<2 x float> +// SPIRV: call <2 x float> @llvm.spv.saturate.v2f32(<2 x float> +float2 test_saturate_float2(float2 p0) { return saturate(p0); } +// CHECK: define noundef <3 x float> @"?test_saturate_float3 +// CHECK: call <3 x float> @llvm.dx.saturate.v3f32 +// SPIRV: define spir_func noundef <3 x float> @_Z20test_saturate_float3Dv3_f(<3 x float> +// SPIRV: call <3 x float> @llvm.spv.saturate.v3f32(<3 x float> +float3 test_saturate_float3(float3 p0) { return saturate(p0); } +// CHECK: define noundef <4 x float> @"?test_saturate_float4 +// CHECK: call <4 x float> @llvm.dx.saturate.v4f32 +// SPIRV: define spir_func noundef <4 x float> @_Z20test_saturate_float4Dv4_f(<4 x float> +// SPIRV: call <4 x float> @llvm.spv.saturate.v4f32(<4 x float> +float4 test_saturate_float4(float4 p0) { return saturate(p0); } + +// CHECK: define noundef double @ +// CHECK: call double @llvm.dx.saturate.f64( +// SPIRV: define spir_func noundef double @_Z20test_saturate_doubled(double +// SPIRV: call double @llvm.spv.saturate.f64(double +double test_saturate_double(double p0) { return saturate(p0); } +// CHECK: define noundef <2 x double> @ +// CHECK: call <2 x double> @llvm.dx.saturate.v2f64 +// SPIRV: define spir_func noundef <2 x double> @_Z21test_saturate_double2Dv2_d(<2 x double> +// SPIRV: call <2 x double> @llvm.spv.saturate.v2f64(<2 x double> +double2 test_saturate_double2(double2 p0) { return saturate(p0); } +// CHECK: define noundef <3 x double> @ +// CHECK: call <3 x double> @llvm.dx.saturate.v3f64 +// SPIRV: define spir_func noundef <3 x double> @_Z21test_saturate_double3Dv3_d(<3 x double> +// SPIRV: call <3 x double> @llvm.spv.saturate.v3f64(<3 x double> +double3 test_saturate_double3(double3 p0) { return saturate(p0); } +// CHECK: define noundef <4 x double> @ +// CHECK: call <4 x double> @llvm.dx.saturate.v4f64 +// SPIRV: define spir_func noundef <4 x double> @_Z21test_saturate_double4Dv4_d(<4 x double> +// SPIRV: call <4 x double> @llvm.spv.saturate.v4f64(<4 x double> +double4 test_saturate_double4(double4 p0) { return saturate(p0); } diff --git a/clang/test/CodeGenOpenCL/builtins-fp-atomics-gfx12.cl b/clang/test/CodeGenOpenCL/builtins-fp-atomics-gfx12.cl index 6b8a6d14575db8..e8b6eb57c38d7a 100644 --- a/clang/test/CodeGenOpenCL/builtins-fp-atomics-gfx12.cl +++ b/clang/test/CodeGenOpenCL/builtins-fp-atomics-gfx12.cl @@ -11,7 +11,7 @@ typedef short __attribute__((ext_vector_type(2))) short2; // CHECK-LABEL: test_local_add_2bf16 // CHECK: [[BC0:%.+]] = bitcast <2 x i16> {{.+}} to <2 x bfloat> -// CHECK: [[RMW:%.+]] = atomicrmw fadd ptr addrspace(3) %{{.+}}, <2 x bfloat> [[BC0]] syncscope("agent") monotonic, align 4 +// CHECK-NEXT: [[RMW:%.+]] = atomicrmw fadd ptr addrspace(3) %{{.+}}, <2 x bfloat> [[BC0]] syncscope("agent") monotonic, align 4 // CHECK-NEXT: bitcast <2 x bfloat> [[RMW]] to <2 x i16> // GFX12-LABEL: test_local_add_2bf16 @@ -48,7 +48,8 @@ void test_local_add_2f16_noret(__local half2 *addr, half2 x) { } // CHECK-LABEL: test_flat_add_2f16 -// CHECK: call <2 x half> @llvm.amdgcn.flat.atomic.fadd.v2f16.p0.v2f16(ptr %{{.*}}, <2 x half> %{{.*}}) +// CHECK: [[RMW:%.+]] = atomicrmw fadd ptr %{{.+}}, <2 x half> %{{.+}} syncscope("agent") monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // GFX12-LABEL: test_flat_add_2f16 // GFX12: flat_atomic_pk_add_f16 half2 test_flat_add_2f16(__generic half2 *addr, half2 x) { @@ -56,7 +57,10 @@ half2 test_flat_add_2f16(__generic half2 *addr, half2 x) { } // CHECK-LABEL: test_flat_add_2bf16 -// CHECK: call <2 x i16> @llvm.amdgcn.flat.atomic.fadd.v2bf16.p0(ptr %{{.*}}, <2 x i16> %{{.*}}) +// CHECK: [[BC:%.+]] = bitcast <2 x i16> %{{.+}} to <2 x bfloat> +// CHECK: [[RMW:%.+]] = atomicrmw fadd ptr %{{.+}}, <2 x bfloat> [[BC]] syncscope("agent") monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} +// CHECK: bitcast <2 x bfloat> [[RMW]] to <2 x i16> + // GFX12-LABEL: test_flat_add_2bf16 // GFX12: flat_atomic_pk_add_bf16 short2 test_flat_add_2bf16(__generic short2 *addr, short2 x) { @@ -64,7 +68,8 @@ short2 test_flat_add_2bf16(__generic short2 *addr, short2 x) { } // CHECK-LABEL: test_global_add_half2 -// CHECK: call <2 x half> @llvm.amdgcn.global.atomic.fadd.v2f16.p1.v2f16(ptr addrspace(1) %{{.*}}, <2 x half> %{{.*}}) +// CHECK: [[RMW:%.+]] = atomicrmw fadd ptr addrspace(1) %{{.+}}, <2 x half> %{{.+}} syncscope("agent") monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // GFX12-LABEL: test_global_add_half2 // GFX12: global_atomic_pk_add_f16 v2, v[0:1], v2, off th:TH_ATOMIC_RETURN void test_global_add_half2(__global half2 *addr, half2 x) { @@ -73,7 +78,8 @@ void test_global_add_half2(__global half2 *addr, half2 x) { } // CHECK-LABEL: test_global_add_half2_noret -// CHECK: call <2 x half> @llvm.amdgcn.global.atomic.fadd.v2f16.p1.v2f16(ptr addrspace(1) %{{.*}}, <2 x half> %{{.*}}) +// CHECK: [[RMW:%.+]] = atomicrmw fadd ptr addrspace(1) %{{.+}}, <2 x half> %{{.+}} syncscope("agent") monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // GFX12-LABEL: test_global_add_half2_noret // GFX12: global_atomic_pk_add_f16 v[0:1], v2, off void test_global_add_half2_noret(__global half2 *addr, half2 x) { @@ -81,7 +87,11 @@ void test_global_add_half2_noret(__global half2 *addr, half2 x) { } // CHECK-LABEL: test_global_add_2bf16 -// CHECK: call <2 x i16> @llvm.amdgcn.global.atomic.fadd.v2bf16.p1(ptr addrspace(1) %{{.*}}, <2 x i16> %{{.*}}) +// CHECK: [[BC:%.+]] = bitcast <2 x i16> %{{.+}} to <2 x bfloat> +// CHECK: [[RMW:%.+]] = atomicrmw fadd ptr addrspace(1) %{{.+}}, <2 x bfloat> [[BC]] syncscope("agent") monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} +// CHECK: bitcast <2 x bfloat> [[RMW]] to <2 x i16> + + // GFX12-LABEL: test_global_add_2bf16 // GFX12: global_atomic_pk_add_bf16 v2, v[0:1], v2, off th:TH_ATOMIC_RETURN void test_global_add_2bf16(__global short2 *addr, short2 x) { @@ -90,7 +100,10 @@ void test_global_add_2bf16(__global short2 *addr, short2 x) { } // CHECK-LABEL: test_global_add_2bf16_noret -// CHECK: call <2 x i16> @llvm.amdgcn.global.atomic.fadd.v2bf16.p1(ptr addrspace(1) %{{.*}}, <2 x i16> %{{.*}}) +// CHECK: [[BC:%.+]] = bitcast <2 x i16> %{{.+}} to <2 x bfloat> +// CHECK: [[RMW:%.+]] = atomicrmw fadd ptr addrspace(1) %{{.+}}, <2 x bfloat> [[BC]] syncscope("agent") monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} +// CHECK: bitcast <2 x bfloat> [[RMW]] to <2 x i16> + // GFX12-LABEL: test_global_add_2bf16_noret // GFX12: global_atomic_pk_add_bf16 v[0:1], v2, off void test_global_add_2bf16_noret(__global short2 *addr, short2 x) { diff --git a/clang/test/CodeGenOpenCL/builtins-fp-atomics-gfx90a.cl b/clang/test/CodeGenOpenCL/builtins-fp-atomics-gfx90a.cl index c525c250c937ca..556e553903d1a5 100644 --- a/clang/test/CodeGenOpenCL/builtins-fp-atomics-gfx90a.cl +++ b/clang/test/CodeGenOpenCL/builtins-fp-atomics-gfx90a.cl @@ -18,7 +18,7 @@ void test_global_add_f64(__global double *addr, double x) { } // CHECK-LABEL: test_global_add_half2 -// CHECK: call <2 x half> @llvm.amdgcn.global.atomic.fadd.v2f16.p1.v2f16(ptr addrspace(1) %{{.*}}, <2 x half> %{{.*}}) +// CHECK: = atomicrmw fadd ptr addrspace(1) %{{.+}}, <2 x half> %{{.+}} syncscope("agent") monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} // GFX90A-LABEL: test_global_add_half2 // GFX90A: global_atomic_pk_add_f16 v2, v[0:1], v2, off glc void test_global_add_half2(__global half2 *addr, half2 x) { @@ -27,7 +27,8 @@ void test_global_add_half2(__global half2 *addr, half2 x) { } // CHECK-LABEL: test_global_global_min_f64 -// CHECK: call double @llvm.amdgcn.global.atomic.fmin.f64.p1.f64(ptr addrspace(1) %{{.*}}, double %{{.*}}) +// CHECK: = atomicrmw fmin ptr addrspace(1) {{.+}}, double %{{.+}} syncscope("agent") monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // GFX90A-LABEL: test_global_global_min_f64$local // GFX90A: global_atomic_min_f64 void test_global_global_min_f64(__global double *addr, double x){ @@ -36,7 +37,8 @@ void test_global_global_min_f64(__global double *addr, double x){ } // CHECK-LABEL: test_global_max_f64 -// CHECK: call double @llvm.amdgcn.global.atomic.fmax.f64.p1.f64(ptr addrspace(1) %{{.*}}, double %{{.*}}) +// CHECK: = atomicrmw fmax ptr addrspace(1) {{.+}}, double %{{.+}} syncscope("agent") monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // GFX90A-LABEL: test_global_max_f64$local // GFX90A: global_atomic_max_f64 void test_global_max_f64(__global double *addr, double x){ @@ -45,7 +47,8 @@ void test_global_max_f64(__global double *addr, double x){ } // CHECK-LABEL: test_flat_add_local_f64 -// CHECK: call double @llvm.amdgcn.flat.atomic.fadd.f64.p3.f64(ptr addrspace(3) %{{.*}}, double %{{.*}}) +// CHECK: = atomicrmw fadd ptr addrspace(3) %{{.+}}, double %{{.+}} syncscope("agent") monotonic, align 8{{$}} + // GFX90A-LABEL: test_flat_add_local_f64$local // GFX90A: ds_add_rtn_f64 void test_flat_add_local_f64(__local double *addr, double x){ @@ -54,7 +57,8 @@ void test_flat_add_local_f64(__local double *addr, double x){ } // CHECK-LABEL: test_flat_global_add_f64 -// CHECK: call double @llvm.amdgcn.flat.atomic.fadd.f64.p1.f64(ptr addrspace(1) %{{.*}}, double %{{.*}}) +// CHECK: = atomicrmw fadd ptr addrspace(1) {{.+}}, double %{{.+}} syncscope("agent") monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // GFX90A-LABEL: test_flat_global_add_f64$local // GFX90A: global_atomic_add_f64 void test_flat_global_add_f64(__global double *addr, double x){ @@ -63,7 +67,8 @@ void test_flat_global_add_f64(__global double *addr, double x){ } // CHECK-LABEL: test_flat_min_flat_f64 -// CHECK: call double @llvm.amdgcn.flat.atomic.fmin.f64.p0.f64(ptr %{{.*}}, double %{{.*}}) +// CHECK: = atomicrmw fmin ptr {{.+}}, double %{{.+}} syncscope("agent") monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // GFX90A-LABEL: test_flat_min_flat_f64$local // GFX90A: flat_atomic_min_f64 void test_flat_min_flat_f64(__generic double *addr, double x){ @@ -72,7 +77,8 @@ void test_flat_min_flat_f64(__generic double *addr, double x){ } // CHECK-LABEL: test_flat_global_min_f64 -// CHECK: call double @llvm.amdgcn.flat.atomic.fmin.f64.p1.f64(ptr addrspace(1) %{{.*}}, double %{{.*}}) +// CHECK: = atomicrmw fmin ptr addrspace(1) {{.+}}, double %{{.+}} syncscope("agent") monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // GFX90A: test_flat_global_min_f64$local // GFX90A: global_atomic_min_f64 void test_flat_global_min_f64(__global double *addr, double x){ @@ -81,7 +87,8 @@ void test_flat_global_min_f64(__global double *addr, double x){ } // CHECK-LABEL: test_flat_max_flat_f64 -// CHECK: call double @llvm.amdgcn.flat.atomic.fmax.f64.p0.f64(ptr %{{.*}}, double %{{.*}}) +// CHECK: = atomicrmw fmax ptr {{.+}}, double %{{.+}} syncscope("agent") monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // GFX90A-LABEL: test_flat_max_flat_f64$local // GFX90A: flat_atomic_max_f64 void test_flat_max_flat_f64(__generic double *addr, double x){ @@ -90,7 +97,8 @@ void test_flat_max_flat_f64(__generic double *addr, double x){ } // CHECK-LABEL: test_flat_global_max_f64 -// CHECK: call double @llvm.amdgcn.flat.atomic.fmax.f64.p1.f64(ptr addrspace(1) %{{.*}}, double %{{.*}}) +// CHECK: = atomicrmw fmax ptr addrspace(1) {{.+}}, double %{{.+}} syncscope("agent") monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // GFX90A-LABEL: test_flat_global_max_f64$local // GFX90A: global_atomic_max_f64 void test_flat_global_max_f64(__global double *addr, double x){ diff --git a/clang/test/CodeGenOpenCL/builtins-fp-atomics-gfx940.cl b/clang/test/CodeGenOpenCL/builtins-fp-atomics-gfx940.cl index 5481138b9fee43..832d7df00db142 100644 --- a/clang/test/CodeGenOpenCL/builtins-fp-atomics-gfx940.cl +++ b/clang/test/CodeGenOpenCL/builtins-fp-atomics-gfx940.cl @@ -10,7 +10,8 @@ typedef half __attribute__((ext_vector_type(2))) half2; typedef short __attribute__((ext_vector_type(2))) short2; // CHECK-LABEL: test_flat_add_f32 -// CHECK: call float @llvm.amdgcn.flat.atomic.fadd.f32.p0.f32(ptr %{{.*}}, float %{{.*}}) +// CHECK: [[RMW:%.+]] = atomicrmw fadd ptr %{{.+}}, float %{{.+}} syncscope("agent") monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+}}, !amdgpu.ignore.denormal.mode !{{[0-9]+$}} + // GFX940-LABEL: test_flat_add_f32 // GFX940: flat_atomic_add_f32 half2 test_flat_add_f32(__generic float *addr, float x) { @@ -18,7 +19,8 @@ half2 test_flat_add_f32(__generic float *addr, float x) { } // CHECK-LABEL: test_flat_add_2f16 -// CHECK: call <2 x half> @llvm.amdgcn.flat.atomic.fadd.v2f16.p0.v2f16(ptr %{{.*}}, <2 x half> %{{.*}}) +// CHECK: [[RMW:%.+]] = atomicrmw fadd ptr %{{.+}}, <2 x half> %{{.+}} syncscope("agent") monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // GFX940-LABEL: test_flat_add_2f16 // GFX940: flat_atomic_pk_add_f16 half2 test_flat_add_2f16(__generic half2 *addr, half2 x) { @@ -26,7 +28,10 @@ half2 test_flat_add_2f16(__generic half2 *addr, half2 x) { } // CHECK-LABEL: test_flat_add_2bf16 -// CHECK: call <2 x i16> @llvm.amdgcn.flat.atomic.fadd.v2bf16.p0(ptr %{{.*}}, <2 x i16> %{{.*}}) +// CHECK: [[BC0:%.+]] = bitcast <2 x i16> {{.+}} to <2 x bfloat> +// CHECK: [[RMW:%.+]] = atomicrmw fadd ptr %{{.+}}, <2 x bfloat> [[BC0]] syncscope("agent") monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} +// CHECK-NEXT: bitcast <2 x bfloat> [[RMW]] to <2 x i16> + // GFX940-LABEL: test_flat_add_2bf16 // GFX940: flat_atomic_pk_add_bf16 short2 test_flat_add_2bf16(__generic short2 *addr, short2 x) { @@ -34,7 +39,10 @@ short2 test_flat_add_2bf16(__generic short2 *addr, short2 x) { } // CHECK-LABEL: test_global_add_2bf16 -// CHECK: call <2 x i16> @llvm.amdgcn.global.atomic.fadd.v2bf16.p1(ptr addrspace(1) %{{.*}}, <2 x i16> %{{.*}}) +// CHECK: [[BC0:%.+]] = bitcast <2 x i16> {{.+}} to <2 x bfloat> +// CHECK: [[RMW:%.+]] = atomicrmw fadd ptr addrspace(1) %{{.+}}, <2 x bfloat> [[BC0]] syncscope("agent") monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} +// CHECK-NEXT: bitcast <2 x bfloat> [[RMW]] to <2 x i16> + // GFX940-LABEL: test_global_add_2bf16 // GFX940: global_atomic_pk_add_bf16 short2 test_global_add_2bf16(__global short2 *addr, short2 x) { diff --git a/clang/test/Driver/Inputs/MacOSX15.1.sdk/SDKSettings.json b/clang/test/Driver/Inputs/MacOSX15.1.sdk/SDKSettings.json new file mode 100644 index 00000000000000..d46295b2ab5a17 --- /dev/null +++ b/clang/test/Driver/Inputs/MacOSX15.1.sdk/SDKSettings.json @@ -0,0 +1 @@ +{"Version":"15.1", "MaximumDeploymentTarget": "15.1.99"} diff --git a/clang/test/Driver/darwin-builtin-modules.c b/clang/test/Driver/darwin-builtin-modules.c index ec515133be8aba..4564d7317d7abe 100644 --- a/clang/test/Driver/darwin-builtin-modules.c +++ b/clang/test/Driver/darwin-builtin-modules.c @@ -8,5 +8,8 @@ // RUN: %clang -isysroot %S/Inputs/MacOSX15.0.sdk -target x86_64-apple-macos14.0 -### %s 2>&1 | FileCheck --check-prefix=CHECK_FUTURE %s // RUN: %clang -isysroot %S/Inputs/MacOSX15.0.sdk -target x86_64-apple-macos15.0 -### %s 2>&1 | FileCheck --check-prefix=CHECK_FUTURE %s +// RUN: %clang -isysroot %S/Inputs/MacOSX15.0.sdk -target x86_64-apple-ios18.0-macabi -### %s 2>&1 | FileCheck --check-prefix=CHECK_FUTURE %s +// RUN: %clang -isysroot %S/Inputs/MacOSX15.1.sdk -target x86_64-apple-macos15.1 -darwin-target-variant x86_64-apple-ios18.1-macabi -### %s 2>&1 | FileCheck --check-prefix=CHECK_FUTURE %s +// RUN: %clang -isysroot %S/Inputs/MacOSX15.1.sdk -target x86_64-apple-ios18.1-macabi -darwin-target-variant x86_64-apple-macos15.1 -### %s 2>&1 | FileCheck --check-prefix=CHECK_FUTURE %s // RUN: %clang -isysroot %S/Inputs/DriverKit23.0.sdk -target arm64-apple-driverkit23.0 -### %s 2>&1 | FileCheck --check-prefix=CHECK_FUTURE %s // CHECK_FUTURE-NOT: -fbuiltin-headers-in-system-modules diff --git a/clang/test/Driver/fp-model.c b/clang/test/Driver/fp-model.c index 2348d4b41f43ab..6f17d4aeb1ef57 100644 --- a/clang/test/Driver/fp-model.c +++ b/clang/test/Driver/fp-model.c @@ -2,13 +2,17 @@ // and other floating point options get a warning diagnostic. // -// RUN: %clang -### -ffp-model=fast -ffp-contract=off -c %s 2>&1 \ +// RUN: %clang -### -ffp-model=aggressive -ffp-contract=off -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=WARN %s -// WARN: warning: overriding '-ffp-model=fast' option with '-ffp-contract=off' [-Woverriding-option] +// WARN: warning: overriding '-ffp-model=aggressive' option with '-ffp-contract=off' [-Woverriding-option] + +// RUN: %clang -### -ffp-model=fast -ffp-contract=off -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=WARN0 %s +// WARN0: warning: overriding '-ffp-model=fast' option with '-ffp-contract=off' [-Woverriding-option] -// RUN: %clang -### -ffp-model=fast -ffp-contract=on -c %s 2>&1 \ +// RUN: %clang -### -ffp-model=aggressive -ffp-contract=on -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=WARN1 %s -// WARN1: warning: overriding '-ffp-model=fast' option with '-ffp-contract=on' [-Woverriding-option] +// WARN1: warning: overriding '-ffp-model=aggressive' option with '-ffp-contract=on' [-Woverriding-option] // RUN: %clang -### -ffp-model=strict -fassociative-math -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=WARN2 %s @@ -74,9 +78,12 @@ // RUN: %clang -### -Ofast -ffp-model=strict -c %s 2>&1 | FileCheck \ // RUN: --check-prefix=WARN12 %s -// RUN: %clang -### -Werror -ffast-math -ffp-model=strict -c %s // WARN12: warning: overriding '-ffp-model=strict' option with '-Ofast' +// RUN: %clang -### -ffast-math -ffp-model=strict -c %s 2>&1 | FileCheck \ +// RUN: --check-prefix=WARN-CX-BASIC-TO-FULL %s +// WARN-CX-BASIC-TO-FULL: warning: overriding '-fcomplex-arithmetic=basic' option with '-fcomplex-arithmetic=full' + // RUN: %clang -### -ffp-model=strict -fapprox-func -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=WARN13 %s // WARN13: warning: overriding '-ffp-model=strict' option with '-fapprox-func' [-Woverriding-option] @@ -97,44 +104,61 @@ // RUN: %clang -### -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOROUND %s // CHECK-NOROUND: "-cc1" -// CHECK-NOROUND: "-fno-rounding-math" +// CHECK-NOROUND-SAME: "-fno-rounding-math" // RUN: %clang -### -frounding-math -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-ROUND --implicit-check-not ffp-exception-behavior=strict %s // CHECK-ROUND: "-cc1" -// CHECK-ROUND: "-frounding-math" +// CHECK-ROUND-SAME: "-frounding-math" // RUN: %clang -### -ftrapping-math -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-TRAP %s // CHECK-TRAP: "-cc1" -// CHECK-TRAP: "-ffp-exception-behavior=strict" +// CHECK-TRAP-SAME: "-ffp-exception-behavior=strict" + +// RUN: %clang -### -nostdinc -ffp-model=aggressive -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-FPM-AGGR %s +// CHECK-FPM-AGGR: "-cc1" +// CHECK-FPM-AGGR-SAME: "-menable-no-infs" +// CHECK-FPM-AGGR-SAME: "-menable-no-nans" +// CHECK-FPM-AGGR-SAME: "-fapprox-func" +// CHECK-FPM-AGGR-SAME: "-funsafe-math-optimizations" +// CHECK-FPM-AGGR-SAME: "-fno-signed-zeros" +// CHECK-FPM-AGGR-SAME: "-mreassociate" +// CHECK-FPM-AGGR-SAME: "-freciprocal-math" +// CHECK-FPM-AGGR-SAME: "-ffp-contract=fast" +// CHECK-FPM-AGGR-SAME: "-fno-rounding-math" +// CHECK-FPM-AGGR-SAME: "-ffast-math" +// CHECK-FPM-AGGR-SAME: "-ffinite-math-only" +// CHECK-FPM-AGGR-SAME: "-complex-range=basic" // RUN: %clang -### -nostdinc -ffp-model=fast -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FPM-FAST %s // CHECK-FPM-FAST: "-cc1" -// CHECK-FPM-FAST: "-menable-no-infs" -// CHECK-FPM-FAST: "-menable-no-nans" -// CHECK-FPM-FAST: "-fapprox-func" -// CHECK-FPM-FAST: "-funsafe-math-optimizations" -// CHECK-FPM-FAST: "-fno-signed-zeros" -// CHECK-FPM-FAST: "-mreassociate" -// CHECK-FPM-FAST: "-freciprocal-math" -// CHECK-FPM-FAST: "-ffp-contract=fast" -// CHECK-FPM-FAST: "-fno-rounding-math" -// CHECK-FPM-FAST: "-ffast-math" -// CHECK-FPM-FAST: "-ffinite-math-only" +// CHECK-FPM-FAST-NOT: "-menable-no-infs" +// CHECK-FPM-FAST-NOT: "-menable-no-nans" +// CHECK-FPM-FAST-SAME: "-fapprox-func" +// CHECK-FPM-FAST-SAME: "-funsafe-math-optimizations" +// CHECK-FPM-FAST-SAME: "-fno-signed-zeros" +// CHECK-FPM-FAST-SAME: "-mreassociate" +// CHECK-FPM-FAST-SAME: "-freciprocal-math" +// CHECK-FPM-FAST-SAME: "-ffp-contract=fast" +// CHECK-FPM-FAST-SAME: "-fno-rounding-math" +// CHECK-FPM-FAST-NOT: "-ffast-math" +// CHECK-FPM-FAST-NOT: "-ffinite-math-only" +// CHECK-FPM-FAST-SAME: "-complex-range=promoted" // RUN: %clang -### -nostdinc -ffp-model=precise -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FPM-PRECISE %s // CHECK-FPM-PRECISE: "-cc1" -// CHECK-FPM-PRECISE: "-ffp-contract=on" -// CHECK-FPM-PRECISE: "-fno-rounding-math" +// CHECK-FPM-PRECISE-SAME: "-ffp-contract=on" +// CHECK-FPM-PRECISE-SAME: "-fno-rounding-math" // RUN: %clang -### -nostdinc -ffp-model=strict -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FPM-STRICT %s // CHECK-FPM-STRICT: "-cc1" -// CHECK-FPM-STRICT: "-frounding-math" -// CHECK-FPM-STRICT: "-ffp-exception-behavior=strict" +// CHECK-FPM-STRICT-SAME: "-frounding-math" +// CHECK-FPM-STRICT-SAME: "-ffp-exception-behavior=strict" // RUN: %clang -### -nostdinc -ffp-model=strict -ffp-model=fast -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NO-EXCEPT %s @@ -148,14 +172,14 @@ // RUN: %clang -### -nostdinc -ffp-exception-behavior=strict -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FEB-STRICT %s // CHECK-FEB-STRICT: "-cc1" -// CHECK-FEB-STRICT: "-fno-rounding-math" -// CHECK-FEB-STRICT: "-ffp-exception-behavior=strict" +// CHECK-FEB-STRICT-SAME: "-fno-rounding-math" +// CHECK-FEB-STRICT-SAME: "-ffp-exception-behavior=strict" // RUN: %clang -### -nostdinc -ffp-exception-behavior=maytrap -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FEB-MAYTRAP %s // CHECK-FEB-MAYTRAP: "-cc1" -// CHECK-FEB-MAYTRAP: "-fno-rounding-math" -// CHECK-FEB-MAYTRAP: "-ffp-exception-behavior=maytrap" +// CHECK-FEB-MAYTRAP-SAME: "-fno-rounding-math" +// CHECK-FEB-MAYTRAP-SAME: "-ffp-exception-behavior=maytrap" // RUN: %clang -### -nostdinc -ffp-exception-behavior=ignore -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FEB-IGNORE %s @@ -163,23 +187,41 @@ // CHECK-FEB-IGNORE: "-fno-rounding-math" // CHECK-FEB-IGNORE: "-ffp-exception-behavior=ignore" -// RUN: %clang -### -nostdinc -Werror -ffast-math -ffp-model=fast -c %s 2>&1 \ +// RUN: %clang -### -nostdinc -Werror -ffast-math -ffp-model=aggressive -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-FASTMATH-FPM-AGGR %s +// CHECK-FASTMATH-FPM-AGGR: "-cc1" +// CHECK-FASTMATH-FPM-AGGR-SAME: "-menable-no-infs" +// CHECK-FASTMATH-FPM-AGGR-SAME: "-menable-no-nans" +// CHECK-FASTMATH-FPM-AGGR-SAME: "-fapprox-func" +// CHECK-FASTMATH-FPM-AGGR-SAME: "-funsafe-math-optimizations" +// CHECK-FASTMATH-FPM-AGGR-SAME: "-fno-signed-zeros" +// CHECK-FASTMATH-FPM-AGGR-SAME: "-mreassociate" +// CHECK-FASTMATH-FPM-AGGR-SAME: "-freciprocal-math" +// CHECK-FASTMATH-FPM-AGGR-SAME: "-ffp-contract=fast" +// CHECK-FASTMATH-FPM-AGGR-SAME: "-fno-rounding-math" +// CHECK-FASTMATH-FPM-AGGR-SAME: "-ffast-math" +// CHECK-FASTMATH-FPM-AGGR-SAME: "-ffinite-math-only" +// CHECK-FASTMATH-FPM-AGGR-SAME: "-complex-range=basic" + +// RUN: %clang -### -nostdinc -ffast-math -ffp-model=fast -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FASTMATH-FPM-FAST %s +// CHECK-FASTMATH-FPM-FAST: warning: overriding '-fcomplex-arithmetic=basic' option with '-fcomplex-arithmetic=promoted' // CHECK-FASTMATH-FPM-FAST: "-cc1" -// CHECK-FASTMATH-FPM-FAST: "-menable-no-infs" -// CHECK-FASTMATH-FPM-FAST: "-menable-no-nans" -// CHECK-FASTMATH-FPM-FAST: "-fapprox-func" -// CHECK-FASTMATH-FPM-FAST: "-funsafe-math-optimizations" -// CHECK-FASTMATH-FPM-FAST: "-fno-signed-zeros" -// CHECK-FASTMATH-FPM-FAST: "-mreassociate" -// CHECK-FASTMATH-FPM-FAST: "-freciprocal-math" -// CHECK-FASTMATH-FPM-FAST: "-ffp-contract=fast" -// CHECK-FASTMATH-FPM-FAST: "-fno-rounding-math" -// CHECK-FASTMATH-FPM-FAST: "-ffast-math" -// CHECK-FASTMATH-FPM-FAST: "-ffinite-math-only" - -// RUN: %clang -### -nostdinc -Werror -ffast-math -ffp-model=precise -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=CHECK-FASTMATH-FPM-PRECISE %s +// CHECK-FASTMATH-FPM-FAST-NOT: "-menable-no-infs" +// CHECK-FASTMATH-FPM-FAST-NOT: "-menable-no-nans" +// CHECK-FASTMATH-FPM-FAST-SAME: "-fapprox-func" +// CHECK-FASTMATH-FPM-FAST-SAME: "-funsafe-math-optimizations" +// CHECK-FASTMATH-FPM-FAST-SAME: "-fno-signed-zeros" +// CHECK-FASTMATH-FPM-FAST-SAME: "-mreassociate" +// CHECK-FASTMATH-FPM-FAST-SAME: "-freciprocal-math" +// CHECK-FASTMATH-FPM-FAST-SAME: "-ffp-contract=fast" +// CHECK-FASTMATH-FPM-FAST-SAME: "-fno-rounding-math" +// CHECK-FASTMATH-FPM-FAST-NOT: "-ffast-math" +// CHECK-FASTMATH-FPM-FAST-NOT: "-ffinite-math-only" +// CHECK-FASTMATH-FPM-FAST-SAME: "-complex-range=promoted" + +// RUN: %clang -### -nostdinc -ffast-math -ffp-model=precise -c %s 2>&1 \ +// RUN: | FileCheck --check-prefixes=CHECK-FASTMATH-FPM-PRECISE,WARN-CX-BASIC-TO-FULL %s // CHECK-FASTMATH-FPM-PRECISE: "-cc1" // CHECK-FASTMATH-FPM-PRECISE-NOT: "-menable-no-infs" // CHECK-FASTMATH-FPM-PRECISE-NOT: "-menable-no-nans" @@ -188,13 +230,14 @@ // CHECK-FASTMATH-FPM-PRECISE-NOT: "-fno-signed-zeros" // CHECK-FASTMATH-FPM-PRECISE-NOT: "-mreassociate" // CHECK-FASTMATH-FPM-PRECISE-NOT: "-freciprocal-math" -// CHECK-FASTMATH-FPM-PRECISE: "-ffp-contract=on" -// CHECK-FASTMATH-FPM-PRECISE: "-fno-rounding-math" +// CHECK-FASTMATH-FPM-PRECISE-SAME: "-ffp-contract=on" +// CHECK-FASTMATH-FPM-PRECISE-SAME: "-fno-rounding-math" // CHECK-FASTMATH-FPM-PRECISE-NOT: "-ffast-math" // CHECK-FASTMATH-FPM-PRECISE-NOT: "-ffinite-math-only" +// CHECK-FASTMATH-FPM-PRECISE-SAME: "-complex-range=full" -// RUN: %clang -### -nostdinc -Werror -ffast-math -ffp-model=strict -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=CHECK-FASTMATH-FPM-STRICT %s +// RUN: %clang -### -nostdinc -ffast-math -ffp-model=strict -c %s 2>&1 \ +// RUN: | FileCheck --check-prefixes=CHECK-FASTMATH-FPM-STRICT,WARN-CX-BASIC-TO-FULL %s // CHECK-FASTMATH-FPM-STRICT: "-cc1" // CHECK-FASTMATH-FPM-STRICT-NOT: "-menable-no-infs" // CHECK-FASTMATH-FPM-STRICT-NOT: "-menable-no-nans" @@ -203,7 +246,8 @@ // CHECK-FASTMATH-FPM-STRICT-NOT: "-fno-signed-zeros" // CHECK-FASTMATH-FPM-STRICT-NOT: "-mreassociate" // CHECK-FASTMATH-FPM-STRICT-NOT: "-freciprocal-math" -// CHECK-FASTMATH-FPM-STRICT: "-ffp-contract=off" +// CHECK-FASTMATH-FPM-STRICT-SAME: "-ffp-contract=off" // CHECK-FASTMATH-FPM-STRICT-NOT: "-fno-rounding-math" // CHECK-FASTMATH-FPM-STRICT-NOT: "-ffast-math" // CHECK-FASTMATH-FPM-STRICT-NOT: "-ffinite-math-only" +// CHECK-FASTMATH-FPM-STRICT-SAME: "-complex-range=full" diff --git a/clang/test/Driver/mips-msa.c b/clang/test/Driver/mips-msa.c new file mode 100644 index 00000000000000..28b5012da336cc --- /dev/null +++ b/clang/test/Driver/mips-msa.c @@ -0,0 +1,12 @@ +// RUN: %clang -### -c --target=mips64el-unknown-linux-gnuabi64 \ +// RUN: -Wa,-mmsa %s -Werror 2>&1 | FileCheck %s --check-prefix=CHECK-MMSA +// CHECK-MMSA: "-cc1" {{.*}}"-mmsa" + +// RUN: %clang -### -c --target=mips64el-unknown-linux-gnuabi64 \ +// RUN: -Wa,-mmsa,-mno-msa %s -Werror 2>&1 | FileCheck %s --check-prefix=CHECK-NOMMSA +// CHECK-NOMMSA: "-cc1" +// CHECK-NOMMSA-NOT: "-mssa" + +// RUN: not %clang -### -c --target=x86_64 -Wa,-mmsa -Wa,-mno-msa %s 2>&1 | FileCheck %s --check-prefix=ERR +// ERR: error: unsupported argument '-mmsa' to option '-Wa,' +// ERR: error: unsupported argument '-mno-msa' to option '-Wa,' diff --git a/clang/test/ExtractAPI/anonymous_record_no_typedef.c b/clang/test/ExtractAPI/anonymous_record_no_typedef.c index 789316ca8930b8..064c223ad56e73 100644 --- a/clang/test/ExtractAPI/anonymous_record_no_typedef.c +++ b/clang/test/ExtractAPI/anonymous_record_no_typedef.c @@ -163,4 +163,16 @@ enum { // GLOBALOTHERCASE-NEXT: "GlobalOtherCase" // GLOBALOTHERCASE-NEXT: ] +// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix VEC +union Vector { + struct { + float X; + float Y; + }; + float Data[2]; +}; +// VEC-DAG: "!testRelLabel": "memberOf $ c:@U@Vector@FI@Data $ c:@U@Vector" +// VEC-DAG: "!testRelLabel": "memberOf $ c:@U@Vector@Sa@FI@X $ c:@U@Vector" +// VEC-DAG: "!testRelLabel": "memberOf $ c:@U@Vector@Sa@FI@Y $ c:@U@Vector" + // expected-no-diagnostics diff --git a/clang/test/Misc/target-invalid-cpu-note.c b/clang/test/Misc/target-invalid-cpu-note.c deleted file mode 100644 index b1783f3917a350..00000000000000 --- a/clang/test/Misc/target-invalid-cpu-note.c +++ /dev/null @@ -1,96 +0,0 @@ -// Use CHECK-NEXT instead of multiple CHECK-SAME to ensure we will fail if there is anything extra in the output. -// RUN: not %clang_cc1 -triple armv5--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix ARM -// ARM: error: unknown target CPU 'not-a-cpu' -// ARM-NEXT: note: valid target CPU values are: arm8, arm810, strongarm, strongarm110, strongarm1100, strongarm1110, arm7tdmi, arm7tdmi-s, arm710t, arm720t, arm9, arm9tdmi, arm920, arm920t, arm922t, arm940t, ep9312, arm10tdmi, arm1020t, arm9e, arm946e-s, arm966e-s, arm968e-s, arm10e, arm1020e, arm1022e, arm926ej-s, arm1136j-s, arm1136jf-s, mpcore, mpcorenovfp, arm1176jz-s, arm1176jzf-s, arm1156t2-s, arm1156t2f-s, cortex-m0, cortex-m0plus, cortex-m1, sc000, cortex-a5, cortex-a7, cortex-a8, cortex-a9, cortex-a12, cortex-a15, cortex-a17, krait, cortex-r4, cortex-r4f, cortex-r5, cortex-r7, cortex-r8, cortex-r52, cortex-r52plus, sc300, cortex-m3, cortex-m4, cortex-m7, cortex-m23, cortex-m33, cortex-m35p, cortex-m55, cortex-m85, cortex-m52, cortex-a32, cortex-a35, cortex-a53, cortex-a55, cortex-a57, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-a710, cortex-x1, cortex-x1c, neoverse-n1, neoverse-n2, neoverse-v1, cyclone, exynos-m3, exynos-m4, exynos-m5, kryo, iwmmxt, xscale, swift{{$}} - -// RUN: not %clang_cc1 -triple arm64--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix AARCH64 -// AARCH64: error: unknown target CPU 'not-a-cpu' -// AARCH64-NEXT: note: valid target CPU values are: a64fx, ampere1, ampere1a, ampere1b, apple-a10, apple-a11, apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-a7, apple-a8, apple-a9, apple-m1, apple-m2, apple-m3, apple-m4, apple-s4, apple-s5, carmel, cobalt-100, cortex-a34, cortex-a35, cortex-a510, cortex-a520, cortex-a520ae, cortex-a53, cortex-a55, cortex-a57, cortex-a65, cortex-a65ae, cortex-a710, cortex-a715, cortex-a72, cortex-a720, cortex-a720ae, cortex-a725, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-r82, cortex-r82ae, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, cortex-x925, cyclone, exynos-m3, exynos-m4, exynos-m5, falkor, generic, grace, kryo, neoverse-512tvb, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-n3, neoverse-v1, neoverse-v2, neoverse-v3, neoverse-v3ae, oryon-1, saphira, thunderx, thunderx2t99, thunderx3t110, thunderxt81, thunderxt83, thunderxt88, tsv110{{$}} - -// RUN: not %clang_cc1 -triple arm64--- -tune-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix TUNE_AARCH64 -// TUNE_AARCH64: error: unknown target CPU 'not-a-cpu' -// TUNE_AARCH64-NEXT: note: valid target CPU values are: a64fx, ampere1, ampere1a, ampere1b, apple-a10, apple-a11, apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-a7, apple-a8, apple-a9, apple-m1, apple-m2, apple-m3, apple-m4, apple-s4, apple-s5, carmel, cobalt-100, cortex-a34, cortex-a35, cortex-a510, cortex-a520, cortex-a520ae, cortex-a53, cortex-a55, cortex-a57, cortex-a65, cortex-a65ae, cortex-a710, cortex-a715, cortex-a72, cortex-a720, cortex-a720ae, cortex-a725, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-r82, cortex-r82ae, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, cortex-x925, cyclone, exynos-m3, exynos-m4, exynos-m5, falkor, generic, grace, kryo, neoverse-512tvb, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-n3, neoverse-v1, neoverse-v2, neoverse-v3, neoverse-v3ae, oryon-1, saphira, thunderx, thunderx2t99, thunderx3t110, thunderxt81, thunderxt83, thunderxt88, tsv110{{$}} - -// RUN: not %clang_cc1 -triple i386--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix X86 -// X86: error: unknown target CPU 'not-a-cpu' -// X86-NEXT: note: valid target CPU values are: i386, i486, winchip-c6, winchip2, c3, i586, pentium, pentium-mmx, pentiumpro, i686, pentium2, pentium3, pentium3m, pentium-m, c3-2, yonah, pentium4, pentium4m, prescott, nocona, core2, penryn, bonnell, atom, silvermont, slm, goldmont, goldmont-plus, tremont, nehalem, corei7, westmere, sandybridge, corei7-avx, ivybridge, core-avx-i, haswell, core-avx2, broadwell, skylake, skylake-avx512, skx, cascadelake, cooperlake, cannonlake, icelake-client, rocketlake, icelake-server, tigerlake, sapphirerapids, alderlake, raptorlake, meteorlake, arrowlake, arrowlake-s, lunarlake, gracemont, pantherlake, sierraforest, grandridge, graniterapids, graniterapids-d, emeraldrapids, clearwaterforest, knl, knm, lakemont, k6, k6-2, k6-3, athlon, athlon-tbird, athlon-xp, athlon-mp, athlon-4, k8, athlon64, athlon-fx, opteron, k8-sse3, athlon64-sse3, opteron-sse3, amdfam10, barcelona, btver1, btver2, bdver1, bdver2, bdver3, bdver4, znver1, znver2, znver3, znver4, x86-64, x86-64-v2, x86-64-v3, x86-64-v4, geode{{$}} - -// RUN: not %clang_cc1 -triple x86_64--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix X86_64 -// X86_64: error: unknown target CPU 'not-a-cpu' -// X86_64-NEXT: note: valid target CPU values are: nocona, core2, penryn, bonnell, atom, silvermont, slm, goldmont, goldmont-plus, tremont, nehalem, corei7, westmere, sandybridge, corei7-avx, ivybridge, core-avx-i, haswell, core-avx2, broadwell, skylake, skylake-avx512, skx, cascadelake, cooperlake, cannonlake, icelake-client, rocketlake, icelake-server, tigerlake, sapphirerapids, alderlake, raptorlake, meteorlake, arrowlake, arrowlake-s, lunarlake, gracemont, pantherlake, sierraforest, grandridge, graniterapids, graniterapids-d, emeraldrapids, clearwaterforest, knl, knm, k8, athlon64, athlon-fx, opteron, k8-sse3, athlon64-sse3, opteron-sse3, amdfam10, barcelona, btver1, btver2, bdver1, bdver2, bdver3, bdver4, znver1, znver2, znver3, znver4, x86-64, x86-64-v2, x86-64-v3, x86-64-v4{{$}} - -// RUN: not %clang_cc1 -triple i386--- -tune-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix TUNE_X86 -// TUNE_X86: error: unknown target CPU 'not-a-cpu' -// TUNE_X86-NEXT: note: valid target CPU values are: i386, i486, winchip-c6, winchip2, c3, i586, pentium, pentium-mmx, pentiumpro, i686, pentium2, pentium3, pentium3m, pentium-m, c3-2, yonah, pentium4, pentium4m, prescott, nocona, core2, penryn, bonnell, atom, silvermont, slm, goldmont, goldmont-plus, tremont, nehalem, corei7, westmere, sandybridge, corei7-avx, ivybridge, core-avx-i, haswell, core-avx2, broadwell, skylake, skylake-avx512, skx, cascadelake, cooperlake, cannonlake, icelake-client, rocketlake, icelake-server, tigerlake, sapphirerapids, alderlake, raptorlake, meteorlake, arrowlake, arrowlake-s, lunarlake, gracemont, pantherlake, sierraforest, grandridge, graniterapids, graniterapids-d, emeraldrapids, clearwaterforest, knl, knm, lakemont, k6, k6-2, k6-3, athlon, athlon-tbird, athlon-xp, athlon-mp, athlon-4, k8, athlon64, athlon-fx, opteron, k8-sse3, athlon64-sse3, opteron-sse3, amdfam10, barcelona, btver1, btver2, bdver1, bdver2, bdver3, bdver4, znver1, znver2, znver3, znver4, x86-64, geode{{$}} - -// RUN: not %clang_cc1 -triple x86_64--- -tune-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix TUNE_X86_64 -// TUNE_X86_64: error: unknown target CPU 'not-a-cpu' -// TUNE_X86_64-NEXT: note: valid target CPU values are: i386, i486, winchip-c6, winchip2, c3, i586, pentium, pentium-mmx, pentiumpro, i686, pentium2, pentium3, pentium3m, pentium-m, c3-2, yonah, pentium4, pentium4m, prescott, nocona, core2, penryn, bonnell, atom, silvermont, slm, goldmont, goldmont-plus, tremont, nehalem, corei7, westmere, sandybridge, corei7-avx, ivybridge, core-avx-i, haswell, core-avx2, broadwell, skylake, skylake-avx512, skx, cascadelake, cooperlake, cannonlake, icelake-client, rocketlake, icelake-server, tigerlake, sapphirerapids, alderlake, raptorlake, meteorlake, arrowlake, arrowlake-s, lunarlake, gracemont, pantherlake, sierraforest, grandridge, graniterapids, graniterapids-d, emeraldrapids, clearwaterforest, knl, knm, lakemont, k6, k6-2, k6-3, athlon, athlon-tbird, athlon-xp, athlon-mp, athlon-4, k8, athlon64, athlon-fx, opteron, k8-sse3, athlon64-sse3, opteron-sse3, amdfam10, barcelona, btver1, btver2, bdver1, bdver2, bdver3, bdver4, znver1, znver2, znver3, znver4, x86-64, geode{{$}} - -// RUN: not %clang_cc1 -triple nvptx--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix NVPTX -// NVPTX: error: unknown target CPU 'not-a-cpu' -// NVPTX-NEXT: note: valid target CPU values are: sm_20, sm_21, sm_30, sm_32, sm_35, sm_37, sm_50, sm_52, sm_53, sm_60, sm_61, sm_62, sm_70, sm_72, sm_75, sm_80, sm_86, sm_87, sm_89, sm_90, sm_90a, gfx600, gfx601, gfx602, gfx700, gfx701, gfx702, gfx703, gfx704, gfx705, gfx801, gfx802, gfx803, gfx805, gfx810, gfx9-generic, gfx900, gfx902, gfx904, gfx906, gfx908, gfx909, gfx90a, gfx90c, gfx940, gfx941, gfx942, gfx10-1-generic, gfx1010, gfx1011, gfx1012, gfx1013, gfx10-3-generic, gfx1030, gfx1031, gfx1032, gfx1033, gfx1034, gfx1035, gfx1036, gfx11-generic, gfx1100, gfx1101, gfx1102, gfx1103, gfx1150, gfx1151, gfx1152, gfx12-generic, gfx1200, gfx1201, amdgcnspirv{{$}} - -// RUN: not %clang_cc1 -triple r600--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix R600 -// R600: error: unknown target CPU 'not-a-cpu' -// R600-NEXT: note: valid target CPU values are: r600, rv630, rv635, r630, rs780, rs880, rv610, rv620, rv670, rv710, rv730, rv740, rv770, cedar, palm, cypress, hemlock, juniper, redwood, sumo, sumo2, barts, caicos, aruba, cayman, turks{{$}} - -// RUN: not %clang_cc1 -triple amdgcn--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix AMDGCN -// AMDGCN: error: unknown target CPU 'not-a-cpu' -// AMDGCN-NEXT: note: valid target CPU values are: gfx600, tahiti, gfx601, pitcairn, verde, gfx602, hainan, oland, gfx700, kaveri, gfx701, hawaii, gfx702, gfx703, kabini, mullins, gfx704, bonaire, gfx705, gfx801, carrizo, gfx802, iceland, tonga, gfx803, fiji, polaris10, polaris11, gfx805, tongapro, gfx810, stoney, gfx900, gfx902, gfx904, gfx906, gfx908, gfx909, gfx90a, gfx90c, gfx940, gfx941, gfx942, gfx1010, gfx1011, gfx1012, gfx1013, gfx1030, gfx1031, gfx1032, gfx1033, gfx1034, gfx1035, gfx1036, gfx1100, gfx1101, gfx1102, gfx1103, gfx1150, gfx1151, gfx1152, gfx1200, gfx1201, gfx9-generic, gfx10-1-generic, gfx10-3-generic, gfx11-generic, gfx12-generic{{$}} - -// RUN: not %clang_cc1 -triple wasm64--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix WEBASM -// WEBASM: error: unknown target CPU 'not-a-cpu' -// WEBASM-NEXT: note: valid target CPU values are: mvp, bleeding-edge, generic{{$}} - -// RUN: not %clang_cc1 -triple systemz--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix SYSTEMZ -// SYSTEMZ: error: unknown target CPU 'not-a-cpu' -// SYSTEMZ-NEXT: note: valid target CPU values are: arch8, z10, arch9, z196, arch10, zEC12, arch11, z13, arch12, z14, arch13, z15, arch14, z16{{$}} - -// RUN: not %clang_cc1 -triple sparc--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix SPARC -// SPARC: error: unknown target CPU 'not-a-cpu' -// SPARC-NEXT: note: valid target CPU values are: v8, supersparc, sparclite, f934, hypersparc, sparclite86x, sparclet, tsc701, v9, ultrasparc, ultrasparc3, niagara, niagara2, niagara3, niagara4, ma2100, ma2150, ma2155, ma2450, ma2455, ma2x5x, ma2080, ma2085, ma2480, ma2485, ma2x8x, leon2, at697e, at697f, leon3, ut699, gr712rc, leon4, gr740{{$}} - -// RUN: not %clang_cc1 -triple sparcv9--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix SPARCV9 -// SPARCV9: error: unknown target CPU 'not-a-cpu' -// SPARCV9-NEXT: note: valid target CPU values are: v9, ultrasparc, ultrasparc3, niagara, niagara2, niagara3, niagara4{{$}} - -// RUN: not %clang_cc1 -triple powerpc--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix PPC -// PPC: error: unknown target CPU 'not-a-cpu' -// PPC-NEXT: note: valid target CPU values are: generic, 440, 440fp, ppc440, 450, 601, 602, 603, 603e, 603ev, 604, 604e, 620, 630, g3, 7400, g4, 7450, g4+, 750, 8548, ppc405, ppc464, ppc476, 970, ppc970, g5, a2, ppca2, ppc-cell-be, e500, e500mc, e5500, power3, pwr3, pwr4, power4, pwr5, power5, pwr5+, power5+, pwr5x, power5x, pwr6, power6, pwr6x, power6x, pwr7, power7, pwr8, power8, pwr9, power9, pwr10, power10, pwr11, power11, powerpc, ppc, ppc32, powerpc64, ppc64, powerpc64le, ppc64le, future{{$}} - -// RUN: not %clang_cc1 -triple mips--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix MIPS -// MIPS: error: unknown target CPU 'not-a-cpu' -// MIPS-NEXT: note: valid target CPU values are: mips1, mips2, mips3, mips4, mips5, mips32, mips32r2, mips32r3, mips32r5, mips32r6, mips64, mips64r2, mips64r3, mips64r5, mips64r6, octeon, octeon+, p5600{{$}} - -// RUN: not %clang_cc1 -triple lanai--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix LANAI -// LANAI: error: unknown target CPU 'not-a-cpu' -// LANAI-NEXT: note: valid target CPU values are: v11{{$}} - -// RUN: not %clang_cc1 -triple hexagon--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix HEXAGON -// HEXAGON: error: unknown target CPU 'not-a-cpu' -// HEXAGON-NEXT: note: valid target CPU values are: hexagonv5, hexagonv55, hexagonv60, hexagonv62, hexagonv65, hexagonv66, hexagonv67, hexagonv67t, hexagonv68, hexagonv69, hexagonv71, hexagonv71t, hexagonv73{{$}} - -// RUN: not %clang_cc1 -triple bpf--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix BPF -// BPF: error: unknown target CPU 'not-a-cpu' -// BPF-NEXT: note: valid target CPU values are: generic, v1, v2, v3, v4, probe{{$}} - -// RUN: not %clang_cc1 -triple avr--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix AVR -// AVR: error: unknown target CPU 'not-a-cpu' -// AVR-NEXT: note: valid target CPU values are: avr1, at90s1200, attiny11, attiny12, attiny15, attiny28, avr2, at90s2313, at90s2323, at90s2333, at90s2343, attiny22, attiny26, at86rf401, at90s4414, at90s4433, at90s4434, at90s8515, at90c8534, at90s8535, avr25, ata5272, ata6616c, attiny13, attiny13a, attiny2313, attiny2313a, attiny24, attiny24a, attiny4313, attiny44, attiny44a, attiny84, attiny84a, attiny25, attiny45, attiny85, attiny261, attiny261a, attiny441, attiny461, attiny461a, attiny841, attiny861, attiny861a, attiny87, attiny43u, attiny48, attiny88, attiny828, avr3, at43usb355, at76c711, avr31, atmega103, at43usb320, avr35, attiny167, at90usb82, at90usb162, ata5505, ata6617c, ata664251, atmega8u2, atmega16u2, atmega32u2, attiny1634, avr4, atmega8, ata6289, atmega8a, ata6285, ata6286, ata6612c, atmega48, atmega48a, atmega48pa, atmega48pb, atmega48p, atmega88, atmega88a, atmega88p, atmega88pa, atmega88pb, atmega8515, atmega8535, atmega8hva, at90pwm1, at90pwm2, at90pwm2b, at90pwm3, at90pwm3b, at90pwm81, avr5, ata5702m322, ata5782, ata5790, ata5790n, ata5791, ata5795, ata5831, ata6613c, ata6614q, ata8210, ata8510, atmega16, atmega16a, atmega161, atmega162, atmega163, atmega164a, atmega164p, atmega164pa, atmega165, atmega165a, atmega165p, atmega165pa, atmega168, atmega168a, atmega168p, atmega168pa, atmega168pb, atmega169, atmega169a, atmega169p, atmega169pa, atmega32, atmega32a, atmega323, atmega324a, atmega324p, atmega324pa, atmega324pb, atmega325, atmega325a, atmega325p, atmega325pa, atmega3250, atmega3250a, atmega3250p, atmega3250pa, atmega328, atmega328p, atmega328pb, atmega329, atmega329a, atmega329p, atmega329pa, atmega3290, atmega3290a, atmega3290p, atmega3290pa, atmega406, atmega64, atmega64a, atmega640, atmega644, atmega644a, atmega644p, atmega644pa, atmega645, atmega645a, atmega645p, atmega649, atmega649a, atmega649p, atmega6450, atmega6450a, atmega6450p, atmega6490, atmega6490a, atmega6490p, atmega64rfr2, atmega644rfr2, atmega16hva, atmega16hva2, atmega16hvb, atmega16hvbrevb, atmega32hvb, atmega32hvbrevb, atmega64hve, atmega64hve2, at90can32, at90can64, at90pwm161, at90pwm216, at90pwm316, atmega32c1, atmega64c1, atmega16m1, atmega32m1, atmega64m1, atmega16u4, atmega32u4, atmega32u6, at90usb646, at90usb647, at90scr100, at94k, m3000, avr51, atmega128, atmega128a, atmega1280, atmega1281, atmega1284, atmega1284p, atmega128rfa1, atmega128rfr2, atmega1284rfr2, at90can128, at90usb1286, at90usb1287, avr6, atmega2560, atmega2561, atmega256rfr2, atmega2564rfr2, avrxmega2, atxmega16a4, atxmega16a4u, atxmega16c4, atxmega16d4, atxmega32a4, atxmega32a4u, atxmega32c3, atxmega32c4, atxmega32d3, atxmega32d4, atxmega32e5, atxmega16e5, atxmega8e5, avrxmega4, atxmega64a3, atxmega64a3u, atxmega64a4u, atxmega64b1, atxmega64b3, atxmega64c3, atxmega64d3, atxmega64d4, avrxmega5, atxmega64a1, atxmega64a1u, avrxmega6, atxmega128a3, atxmega128a3u, atxmega128b1, atxmega128b3, atxmega128c3, atxmega128d3, atxmega128d4, atxmega192a3, atxmega192a3u, atxmega192c3, atxmega192d3, atxmega256a3, atxmega256a3u, atxmega256a3b, atxmega256a3bu, atxmega256c3, atxmega256d3, atxmega384c3, atxmega384d3, avrxmega7, atxmega128a1, atxmega128a1u, atxmega128a4u, avrtiny, attiny4, attiny5, attiny9, attiny10, attiny20, attiny40, attiny102, attiny104, avrxmega3, attiny202, attiny402, attiny204, attiny404, attiny804, attiny1604, attiny406, attiny806, attiny1606, attiny807, attiny1607, attiny212, attiny412, attiny214, attiny414, attiny814, attiny1614, attiny416, attiny816, attiny1616, attiny3216, attiny417, attiny817, attiny1617, attiny3217, attiny1624, attiny1626, attiny1627, atmega808, atmega809, atmega1608, atmega1609, atmega3208, atmega3209, atmega4808, atmega4809 - -// RUN: not %clang_cc1 -triple riscv32 -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix RISCV32 -// RISCV32: error: unknown target CPU 'not-a-cpu' -// RISCV32-NEXT: note: valid target CPU values are: generic-rv32, rocket-rv32, sifive-e20, sifive-e21, sifive-e24, sifive-e31, sifive-e34, sifive-e76, syntacore-scr1-base, syntacore-scr1-max, syntacore-scr3-rv32, syntacore-scr4-rv32, syntacore-scr5-rv32{{$}} - -// RUN: not %clang_cc1 -triple riscv64 -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix RISCV64 -// RISCV64: error: unknown target CPU 'not-a-cpu' -// RISCV64-NEXT: note: valid target CPU values are: generic-rv64, rocket-rv64, sifive-p450, sifive-p470, sifive-p670, sifive-s21, sifive-s51, sifive-s54, sifive-s76, sifive-u54, sifive-u74, sifive-x280, spacemit-x60, syntacore-scr3-rv64, syntacore-scr4-rv64, syntacore-scr5-rv64, veyron-v1, xiangshan-nanhu{{$}} - -// RUN: not %clang_cc1 -triple riscv32 -tune-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix TUNE-RISCV32 -// TUNE-RISCV32: error: unknown target CPU 'not-a-cpu' -// TUNE-RISCV32-NEXT: note: valid target CPU values are: generic-rv32, rocket-rv32, sifive-e20, sifive-e21, sifive-e24, sifive-e31, sifive-e34, sifive-e76, syntacore-scr1-base, syntacore-scr1-max, syntacore-scr3-rv32, syntacore-scr4-rv32, syntacore-scr5-rv32, generic, rocket, sifive-7-series{{$}} - -// RUN: not %clang_cc1 -triple riscv64 -tune-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix TUNE-RISCV64 -// TUNE-RISCV64: error: unknown target CPU 'not-a-cpu' -// TUNE-RISCV64-NEXT: note: valid target CPU values are: generic-rv64, rocket-rv64, sifive-p450, sifive-p470, sifive-p670, sifive-s21, sifive-s51, sifive-s54, sifive-s76, sifive-u54, sifive-u74, sifive-x280, spacemit-x60, syntacore-scr3-rv64, syntacore-scr4-rv64, syntacore-scr5-rv64, veyron-v1, xiangshan-nanhu, generic, rocket, sifive-7-series{{$}} diff --git a/clang/test/Misc/target-invalid-cpu-note/aarch64.c b/clang/test/Misc/target-invalid-cpu-note/aarch64.c new file mode 100644 index 00000000000000..ab83f299ac5997 --- /dev/null +++ b/clang/test/Misc/target-invalid-cpu-note/aarch64.c @@ -0,0 +1,92 @@ +// This test uses '-SAME: {{^}}' to start matching immediately where the +// previous check finished matching (specifically, caret is not treated as +// matching a start of line when used like this in FileCheck). + +// RUN: not %clang_cc1 -triple arm64--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s +// RUN: not %clang_cc1 -triple arm64--- -tune-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s + +// CHECK: error: unknown target CPU 'not-a-cpu' +// CHECK-NEXT: note: valid target CPU values are: +// CHECK-SAME: {{^}} a64fx +// CHECK-SAME: {{^}}, ampere1 +// CHECK-SAME: {{^}}, ampere1a +// CHECK-SAME: {{^}}, ampere1b +// CHECK-SAME: {{^}}, apple-a10 +// CHECK-SAME: {{^}}, apple-a11 +// CHECK-SAME: {{^}}, apple-a12 +// CHECK-SAME: {{^}}, apple-a13 +// CHECK-SAME: {{^}}, apple-a14 +// CHECK-SAME: {{^}}, apple-a15 +// CHECK-SAME: {{^}}, apple-a16 +// CHECK-SAME: {{^}}, apple-a17 +// CHECK-SAME: {{^}}, apple-a7 +// CHECK-SAME: {{^}}, apple-a8 +// CHECK-SAME: {{^}}, apple-a9 +// CHECK-SAME: {{^}}, apple-m1 +// CHECK-SAME: {{^}}, apple-m2 +// CHECK-SAME: {{^}}, apple-m3 +// CHECK-SAME: {{^}}, apple-m4 +// CHECK-SAME: {{^}}, apple-s4 +// CHECK-SAME: {{^}}, apple-s5 +// CHECK-SAME: {{^}}, carmel +// CHECK-SAME: {{^}}, cobalt-100 +// CHECK-SAME: {{^}}, cortex-a34 +// CHECK-SAME: {{^}}, cortex-a35 +// CHECK-SAME: {{^}}, cortex-a510 +// CHECK-SAME: {{^}}, cortex-a520 +// CHECK-SAME: {{^}}, cortex-a520ae +// CHECK-SAME: {{^}}, cortex-a53 +// CHECK-SAME: {{^}}, cortex-a55 +// CHECK-SAME: {{^}}, cortex-a57 +// CHECK-SAME: {{^}}, cortex-a65 +// CHECK-SAME: {{^}}, cortex-a65ae +// CHECK-SAME: {{^}}, cortex-a710 +// CHECK-SAME: {{^}}, cortex-a715 +// CHECK-SAME: {{^}}, cortex-a72 +// CHECK-SAME: {{^}}, cortex-a720 +// CHECK-SAME: {{^}}, cortex-a720ae +// CHECK-SAME: {{^}}, cortex-a725 +// CHECK-SAME: {{^}}, cortex-a73 +// CHECK-SAME: {{^}}, cortex-a75 +// CHECK-SAME: {{^}}, cortex-a76 +// CHECK-SAME: {{^}}, cortex-a76ae +// CHECK-SAME: {{^}}, cortex-a77 +// CHECK-SAME: {{^}}, cortex-a78 +// CHECK-SAME: {{^}}, cortex-a78ae +// CHECK-SAME: {{^}}, cortex-a78c +// CHECK-SAME: {{^}}, cortex-r82 +// CHECK-SAME: {{^}}, cortex-r82ae +// CHECK-SAME: {{^}}, cortex-x1 +// CHECK-SAME: {{^}}, cortex-x1c +// CHECK-SAME: {{^}}, cortex-x2 +// CHECK-SAME: {{^}}, cortex-x3 +// CHECK-SAME: {{^}}, cortex-x4 +// CHECK-SAME: {{^}}, cortex-x925 +// CHECK-SAME: {{^}}, cyclone +// CHECK-SAME: {{^}}, exynos-m3 +// CHECK-SAME: {{^}}, exynos-m4 +// CHECK-SAME: {{^}}, exynos-m5 +// CHECK-SAME: {{^}}, falkor +// CHECK-SAME: {{^}}, generic +// CHECK-SAME: {{^}}, grace +// CHECK-SAME: {{^}}, kryo +// CHECK-SAME: {{^}}, neoverse-512tvb +// CHECK-SAME: {{^}}, neoverse-e1 +// CHECK-SAME: {{^}}, neoverse-n1 +// CHECK-SAME: {{^}}, neoverse-n2 +// CHECK-SAME: {{^}}, neoverse-n3 +// CHECK-SAME: {{^}}, neoverse-v1 +// CHECK-SAME: {{^}}, neoverse-v2 +// CHECK-SAME: {{^}}, neoverse-v3 +// CHECK-SAME: {{^}}, neoverse-v3ae +// CHECK-SAME: {{^}}, oryon-1 +// CHECK-SAME: {{^}}, saphira +// CHECK-SAME: {{^}}, thunderx +// CHECK-SAME: {{^}}, thunderx2t99 +// CHECK-SAME: {{^}}, thunderx3t110 +// CHECK-SAME: {{^}}, thunderxt81 +// CHECK-SAME: {{^}}, thunderxt83 +// CHECK-SAME: {{^}}, thunderxt88 +// CHECK-SAME: {{^}}, tsv110 +// CHECK-SAME: {{$}} + diff --git a/clang/test/Misc/target-invalid-cpu-note/amdgcn.c b/clang/test/Misc/target-invalid-cpu-note/amdgcn.c new file mode 100644 index 00000000000000..0f01ff35035bd2 --- /dev/null +++ b/clang/test/Misc/target-invalid-cpu-note/amdgcn.c @@ -0,0 +1,76 @@ +// This test uses '-SAME: {{^}}' to start matching immediately where the +// previous check finished matching (specifically, caret is not treated as +// matching a start of line when used like this in FileCheck). + +// RUN: not %clang_cc1 -triple amdgcn--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s +// CHECK: error: unknown target CPU 'not-a-cpu' +// CHECK-NEXT: note: valid target CPU values are: +// CHECK-SAME: {{^}} gfx600 +// CHECK-SAME: {{^}}, tahiti +// CHECK-SAME: {{^}}, gfx601 +// CHECK-SAME: {{^}}, pitcairn +// CHECK-SAME: {{^}}, verde +// CHECK-SAME: {{^}}, gfx602 +// CHECK-SAME: {{^}}, hainan +// CHECK-SAME: {{^}}, oland +// CHECK-SAME: {{^}}, gfx700 +// CHECK-SAME: {{^}}, kaveri +// CHECK-SAME: {{^}}, gfx701 +// CHECK-SAME: {{^}}, hawaii +// CHECK-SAME: {{^}}, gfx702 +// CHECK-SAME: {{^}}, gfx703 +// CHECK-SAME: {{^}}, kabini +// CHECK-SAME: {{^}}, mullins +// CHECK-SAME: {{^}}, gfx704 +// CHECK-SAME: {{^}}, bonaire +// CHECK-SAME: {{^}}, gfx705 +// CHECK-SAME: {{^}}, gfx801 +// CHECK-SAME: {{^}}, carrizo +// CHECK-SAME: {{^}}, gfx802 +// CHECK-SAME: {{^}}, iceland +// CHECK-SAME: {{^}}, tonga +// CHECK-SAME: {{^}}, gfx803 +// CHECK-SAME: {{^}}, fiji +// CHECK-SAME: {{^}}, polaris10 +// CHECK-SAME: {{^}}, polaris11 +// CHECK-SAME: {{^}}, gfx805 +// CHECK-SAME: {{^}}, tongapro +// CHECK-SAME: {{^}}, gfx810 +// CHECK-SAME: {{^}}, stoney +// CHECK-SAME: {{^}}, gfx900 +// CHECK-SAME: {{^}}, gfx902 +// CHECK-SAME: {{^}}, gfx904 +// CHECK-SAME: {{^}}, gfx906 +// CHECK-SAME: {{^}}, gfx908 +// CHECK-SAME: {{^}}, gfx909 +// CHECK-SAME: {{^}}, gfx90a +// CHECK-SAME: {{^}}, gfx90c +// CHECK-SAME: {{^}}, gfx940 +// CHECK-SAME: {{^}}, gfx941 +// CHECK-SAME: {{^}}, gfx942 +// CHECK-SAME: {{^}}, gfx1010 +// CHECK-SAME: {{^}}, gfx1011 +// CHECK-SAME: {{^}}, gfx1012 +// CHECK-SAME: {{^}}, gfx1013 +// CHECK-SAME: {{^}}, gfx1030 +// CHECK-SAME: {{^}}, gfx1031 +// CHECK-SAME: {{^}}, gfx1032 +// CHECK-SAME: {{^}}, gfx1033 +// CHECK-SAME: {{^}}, gfx1034 +// CHECK-SAME: {{^}}, gfx1035 +// CHECK-SAME: {{^}}, gfx1036 +// CHECK-SAME: {{^}}, gfx1100 +// CHECK-SAME: {{^}}, gfx1101 +// CHECK-SAME: {{^}}, gfx1102 +// CHECK-SAME: {{^}}, gfx1103 +// CHECK-SAME: {{^}}, gfx1150 +// CHECK-SAME: {{^}}, gfx1151 +// CHECK-SAME: {{^}}, gfx1152 +// CHECK-SAME: {{^}}, gfx1200 +// CHECK-SAME: {{^}}, gfx1201 +// CHECK-SAME: {{^}}, gfx9-generic +// CHECK-SAME: {{^}}, gfx10-1-generic +// CHECK-SAME: {{^}}, gfx10-3-generic +// CHECK-SAME: {{^}}, gfx11-generic +// CHECK-SAME: {{^}}, gfx12-generic +// CHECK-SAME: {{$}} diff --git a/clang/test/Misc/target-invalid-cpu-note/arm.c b/clang/test/Misc/target-invalid-cpu-note/arm.c new file mode 100644 index 00000000000000..27608cc6eb29fc --- /dev/null +++ b/clang/test/Misc/target-invalid-cpu-note/arm.c @@ -0,0 +1,100 @@ +// This test uses '-SAME: {{^}}' to start matching immediately where the +// previous check finished matching (specifically, caret is not treated as +// matching a start of line when used like this in FileCheck). + +// RUN: not %clang_cc1 -triple armv5--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s +// CHECK: error: unknown target CPU 'not-a-cpu' +// CHECK-NEXT: note: valid target CPU values are: +// CHECK-SAME: {{^}} arm8 +// CHECK-SAME: {{^}}, arm810 +// CHECK-SAME: {{^}}, strongarm +// CHECK-SAME: {{^}}, strongarm110 +// CHECK-SAME: {{^}}, strongarm1100 +// CHECK-SAME: {{^}}, strongarm1110 +// CHECK-SAME: {{^}}, arm7tdmi +// CHECK-SAME: {{^}}, arm7tdmi-s +// CHECK-SAME: {{^}}, arm710t +// CHECK-SAME: {{^}}, arm720t +// CHECK-SAME: {{^}}, arm9 +// CHECK-SAME: {{^}}, arm9tdmi +// CHECK-SAME: {{^}}, arm920 +// CHECK-SAME: {{^}}, arm920t +// CHECK-SAME: {{^}}, arm922t +// CHECK-SAME: {{^}}, arm940t +// CHECK-SAME: {{^}}, ep9312 +// CHECK-SAME: {{^}}, arm10tdmi +// CHECK-SAME: {{^}}, arm1020t +// CHECK-SAME: {{^}}, arm9e +// CHECK-SAME: {{^}}, arm946e-s +// CHECK-SAME: {{^}}, arm966e-s +// CHECK-SAME: {{^}}, arm968e-s +// CHECK-SAME: {{^}}, arm10e +// CHECK-SAME: {{^}}, arm1020e +// CHECK-SAME: {{^}}, arm1022e +// CHECK-SAME: {{^}}, arm926ej-s +// CHECK-SAME: {{^}}, arm1136j-s +// CHECK-SAME: {{^}}, arm1136jf-s +// CHECK-SAME: {{^}}, mpcore +// CHECK-SAME: {{^}}, mpcorenovfp +// CHECK-SAME: {{^}}, arm1176jz-s +// CHECK-SAME: {{^}}, arm1176jzf-s +// CHECK-SAME: {{^}}, arm1156t2-s +// CHECK-SAME: {{^}}, arm1156t2f-s +// CHECK-SAME: {{^}}, cortex-m0 +// CHECK-SAME: {{^}}, cortex-m0plus +// CHECK-SAME: {{^}}, cortex-m1 +// CHECK-SAME: {{^}}, sc000 +// CHECK-SAME: {{^}}, cortex-a5 +// CHECK-SAME: {{^}}, cortex-a7 +// CHECK-SAME: {{^}}, cortex-a8 +// CHECK-SAME: {{^}}, cortex-a9 +// CHECK-SAME: {{^}}, cortex-a12 +// CHECK-SAME: {{^}}, cortex-a15 +// CHECK-SAME: {{^}}, cortex-a17 +// CHECK-SAME: {{^}}, krait +// CHECK-SAME: {{^}}, cortex-r4 +// CHECK-SAME: {{^}}, cortex-r4f +// CHECK-SAME: {{^}}, cortex-r5 +// CHECK-SAME: {{^}}, cortex-r7 +// CHECK-SAME: {{^}}, cortex-r8 +// CHECK-SAME: {{^}}, cortex-r52 +// CHECK-SAME: {{^}}, cortex-r52plus +// CHECK-SAME: {{^}}, sc300 +// CHECK-SAME: {{^}}, cortex-m3 +// CHECK-SAME: {{^}}, cortex-m4 +// CHECK-SAME: {{^}}, cortex-m7 +// CHECK-SAME: {{^}}, cortex-m23 +// CHECK-SAME: {{^}}, cortex-m33 +// CHECK-SAME: {{^}}, cortex-m35p +// CHECK-SAME: {{^}}, cortex-m55 +// CHECK-SAME: {{^}}, cortex-m85 +// CHECK-SAME: {{^}}, cortex-m52 +// CHECK-SAME: {{^}}, cortex-a32 +// CHECK-SAME: {{^}}, cortex-a35 +// CHECK-SAME: {{^}}, cortex-a53 +// CHECK-SAME: {{^}}, cortex-a55 +// CHECK-SAME: {{^}}, cortex-a57 +// CHECK-SAME: {{^}}, cortex-a72 +// CHECK-SAME: {{^}}, cortex-a73 +// CHECK-SAME: {{^}}, cortex-a75 +// CHECK-SAME: {{^}}, cortex-a76 +// CHECK-SAME: {{^}}, cortex-a76ae +// CHECK-SAME: {{^}}, cortex-a77 +// CHECK-SAME: {{^}}, cortex-a78 +// CHECK-SAME: {{^}}, cortex-a78ae +// CHECK-SAME: {{^}}, cortex-a78c +// CHECK-SAME: {{^}}, cortex-a710 +// CHECK-SAME: {{^}}, cortex-x1 +// CHECK-SAME: {{^}}, cortex-x1c +// CHECK-SAME: {{^}}, neoverse-n1 +// CHECK-SAME: {{^}}, neoverse-n2 +// CHECK-SAME: {{^}}, neoverse-v1 +// CHECK-SAME: {{^}}, cyclone +// CHECK-SAME: {{^}}, exynos-m3 +// CHECK-SAME: {{^}}, exynos-m4 +// CHECK-SAME: {{^}}, exynos-m5 +// CHECK-SAME: {{^}}, kryo +// CHECK-SAME: {{^}}, iwmmxt +// CHECK-SAME: {{^}}, xscale +// CHECK-SAME: {{^}}, swift +// CHECK-SAME: {{$}} diff --git a/clang/test/Misc/target-invalid-cpu-note/avr.c b/clang/test/Misc/target-invalid-cpu-note/avr.c new file mode 100644 index 00000000000000..86ffbb68385822 --- /dev/null +++ b/clang/test/Misc/target-invalid-cpu-note/avr.c @@ -0,0 +1,322 @@ +// This test uses '-SAME: {{^}}' to start matching immediately where the +// previous check finished matching (specifically, caret is not treated as +// matching a start of line when used like this in FileCheck). + +// RUN: not %clang_cc1 -triple avr--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s +// CHECK: error: unknown target CPU 'not-a-cpu' +// CHECK-NEXT: note: valid target CPU values are: +// CHECK-SAME: {{^}} avr1 +// CHECK-SAME: {{^}}, at90s1200 +// CHECK-SAME: {{^}}, attiny11 +// CHECK-SAME: {{^}}, attiny12 +// CHECK-SAME: {{^}}, attiny15 +// CHECK-SAME: {{^}}, attiny28 +// CHECK-SAME: {{^}}, avr2 +// CHECK-SAME: {{^}}, at90s2313 +// CHECK-SAME: {{^}}, at90s2323 +// CHECK-SAME: {{^}}, at90s2333 +// CHECK-SAME: {{^}}, at90s2343 +// CHECK-SAME: {{^}}, attiny22 +// CHECK-SAME: {{^}}, attiny26 +// CHECK-SAME: {{^}}, at86rf401 +// CHECK-SAME: {{^}}, at90s4414 +// CHECK-SAME: {{^}}, at90s4433 +// CHECK-SAME: {{^}}, at90s4434 +// CHECK-SAME: {{^}}, at90s8515 +// CHECK-SAME: {{^}}, at90c8534 +// CHECK-SAME: {{^}}, at90s8535 +// CHECK-SAME: {{^}}, avr25 +// CHECK-SAME: {{^}}, ata5272 +// CHECK-SAME: {{^}}, ata6616c +// CHECK-SAME: {{^}}, attiny13 +// CHECK-SAME: {{^}}, attiny13a +// CHECK-SAME: {{^}}, attiny2313 +// CHECK-SAME: {{^}}, attiny2313a +// CHECK-SAME: {{^}}, attiny24 +// CHECK-SAME: {{^}}, attiny24a +// CHECK-SAME: {{^}}, attiny4313 +// CHECK-SAME: {{^}}, attiny44 +// CHECK-SAME: {{^}}, attiny44a +// CHECK-SAME: {{^}}, attiny84 +// CHECK-SAME: {{^}}, attiny84a +// CHECK-SAME: {{^}}, attiny25 +// CHECK-SAME: {{^}}, attiny45 +// CHECK-SAME: {{^}}, attiny85 +// CHECK-SAME: {{^}}, attiny261 +// CHECK-SAME: {{^}}, attiny261a +// CHECK-SAME: {{^}}, attiny441 +// CHECK-SAME: {{^}}, attiny461 +// CHECK-SAME: {{^}}, attiny461a +// CHECK-SAME: {{^}}, attiny841 +// CHECK-SAME: {{^}}, attiny861 +// CHECK-SAME: {{^}}, attiny861a +// CHECK-SAME: {{^}}, attiny87 +// CHECK-SAME: {{^}}, attiny43u +// CHECK-SAME: {{^}}, attiny48 +// CHECK-SAME: {{^}}, attiny88 +// CHECK-SAME: {{^}}, attiny828 +// CHECK-SAME: {{^}}, avr3 +// CHECK-SAME: {{^}}, at43usb355 +// CHECK-SAME: {{^}}, at76c711 +// CHECK-SAME: {{^}}, avr31 +// CHECK-SAME: {{^}}, atmega103 +// CHECK-SAME: {{^}}, at43usb320 +// CHECK-SAME: {{^}}, avr35 +// CHECK-SAME: {{^}}, attiny167 +// CHECK-SAME: {{^}}, at90usb82 +// CHECK-SAME: {{^}}, at90usb162 +// CHECK-SAME: {{^}}, ata5505 +// CHECK-SAME: {{^}}, ata6617c +// CHECK-SAME: {{^}}, ata664251 +// CHECK-SAME: {{^}}, atmega8u2 +// CHECK-SAME: {{^}}, atmega16u2 +// CHECK-SAME: {{^}}, atmega32u2 +// CHECK-SAME: {{^}}, attiny1634 +// CHECK-SAME: {{^}}, avr4 +// CHECK-SAME: {{^}}, atmega8 +// CHECK-SAME: {{^}}, ata6289 +// CHECK-SAME: {{^}}, atmega8a +// CHECK-SAME: {{^}}, ata6285 +// CHECK-SAME: {{^}}, ata6286 +// CHECK-SAME: {{^}}, ata6612c +// CHECK-SAME: {{^}}, atmega48 +// CHECK-SAME: {{^}}, atmega48a +// CHECK-SAME: {{^}}, atmega48pa +// CHECK-SAME: {{^}}, atmega48pb +// CHECK-SAME: {{^}}, atmega48p +// CHECK-SAME: {{^}}, atmega88 +// CHECK-SAME: {{^}}, atmega88a +// CHECK-SAME: {{^}}, atmega88p +// CHECK-SAME: {{^}}, atmega88pa +// CHECK-SAME: {{^}}, atmega88pb +// CHECK-SAME: {{^}}, atmega8515 +// CHECK-SAME: {{^}}, atmega8535 +// CHECK-SAME: {{^}}, atmega8hva +// CHECK-SAME: {{^}}, at90pwm1 +// CHECK-SAME: {{^}}, at90pwm2 +// CHECK-SAME: {{^}}, at90pwm2b +// CHECK-SAME: {{^}}, at90pwm3 +// CHECK-SAME: {{^}}, at90pwm3b +// CHECK-SAME: {{^}}, at90pwm81 +// CHECK-SAME: {{^}}, avr5 +// CHECK-SAME: {{^}}, ata5702m322 +// CHECK-SAME: {{^}}, ata5782 +// CHECK-SAME: {{^}}, ata5790 +// CHECK-SAME: {{^}}, ata5790n +// CHECK-SAME: {{^}}, ata5791 +// CHECK-SAME: {{^}}, ata5795 +// CHECK-SAME: {{^}}, ata5831 +// CHECK-SAME: {{^}}, ata6613c +// CHECK-SAME: {{^}}, ata6614q +// CHECK-SAME: {{^}}, ata8210 +// CHECK-SAME: {{^}}, ata8510 +// CHECK-SAME: {{^}}, atmega16 +// CHECK-SAME: {{^}}, atmega16a +// CHECK-SAME: {{^}}, atmega161 +// CHECK-SAME: {{^}}, atmega162 +// CHECK-SAME: {{^}}, atmega163 +// CHECK-SAME: {{^}}, atmega164a +// CHECK-SAME: {{^}}, atmega164p +// CHECK-SAME: {{^}}, atmega164pa +// CHECK-SAME: {{^}}, atmega165 +// CHECK-SAME: {{^}}, atmega165a +// CHECK-SAME: {{^}}, atmega165p +// CHECK-SAME: {{^}}, atmega165pa +// CHECK-SAME: {{^}}, atmega168 +// CHECK-SAME: {{^}}, atmega168a +// CHECK-SAME: {{^}}, atmega168p +// CHECK-SAME: {{^}}, atmega168pa +// CHECK-SAME: {{^}}, atmega168pb +// CHECK-SAME: {{^}}, atmega169 +// CHECK-SAME: {{^}}, atmega169a +// CHECK-SAME: {{^}}, atmega169p +// CHECK-SAME: {{^}}, atmega169pa +// CHECK-SAME: {{^}}, atmega32 +// CHECK-SAME: {{^}}, atmega32a +// CHECK-SAME: {{^}}, atmega323 +// CHECK-SAME: {{^}}, atmega324a +// CHECK-SAME: {{^}}, atmega324p +// CHECK-SAME: {{^}}, atmega324pa +// CHECK-SAME: {{^}}, atmega324pb +// CHECK-SAME: {{^}}, atmega325 +// CHECK-SAME: {{^}}, atmega325a +// CHECK-SAME: {{^}}, atmega325p +// CHECK-SAME: {{^}}, atmega325pa +// CHECK-SAME: {{^}}, atmega3250 +// CHECK-SAME: {{^}}, atmega3250a +// CHECK-SAME: {{^}}, atmega3250p +// CHECK-SAME: {{^}}, atmega3250pa +// CHECK-SAME: {{^}}, atmega328 +// CHECK-SAME: {{^}}, atmega328p +// CHECK-SAME: {{^}}, atmega328pb +// CHECK-SAME: {{^}}, atmega329 +// CHECK-SAME: {{^}}, atmega329a +// CHECK-SAME: {{^}}, atmega329p +// CHECK-SAME: {{^}}, atmega329pa +// CHECK-SAME: {{^}}, atmega3290 +// CHECK-SAME: {{^}}, atmega3290a +// CHECK-SAME: {{^}}, atmega3290p +// CHECK-SAME: {{^}}, atmega3290pa +// CHECK-SAME: {{^}}, atmega406 +// CHECK-SAME: {{^}}, atmega64 +// CHECK-SAME: {{^}}, atmega64a +// CHECK-SAME: {{^}}, atmega640 +// CHECK-SAME: {{^}}, atmega644 +// CHECK-SAME: {{^}}, atmega644a +// CHECK-SAME: {{^}}, atmega644p +// CHECK-SAME: {{^}}, atmega644pa +// CHECK-SAME: {{^}}, atmega645 +// CHECK-SAME: {{^}}, atmega645a +// CHECK-SAME: {{^}}, atmega645p +// CHECK-SAME: {{^}}, atmega649 +// CHECK-SAME: {{^}}, atmega649a +// CHECK-SAME: {{^}}, atmega649p +// CHECK-SAME: {{^}}, atmega6450 +// CHECK-SAME: {{^}}, atmega6450a +// CHECK-SAME: {{^}}, atmega6450p +// CHECK-SAME: {{^}}, atmega6490 +// CHECK-SAME: {{^}}, atmega6490a +// CHECK-SAME: {{^}}, atmega6490p +// CHECK-SAME: {{^}}, atmega64rfr2 +// CHECK-SAME: {{^}}, atmega644rfr2 +// CHECK-SAME: {{^}}, atmega16hva +// CHECK-SAME: {{^}}, atmega16hva2 +// CHECK-SAME: {{^}}, atmega16hvb +// CHECK-SAME: {{^}}, atmega16hvbrevb +// CHECK-SAME: {{^}}, atmega32hvb +// CHECK-SAME: {{^}}, atmega32hvbrevb +// CHECK-SAME: {{^}}, atmega64hve +// CHECK-SAME: {{^}}, atmega64hve2 +// CHECK-SAME: {{^}}, at90can32 +// CHECK-SAME: {{^}}, at90can64 +// CHECK-SAME: {{^}}, at90pwm161 +// CHECK-SAME: {{^}}, at90pwm216 +// CHECK-SAME: {{^}}, at90pwm316 +// CHECK-SAME: {{^}}, atmega32c1 +// CHECK-SAME: {{^}}, atmega64c1 +// CHECK-SAME: {{^}}, atmega16m1 +// CHECK-SAME: {{^}}, atmega32m1 +// CHECK-SAME: {{^}}, atmega64m1 +// CHECK-SAME: {{^}}, atmega16u4 +// CHECK-SAME: {{^}}, atmega32u4 +// CHECK-SAME: {{^}}, atmega32u6 +// CHECK-SAME: {{^}}, at90usb646 +// CHECK-SAME: {{^}}, at90usb647 +// CHECK-SAME: {{^}}, at90scr100 +// CHECK-SAME: {{^}}, at94k +// CHECK-SAME: {{^}}, m3000 +// CHECK-SAME: {{^}}, avr51 +// CHECK-SAME: {{^}}, atmega128 +// CHECK-SAME: {{^}}, atmega128a +// CHECK-SAME: {{^}}, atmega1280 +// CHECK-SAME: {{^}}, atmega1281 +// CHECK-SAME: {{^}}, atmega1284 +// CHECK-SAME: {{^}}, atmega1284p +// CHECK-SAME: {{^}}, atmega128rfa1 +// CHECK-SAME: {{^}}, atmega128rfr2 +// CHECK-SAME: {{^}}, atmega1284rfr2 +// CHECK-SAME: {{^}}, at90can128 +// CHECK-SAME: {{^}}, at90usb1286 +// CHECK-SAME: {{^}}, at90usb1287 +// CHECK-SAME: {{^}}, avr6 +// CHECK-SAME: {{^}}, atmega2560 +// CHECK-SAME: {{^}}, atmega2561 +// CHECK-SAME: {{^}}, atmega256rfr2 +// CHECK-SAME: {{^}}, atmega2564rfr2 +// CHECK-SAME: {{^}}, avrxmega2 +// CHECK-SAME: {{^}}, atxmega16a4 +// CHECK-SAME: {{^}}, atxmega16a4u +// CHECK-SAME: {{^}}, atxmega16c4 +// CHECK-SAME: {{^}}, atxmega16d4 +// CHECK-SAME: {{^}}, atxmega32a4 +// CHECK-SAME: {{^}}, atxmega32a4u +// CHECK-SAME: {{^}}, atxmega32c3 +// CHECK-SAME: {{^}}, atxmega32c4 +// CHECK-SAME: {{^}}, atxmega32d3 +// CHECK-SAME: {{^}}, atxmega32d4 +// CHECK-SAME: {{^}}, atxmega32e5 +// CHECK-SAME: {{^}}, atxmega16e5 +// CHECK-SAME: {{^}}, atxmega8e5 +// CHECK-SAME: {{^}}, avrxmega4 +// CHECK-SAME: {{^}}, atxmega64a3 +// CHECK-SAME: {{^}}, atxmega64a3u +// CHECK-SAME: {{^}}, atxmega64a4u +// CHECK-SAME: {{^}}, atxmega64b1 +// CHECK-SAME: {{^}}, atxmega64b3 +// CHECK-SAME: {{^}}, atxmega64c3 +// CHECK-SAME: {{^}}, atxmega64d3 +// CHECK-SAME: {{^}}, atxmega64d4 +// CHECK-SAME: {{^}}, avrxmega5 +// CHECK-SAME: {{^}}, atxmega64a1 +// CHECK-SAME: {{^}}, atxmega64a1u +// CHECK-SAME: {{^}}, avrxmega6 +// CHECK-SAME: {{^}}, atxmega128a3 +// CHECK-SAME: {{^}}, atxmega128a3u +// CHECK-SAME: {{^}}, atxmega128b1 +// CHECK-SAME: {{^}}, atxmega128b3 +// CHECK-SAME: {{^}}, atxmega128c3 +// CHECK-SAME: {{^}}, atxmega128d3 +// CHECK-SAME: {{^}}, atxmega128d4 +// CHECK-SAME: {{^}}, atxmega192a3 +// CHECK-SAME: {{^}}, atxmega192a3u +// CHECK-SAME: {{^}}, atxmega192c3 +// CHECK-SAME: {{^}}, atxmega192d3 +// CHECK-SAME: {{^}}, atxmega256a3 +// CHECK-SAME: {{^}}, atxmega256a3u +// CHECK-SAME: {{^}}, atxmega256a3b +// CHECK-SAME: {{^}}, atxmega256a3bu +// CHECK-SAME: {{^}}, atxmega256c3 +// CHECK-SAME: {{^}}, atxmega256d3 +// CHECK-SAME: {{^}}, atxmega384c3 +// CHECK-SAME: {{^}}, atxmega384d3 +// CHECK-SAME: {{^}}, avrxmega7 +// CHECK-SAME: {{^}}, atxmega128a1 +// CHECK-SAME: {{^}}, atxmega128a1u +// CHECK-SAME: {{^}}, atxmega128a4u +// CHECK-SAME: {{^}}, avrtiny +// CHECK-SAME: {{^}}, attiny4 +// CHECK-SAME: {{^}}, attiny5 +// CHECK-SAME: {{^}}, attiny9 +// CHECK-SAME: {{^}}, attiny10 +// CHECK-SAME: {{^}}, attiny20 +// CHECK-SAME: {{^}}, attiny40 +// CHECK-SAME: {{^}}, attiny102 +// CHECK-SAME: {{^}}, attiny104 +// CHECK-SAME: {{^}}, avrxmega3 +// CHECK-SAME: {{^}}, attiny202 +// CHECK-SAME: {{^}}, attiny402 +// CHECK-SAME: {{^}}, attiny204 +// CHECK-SAME: {{^}}, attiny404 +// CHECK-SAME: {{^}}, attiny804 +// CHECK-SAME: {{^}}, attiny1604 +// CHECK-SAME: {{^}}, attiny406 +// CHECK-SAME: {{^}}, attiny806 +// CHECK-SAME: {{^}}, attiny1606 +// CHECK-SAME: {{^}}, attiny807 +// CHECK-SAME: {{^}}, attiny1607 +// CHECK-SAME: {{^}}, attiny212 +// CHECK-SAME: {{^}}, attiny412 +// CHECK-SAME: {{^}}, attiny214 +// CHECK-SAME: {{^}}, attiny414 +// CHECK-SAME: {{^}}, attiny814 +// CHECK-SAME: {{^}}, attiny1614 +// CHECK-SAME: {{^}}, attiny416 +// CHECK-SAME: {{^}}, attiny816 +// CHECK-SAME: {{^}}, attiny1616 +// CHECK-SAME: {{^}}, attiny3216 +// CHECK-SAME: {{^}}, attiny417 +// CHECK-SAME: {{^}}, attiny817 +// CHECK-SAME: {{^}}, attiny1617 +// CHECK-SAME: {{^}}, attiny3217 +// CHECK-SAME: {{^}}, attiny1624 +// CHECK-SAME: {{^}}, attiny1626 +// CHECK-SAME: {{^}}, attiny1627 +// CHECK-SAME: {{^}}, atmega808 +// CHECK-SAME: {{^}}, atmega809 +// CHECK-SAME: {{^}}, atmega1608 +// CHECK-SAME: {{^}}, atmega1609 +// CHECK-SAME: {{^}}, atmega3208 +// CHECK-SAME: {{^}}, atmega3209 +// CHECK-SAME: {{^}}, atmega4808 +// CHECK-SAME: {{^}}, atmega4809 +// CHECK-SAME: {{$}} diff --git a/clang/test/Misc/target-invalid-cpu-note/bpf.c b/clang/test/Misc/target-invalid-cpu-note/bpf.c new file mode 100644 index 00000000000000..fe925f86cdd137 --- /dev/null +++ b/clang/test/Misc/target-invalid-cpu-note/bpf.c @@ -0,0 +1,15 @@ +// This test uses '-SAME: {{^}}' to start matching immediately where the +// previous check finished matching (specifically, caret is not treated as +// matching a start of line when used like this in FileCheck). + +// RUN: not %clang_cc1 -triple bpf--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s +// CHECK: error: unknown target CPU 'not-a-cpu' +// CHECK-NEXT: note: valid target CPU values are: +// CHECK-SAME: {{^}} generic +// CHECK-SAME: {{^}}, v1 +// CHECK-SAME: {{^}}, v2 +// CHECK-SAME: {{^}}, v3 +// CHECK-SAME: {{^}}, v4 +// CHECK-SAME: {{^}}, probe +// CHECK-SAME: {{$}} + diff --git a/clang/test/Misc/target-invalid-cpu-note/hexagon.c b/clang/test/Misc/target-invalid-cpu-note/hexagon.c new file mode 100644 index 00000000000000..a7b73f33cccae6 --- /dev/null +++ b/clang/test/Misc/target-invalid-cpu-note/hexagon.c @@ -0,0 +1,21 @@ +// This test uses '-SAME: {{^}}' to start matching immediately where the +// previous check finished matching (specifically, caret is not treated as +// matching a start of line when used like this in FileCheck). + +// RUN: not %clang_cc1 -triple hexagon--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s +// CHECK: error: unknown target CPU 'not-a-cpu' +// CHECK-NEXT: note: valid target CPU values are: +// CHECK-SAME: {{^}} hexagonv5 +// CHECK-SAME: {{^}}, hexagonv55 +// CHECK-SAME: {{^}}, hexagonv60 +// CHECK-SAME: {{^}}, hexagonv62 +// CHECK-SAME: {{^}}, hexagonv65 +// CHECK-SAME: {{^}}, hexagonv66 +// CHECK-SAME: {{^}}, hexagonv67 +// CHECK-SAME: {{^}}, hexagonv67t +// CHECK-SAME: {{^}}, hexagonv68 +// CHECK-SAME: {{^}}, hexagonv69 +// CHECK-SAME: {{^}}, hexagonv71 +// CHECK-SAME: {{^}}, hexagonv71t +// CHECK-SAME: {{^}}, hexagonv73 +// CHECK-SAME: {{$}} diff --git a/clang/test/Misc/target-invalid-cpu-note/lanai.c b/clang/test/Misc/target-invalid-cpu-note/lanai.c new file mode 100644 index 00000000000000..01714c4fce9402 --- /dev/null +++ b/clang/test/Misc/target-invalid-cpu-note/lanai.c @@ -0,0 +1,9 @@ +// This test uses '-SAME: {{^}}' to start matching immediately where the +// previous check finished matching (specifically, caret is not treated as +// matching a start of line when used like this in FileCheck). + +// RUN: not %clang_cc1 -triple lanai--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s +// CHECK: error: unknown target CPU 'not-a-cpu' +// CHECK-NEXT: note: valid target CPU values are: +// CHECK-SAME: {{^}} v11 +// CHECK-SAME: {{$}} diff --git a/clang/test/Misc/target-invalid-cpu-note/mips.c b/clang/test/Misc/target-invalid-cpu-note/mips.c new file mode 100644 index 00000000000000..17b6ff9c57084d --- /dev/null +++ b/clang/test/Misc/target-invalid-cpu-note/mips.c @@ -0,0 +1,26 @@ +// This test uses '-SAME: {{^}}' to start matching immediately where the +// previous check finished matching (specifically, caret is not treated as +// matching a start of line when used like this in FileCheck). + +// RUN: not %clang_cc1 -triple mips--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s +// CHECK: error: unknown target CPU 'not-a-cpu' +// CHECK-NEXT: note: valid target CPU values are: +// CHECK-SAME: {{^}} mips1 +// CHECK-SAME: {{^}}, mips2 +// CHECK-SAME: {{^}}, mips3 +// CHECK-SAME: {{^}}, mips4 +// CHECK-SAME: {{^}}, mips5 +// CHECK-SAME: {{^}}, mips32 +// CHECK-SAME: {{^}}, mips32r2 +// CHECK-SAME: {{^}}, mips32r3 +// CHECK-SAME: {{^}}, mips32r5 +// CHECK-SAME: {{^}}, mips32r6 +// CHECK-SAME: {{^}}, mips64 +// CHECK-SAME: {{^}}, mips64r2 +// CHECK-SAME: {{^}}, mips64r3 +// CHECK-SAME: {{^}}, mips64r5 +// CHECK-SAME: {{^}}, mips64r6 +// CHECK-SAME: {{^}}, octeon +// CHECK-SAME: {{^}}, octeon+ +// CHECK-SAME: {{^}}, p5600 +// CHECK-SAME: {{$}} diff --git a/clang/test/Misc/target-invalid-cpu-note/nvptx.c b/clang/test/Misc/target-invalid-cpu-note/nvptx.c new file mode 100644 index 00000000000000..af4ccff6b07b6c --- /dev/null +++ b/clang/test/Misc/target-invalid-cpu-note/nvptx.c @@ -0,0 +1,80 @@ +// This test uses '-SAME: {{^}}' to start matching immediately where the +// previous check finished matching (specifically, caret is not treated as +// matching a start of line when used like this in FileCheck). + +// RUN: not %clang_cc1 -triple nvptx--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --implicit-check-not={{[a-zA-Z0-9]}} +// CHECK: error: unknown target CPU 'not-a-cpu' +// CHECK-NEXT: note: valid target CPU values are: +// CHECK-SAME: {{^}} sm_20 +// CHECK-SAME: {{^}}, sm_21 +// CHECK-SAME: {{^}}, sm_30 +// CHECK-SAME: {{^}}, sm_32 +// CHECK-SAME: {{^}}, sm_35 +// CHECK-SAME: {{^}}, sm_37 +// CHECK-SAME: {{^}}, sm_50 +// CHECK-SAME: {{^}}, sm_52 +// CHECK-SAME: {{^}}, sm_53 +// CHECK-SAME: {{^}}, sm_60 +// CHECK-SAME: {{^}}, sm_61 +// CHECK-SAME: {{^}}, sm_62 +// CHECK-SAME: {{^}}, sm_70 +// CHECK-SAME: {{^}}, sm_72 +// CHECK-SAME: {{^}}, sm_75 +// CHECK-SAME: {{^}}, sm_80 +// CHECK-SAME: {{^}}, sm_86 +// CHECK-SAME: {{^}}, sm_87 +// CHECK-SAME: {{^}}, sm_89 +// CHECK-SAME: {{^}}, sm_90 +// CHECK-SAME: {{^}}, sm_90a +// CHECK-SAME: {{^}}, gfx600 +// CHECK-SAME: {{^}}, gfx601 +// CHECK-SAME: {{^}}, gfx602 +// CHECK-SAME: {{^}}, gfx700 +// CHECK-SAME: {{^}}, gfx701 +// CHECK-SAME: {{^}}, gfx702 +// CHECK-SAME: {{^}}, gfx703 +// CHECK-SAME: {{^}}, gfx704 +// CHECK-SAME: {{^}}, gfx705 +// CHECK-SAME: {{^}}, gfx801 +// CHECK-SAME: {{^}}, gfx802 +// CHECK-SAME: {{^}}, gfx803 +// CHECK-SAME: {{^}}, gfx805 +// CHECK-SAME: {{^}}, gfx810 +// CHECK-SAME: {{^}}, gfx9-generic +// CHECK-SAME: {{^}}, gfx900 +// CHECK-SAME: {{^}}, gfx902 +// CHECK-SAME: {{^}}, gfx904 +// CHECK-SAME: {{^}}, gfx906 +// CHECK-SAME: {{^}}, gfx908 +// CHECK-SAME: {{^}}, gfx909 +// CHECK-SAME: {{^}}, gfx90a +// CHECK-SAME: {{^}}, gfx90c +// CHECK-SAME: {{^}}, gfx940 +// CHECK-SAME: {{^}}, gfx941 +// CHECK-SAME: {{^}}, gfx942 +// CHECK-SAME: {{^}}, gfx10-1-generic +// CHECK-SAME: {{^}}, gfx1010 +// CHECK-SAME: {{^}}, gfx1011 +// CHECK-SAME: {{^}}, gfx1012 +// CHECK-SAME: {{^}}, gfx1013 +// CHECK-SAME: {{^}}, gfx10-3-generic +// CHECK-SAME: {{^}}, gfx1030 +// CHECK-SAME: {{^}}, gfx1031 +// CHECK-SAME: {{^}}, gfx1032 +// CHECK-SAME: {{^}}, gfx1033 +// CHECK-SAME: {{^}}, gfx1034 +// CHECK-SAME: {{^}}, gfx1035 +// CHECK-SAME: {{^}}, gfx1036 +// CHECK-SAME: {{^}}, gfx11-generic +// CHECK-SAME: {{^}}, gfx1100 +// CHECK-SAME: {{^}}, gfx1101 +// CHECK-SAME: {{^}}, gfx1102 +// CHECK-SAME: {{^}}, gfx1103 +// CHECK-SAME: {{^}}, gfx1150 +// CHECK-SAME: {{^}}, gfx1151 +// CHECK-SAME: {{^}}, gfx1152 +// CHECK-SAME: {{^}}, gfx12-generic +// CHECK-SAME: {{^}}, gfx1200 +// CHECK-SAME: {{^}}, gfx1201 +// CHECK-SAME: {{^}}, amdgcnspirv +// CHECK-SAME: {{$}} diff --git a/clang/test/Misc/target-invalid-cpu-note/powerpc.c b/clang/test/Misc/target-invalid-cpu-note/powerpc.c new file mode 100644 index 00000000000000..3ecc8e5c3eba03 --- /dev/null +++ b/clang/test/Misc/target-invalid-cpu-note/powerpc.c @@ -0,0 +1,73 @@ +// This test uses '-SAME: {{^}}' to start matching immediately where the +// previous check finished matching (specifically, caret is not treated as +// matching a start of line when used like this in FileCheck). + +// RUN: not %clang_cc1 -triple powerpc--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s +// CHECK: error: unknown target CPU 'not-a-cpu' +// CHECK-NEXT: note: valid target CPU values are: +// CHECK-SAME: {{^}} generic +// CHECK-SAME: {{^}}, 440 +// CHECK-SAME: {{^}}, 440fp +// CHECK-SAME: {{^}}, ppc440 +// CHECK-SAME: {{^}}, 450 +// CHECK-SAME: {{^}}, 601 +// CHECK-SAME: {{^}}, 602 +// CHECK-SAME: {{^}}, 603 +// CHECK-SAME: {{^}}, 603e +// CHECK-SAME: {{^}}, 603ev +// CHECK-SAME: {{^}}, 604 +// CHECK-SAME: {{^}}, 604e +// CHECK-SAME: {{^}}, 620 +// CHECK-SAME: {{^}}, 630 +// CHECK-SAME: {{^}}, g3 +// CHECK-SAME: {{^}}, 7400 +// CHECK-SAME: {{^}}, g4 +// CHECK-SAME: {{^}}, 7450 +// CHECK-SAME: {{^}}, g4+ +// CHECK-SAME: {{^}}, 750 +// CHECK-SAME: {{^}}, 8548 +// CHECK-SAME: {{^}}, ppc405 +// CHECK-SAME: {{^}}, ppc464 +// CHECK-SAME: {{^}}, ppc476 +// CHECK-SAME: {{^}}, 970 +// CHECK-SAME: {{^}}, ppc970 +// CHECK-SAME: {{^}}, g5 +// CHECK-SAME: {{^}}, a2 +// CHECK-SAME: {{^}}, ppca2 +// CHECK-SAME: {{^}}, ppc-cell-be +// CHECK-SAME: {{^}}, e500 +// CHECK-SAME: {{^}}, e500mc +// CHECK-SAME: {{^}}, e5500 +// CHECK-SAME: {{^}}, power3 +// CHECK-SAME: {{^}}, pwr3 +// CHECK-SAME: {{^}}, pwr4 +// CHECK-SAME: {{^}}, power4 +// CHECK-SAME: {{^}}, pwr5 +// CHECK-SAME: {{^}}, power5 +// CHECK-SAME: {{^}}, pwr5+ +// CHECK-SAME: {{^}}, power5+ +// CHECK-SAME: {{^}}, pwr5x +// CHECK-SAME: {{^}}, power5x +// CHECK-SAME: {{^}}, pwr6 +// CHECK-SAME: {{^}}, power6 +// CHECK-SAME: {{^}}, pwr6x +// CHECK-SAME: {{^}}, power6x +// CHECK-SAME: {{^}}, pwr7 +// CHECK-SAME: {{^}}, power7 +// CHECK-SAME: {{^}}, pwr8 +// CHECK-SAME: {{^}}, power8 +// CHECK-SAME: {{^}}, pwr9 +// CHECK-SAME: {{^}}, power9 +// CHECK-SAME: {{^}}, pwr10 +// CHECK-SAME: {{^}}, power10 +// CHECK-SAME: {{^}}, pwr11 +// CHECK-SAME: {{^}}, power11 +// CHECK-SAME: {{^}}, powerpc +// CHECK-SAME: {{^}}, ppc +// CHECK-SAME: {{^}}, ppc32 +// CHECK-SAME: {{^}}, powerpc64 +// CHECK-SAME: {{^}}, ppc64 +// CHECK-SAME: {{^}}, powerpc64le +// CHECK-SAME: {{^}}, ppc64le +// CHECK-SAME: {{^}}, future +// CHECK-SAME: {{$}} diff --git a/clang/test/Misc/target-invalid-cpu-note/r600.c b/clang/test/Misc/target-invalid-cpu-note/r600.c new file mode 100644 index 00000000000000..1481d41745ea95 --- /dev/null +++ b/clang/test/Misc/target-invalid-cpu-note/r600.c @@ -0,0 +1,34 @@ +// This test uses '-SAME: {{^}}' to start matching immediately where the +// previous check finished matching (specifically, caret is not treated as +// matching a start of line when used like this in FileCheck). + +// RUN: not %clang_cc1 -triple r600--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s +// CHECK: error: unknown target CPU 'not-a-cpu' +// CHECK-NEXT: note: valid target CPU values are: +// CHECK-SAME: {{^}} r600 +// CHECK-SAME: {{^}}, rv630 +// CHECK-SAME: {{^}}, rv635 +// CHECK-SAME: {{^}}, r630 +// CHECK-SAME: {{^}}, rs780 +// CHECK-SAME: {{^}}, rs880 +// CHECK-SAME: {{^}}, rv610 +// CHECK-SAME: {{^}}, rv620 +// CHECK-SAME: {{^}}, rv670 +// CHECK-SAME: {{^}}, rv710 +// CHECK-SAME: {{^}}, rv730 +// CHECK-SAME: {{^}}, rv740 +// CHECK-SAME: {{^}}, rv770 +// CHECK-SAME: {{^}}, cedar +// CHECK-SAME: {{^}}, palm +// CHECK-SAME: {{^}}, cypress +// CHECK-SAME: {{^}}, hemlock +// CHECK-SAME: {{^}}, juniper +// CHECK-SAME: {{^}}, redwood +// CHECK-SAME: {{^}}, sumo +// CHECK-SAME: {{^}}, sumo2 +// CHECK-SAME: {{^}}, barts +// CHECK-SAME: {{^}}, caicos +// CHECK-SAME: {{^}}, aruba +// CHECK-SAME: {{^}}, cayman +// CHECK-SAME: {{^}}, turks +// CHECK-SAME: {{$}} diff --git a/clang/test/Misc/target-invalid-cpu-note/riscv.c b/clang/test/Misc/target-invalid-cpu-note/riscv.c new file mode 100644 index 00000000000000..0a49755de7d25f --- /dev/null +++ b/clang/test/Misc/target-invalid-cpu-note/riscv.c @@ -0,0 +1,91 @@ +// This test uses '-SAME: {{^}}' to start matching immediately where the +// previous check finished matching (specifically, caret is not treated as +// matching a start of line when used like this in FileCheck). + +// RUN: not %clang_cc1 -triple riscv32 -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix RISCV32 +// RISCV32: error: unknown target CPU 'not-a-cpu' +// RISCV32-NEXT: note: valid target CPU values are: +// RISCV32-SAME: {{^}} generic-rv32 +// RISCV32-SAME: {{^}}, rocket-rv32 +// RISCV32-SAME: {{^}}, sifive-e20 +// RISCV32-SAME: {{^}}, sifive-e21 +// RISCV32-SAME: {{^}}, sifive-e24 +// RISCV32-SAME: {{^}}, sifive-e31 +// RISCV32-SAME: {{^}}, sifive-e34 +// RISCV32-SAME: {{^}}, sifive-e76 +// RISCV32-SAME: {{^}}, syntacore-scr1-base +// RISCV32-SAME: {{^}}, syntacore-scr1-max +// RISCV32-SAME: {{^}}, syntacore-scr3-rv32 +// RISCV32-SAME: {{^}}, syntacore-scr4-rv32 +// RISCV32-SAME: {{^}}, syntacore-scr5-rv32 +// RISCV32-SAME: {{$}} + +// RUN: not %clang_cc1 -triple riscv64 -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix RISCV64 +// RISCV64: error: unknown target CPU 'not-a-cpu' +// RISCV64-NEXT: note: valid target CPU values are: +// RISCV64-SAME: {{^}} generic-rv64 +// RISCV64-SAME: {{^}}, rocket-rv64 +// RISCV64-SAME: {{^}}, sifive-p450 +// RISCV64-SAME: {{^}}, sifive-p470 +// RISCV64-SAME: {{^}}, sifive-p670 +// RISCV64-SAME: {{^}}, sifive-s21 +// RISCV64-SAME: {{^}}, sifive-s51 +// RISCV64-SAME: {{^}}, sifive-s54 +// RISCV64-SAME: {{^}}, sifive-s76 +// RISCV64-SAME: {{^}}, sifive-u54 +// RISCV64-SAME: {{^}}, sifive-u74 +// RISCV64-SAME: {{^}}, sifive-x280 +// RISCV64-SAME: {{^}}, spacemit-x60 +// RISCV64-SAME: {{^}}, syntacore-scr3-rv64 +// RISCV64-SAME: {{^}}, syntacore-scr4-rv64 +// RISCV64-SAME: {{^}}, syntacore-scr5-rv64 +// RISCV64-SAME: {{^}}, veyron-v1 +// RISCV64-SAME: {{^}}, xiangshan-nanhu +// RISCV64-SAME: {{$}} + +// RUN: not %clang_cc1 -triple riscv32 -tune-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix TUNE-RISCV32 +// TUNE-RISCV32: error: unknown target CPU 'not-a-cpu' +// TUNE-RISCV32-NEXT: note: valid target CPU values are: +// TUNE-RISCV32-SAME: {{^}} generic-rv32 +// TUNE-RISCV32-SAME: {{^}}, rocket-rv32 +// TUNE-RISCV32-SAME: {{^}}, sifive-e20 +// TUNE-RISCV32-SAME: {{^}}, sifive-e21 +// TUNE-RISCV32-SAME: {{^}}, sifive-e24 +// TUNE-RISCV32-SAME: {{^}}, sifive-e31 +// TUNE-RISCV32-SAME: {{^}}, sifive-e34 +// TUNE-RISCV32-SAME: {{^}}, sifive-e76 +// TUNE-RISCV32-SAME: {{^}}, syntacore-scr1-base +// TUNE-RISCV32-SAME: {{^}}, syntacore-scr1-max +// TUNE-RISCV32-SAME: {{^}}, syntacore-scr3-rv32 +// TUNE-RISCV32-SAME: {{^}}, syntacore-scr4-rv32 +// TUNE-RISCV32-SAME: {{^}}, syntacore-scr5-rv32 +// TUNE-RISCV32-SAME: {{^}}, generic +// TUNE-RISCV32-SAME: {{^}}, rocket +// TUNE-RISCV32-SAME: {{^}}, sifive-7-series +// TUNE-RISCV32-SAME: {{$}} + +// RUN: not %clang_cc1 -triple riscv64 -tune-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix TUNE-RISCV64 +// TUNE-RISCV64: error: unknown target CPU 'not-a-cpu' +// TUNE-RISCV64-NEXT: note: valid target CPU values are: +// TUNE-RISCV64-SAME: {{^}} generic-rv64 +// TUNE-RISCV64-SAME: {{^}}, rocket-rv64 +// TUNE-RISCV64-SAME: {{^}}, sifive-p450 +// TUNE-RISCV64-SAME: {{^}}, sifive-p470 +// TUNE-RISCV64-SAME: {{^}}, sifive-p670 +// TUNE-RISCV64-SAME: {{^}}, sifive-s21 +// TUNE-RISCV64-SAME: {{^}}, sifive-s51 +// TUNE-RISCV64-SAME: {{^}}, sifive-s54 +// TUNE-RISCV64-SAME: {{^}}, sifive-s76 +// TUNE-RISCV64-SAME: {{^}}, sifive-u54 +// TUNE-RISCV64-SAME: {{^}}, sifive-u74 +// TUNE-RISCV64-SAME: {{^}}, sifive-x280 +// TUNE-RISCV64-SAME: {{^}}, spacemit-x60 +// TUNE-RISCV64-SAME: {{^}}, syntacore-scr3-rv64 +// TUNE-RISCV64-SAME: {{^}}, syntacore-scr4-rv64 +// TUNE-RISCV64-SAME: {{^}}, syntacore-scr5-rv64 +// TUNE-RISCV64-SAME: {{^}}, veyron-v1 +// TUNE-RISCV64-SAME: {{^}}, xiangshan-nanhu +// TUNE-RISCV64-SAME: {{^}}, generic +// TUNE-RISCV64-SAME: {{^}}, rocket +// TUNE-RISCV64-SAME: {{^}}, sifive-7-series +// TUNE-RISCV64-SAME: {{$}} diff --git a/clang/test/Misc/target-invalid-cpu-note/sparc.c b/clang/test/Misc/target-invalid-cpu-note/sparc.c new file mode 100644 index 00000000000000..443c801904e60b --- /dev/null +++ b/clang/test/Misc/target-invalid-cpu-note/sparc.c @@ -0,0 +1,54 @@ +// This test uses '-SAME: {{^}}' to start matching immediately where the +// previous check finished matching (specifically, caret is not treated as +// matching a start of line when used like this in FileCheck). + +// RUN: not %clang_cc1 -triple sparc--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix SPARC +// SPARC: error: unknown target CPU 'not-a-cpu' +// SPARC-NEXT: note: valid target CPU values are: +// SPARC-SAME: {{^}} v8 +// SPARC-SAME: {{^}}, supersparc +// SPARC-SAME: {{^}}, sparclite +// SPARC-SAME: {{^}}, f934 +// SPARC-SAME: {{^}}, hypersparc +// SPARC-SAME: {{^}}, sparclite86x +// SPARC-SAME: {{^}}, sparclet +// SPARC-SAME: {{^}}, tsc701 +// SPARC-SAME: {{^}}, v9 +// SPARC-SAME: {{^}}, ultrasparc +// SPARC-SAME: {{^}}, ultrasparc3 +// SPARC-SAME: {{^}}, niagara +// SPARC-SAME: {{^}}, niagara2 +// SPARC-SAME: {{^}}, niagara3 +// SPARC-SAME: {{^}}, niagara4 +// SPARC-SAME: {{^}}, ma2100 +// SPARC-SAME: {{^}}, ma2150 +// SPARC-SAME: {{^}}, ma2155 +// SPARC-SAME: {{^}}, ma2450 +// SPARC-SAME: {{^}}, ma2455 +// SPARC-SAME: {{^}}, ma2x5x +// SPARC-SAME: {{^}}, ma2080 +// SPARC-SAME: {{^}}, ma2085 +// SPARC-SAME: {{^}}, ma2480 +// SPARC-SAME: {{^}}, ma2485 +// SPARC-SAME: {{^}}, ma2x8x +// SPARC-SAME: {{^}}, leon2 +// SPARC-SAME: {{^}}, at697e +// SPARC-SAME: {{^}}, at697f +// SPARC-SAME: {{^}}, leon3 +// SPARC-SAME: {{^}}, ut699 +// SPARC-SAME: {{^}}, gr712rc +// SPARC-SAME: {{^}}, leon4 +// SPARC-SAME: {{^}}, gr740 +// SPARC-SAME: {{$}} + +// RUN: not %clang_cc1 -triple sparcv9--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix SPARCV9 +// SPARCV9: error: unknown target CPU 'not-a-cpu' +// SPARCV9-NEXT: note: valid target CPU values are: +// SPARCV9-SAME: {{^}} v9 +// SPARCV9-SAME: {{^}}, ultrasparc +// SPARCV9-SAME: {{^}}, ultrasparc3 +// SPARCV9-SAME: {{^}}, niagara +// SPARCV9-SAME: {{^}}, niagara2 +// SPARCV9-SAME: {{^}}, niagara3 +// SPARCV9-SAME: {{^}}, niagara4 +// SPARCV9-SAME: {{$}} diff --git a/clang/test/Misc/target-invalid-cpu-note/systemz.c b/clang/test/Misc/target-invalid-cpu-note/systemz.c new file mode 100644 index 00000000000000..22b0208eca902d --- /dev/null +++ b/clang/test/Misc/target-invalid-cpu-note/systemz.c @@ -0,0 +1,22 @@ +// This test uses '-SAME: {{^}}' to start matching immediately where the +// previous check finished matching (specifically, caret is not treated as +// matching a start of line when used like this in FileCheck). + +// RUN: not %clang_cc1 -triple systemz--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s +// CHECK: error: unknown target CPU 'not-a-cpu' +// CHECK-NEXT: note: valid target CPU values are: +// CHECK-SAME: {{^}} arch8 +// CHECK-SAME: {{^}}, z10 +// CHECK-SAME: {{^}}, arch9 +// CHECK-SAME: {{^}}, z196 +// CHECK-SAME: {{^}}, arch10 +// CHECK-SAME: {{^}}, zEC12 +// CHECK-SAME: {{^}}, arch11 +// CHECK-SAME: {{^}}, z13 +// CHECK-SAME: {{^}}, arch12 +// CHECK-SAME: {{^}}, z14 +// CHECK-SAME: {{^}}, arch13 +// CHECK-SAME: {{^}}, z15 +// CHECK-SAME: {{^}}, arch14 +// CHECK-SAME: {{^}}, z16 +// CHECK-SAME: {{$}} diff --git a/clang/test/Misc/target-invalid-cpu-note/wasm.c b/clang/test/Misc/target-invalid-cpu-note/wasm.c new file mode 100644 index 00000000000000..c90b2fe151e33f --- /dev/null +++ b/clang/test/Misc/target-invalid-cpu-note/wasm.c @@ -0,0 +1,11 @@ +// This test uses '-SAME: {{^}}' to start matching immediately where the +// previous check finished matching (specifically, caret is not treated as +// matching a start of line when used like this in FileCheck). + +// RUN: not %clang_cc1 -triple wasm64--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s +// CHECK: error: unknown target CPU 'not-a-cpu' +// CHECK-NEXT: note: valid target CPU values are: +// CHECK-SAME: {{^}} mvp +// CHECK-SAME: {{^}}, bleeding-edge +// CHECK-SAME: {{^}}, generic +// CHECK-SAME: {{$}} diff --git a/clang/test/Misc/target-invalid-cpu-note/x86.c b/clang/test/Misc/target-invalid-cpu-note/x86.c new file mode 100644 index 00000000000000..607192a5409ba8 --- /dev/null +++ b/clang/test/Misc/target-invalid-cpu-note/x86.c @@ -0,0 +1,384 @@ +// This test uses '-SAME: {{^}}' to start matching immediately where the +// previous check finished matching (specifically, caret is not treated as +// matching a start of line when used like this in FileCheck). + +// RUN: not %clang_cc1 -triple i386--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix X86 +// X86: error: unknown target CPU 'not-a-cpu' +// X86-NEXT: note: valid target CPU values are: +// X86-SAME: {{^}} i386 +// X86-SAME: {{^}}, i486 +// X86-SAME: {{^}}, winchip-c6 +// X86-SAME: {{^}}, winchip2 +// X86-SAME: {{^}}, c3 +// X86-SAME: {{^}}, i586 +// X86-SAME: {{^}}, pentium +// X86-SAME: {{^}}, pentium-mmx +// X86-SAME: {{^}}, pentiumpro +// X86-SAME: {{^}}, i686 +// X86-SAME: {{^}}, pentium2 +// X86-SAME: {{^}}, pentium3 +// X86-SAME: {{^}}, pentium3m +// X86-SAME: {{^}}, pentium-m +// X86-SAME: {{^}}, c3-2 +// X86-SAME: {{^}}, yonah +// X86-SAME: {{^}}, pentium4 +// X86-SAME: {{^}}, pentium4m +// X86-SAME: {{^}}, prescott +// X86-SAME: {{^}}, nocona +// X86-SAME: {{^}}, core2 +// X86-SAME: {{^}}, penryn +// X86-SAME: {{^}}, bonnell +// X86-SAME: {{^}}, atom +// X86-SAME: {{^}}, silvermont +// X86-SAME: {{^}}, slm +// X86-SAME: {{^}}, goldmont +// X86-SAME: {{^}}, goldmont-plus +// X86-SAME: {{^}}, tremont +// X86-SAME: {{^}}, nehalem +// X86-SAME: {{^}}, corei7 +// X86-SAME: {{^}}, westmere +// X86-SAME: {{^}}, sandybridge +// X86-SAME: {{^}}, corei7-avx +// X86-SAME: {{^}}, ivybridge +// X86-SAME: {{^}}, core-avx-i +// X86-SAME: {{^}}, haswell +// X86-SAME: {{^}}, core-avx2 +// X86-SAME: {{^}}, broadwell +// X86-SAME: {{^}}, skylake +// X86-SAME: {{^}}, skylake-avx512 +// X86-SAME: {{^}}, skx +// X86-SAME: {{^}}, cascadelake +// X86-SAME: {{^}}, cooperlake +// X86-SAME: {{^}}, cannonlake +// X86-SAME: {{^}}, icelake-client +// X86-SAME: {{^}}, rocketlake +// X86-SAME: {{^}}, icelake-server +// X86-SAME: {{^}}, tigerlake +// X86-SAME: {{^}}, sapphirerapids +// X86-SAME: {{^}}, alderlake +// X86-SAME: {{^}}, raptorlake +// X86-SAME: {{^}}, meteorlake +// X86-SAME: {{^}}, arrowlake +// X86-SAME: {{^}}, arrowlake-s +// X86-SAME: {{^}}, lunarlake +// X86-SAME: {{^}}, gracemont +// X86-SAME: {{^}}, pantherlake +// X86-SAME: {{^}}, sierraforest +// X86-SAME: {{^}}, grandridge +// X86-SAME: {{^}}, graniterapids +// X86-SAME: {{^}}, graniterapids-d +// X86-SAME: {{^}}, emeraldrapids +// X86-SAME: {{^}}, clearwaterforest +// X86-SAME: {{^}}, knl +// X86-SAME: {{^}}, knm +// X86-SAME: {{^}}, lakemont +// X86-SAME: {{^}}, k6 +// X86-SAME: {{^}}, k6-2 +// X86-SAME: {{^}}, k6-3 +// X86-SAME: {{^}}, athlon +// X86-SAME: {{^}}, athlon-tbird +// X86-SAME: {{^}}, athlon-xp +// X86-SAME: {{^}}, athlon-mp +// X86-SAME: {{^}}, athlon-4 +// X86-SAME: {{^}}, k8 +// X86-SAME: {{^}}, athlon64 +// X86-SAME: {{^}}, athlon-fx +// X86-SAME: {{^}}, opteron +// X86-SAME: {{^}}, k8-sse3 +// X86-SAME: {{^}}, athlon64-sse3 +// X86-SAME: {{^}}, opteron-sse3 +// X86-SAME: {{^}}, amdfam10 +// X86-SAME: {{^}}, barcelona +// X86-SAME: {{^}}, btver1 +// X86-SAME: {{^}}, btver2 +// X86-SAME: {{^}}, bdver1 +// X86-SAME: {{^}}, bdver2 +// X86-SAME: {{^}}, bdver3 +// X86-SAME: {{^}}, bdver4 +// X86-SAME: {{^}}, znver1 +// X86-SAME: {{^}}, znver2 +// X86-SAME: {{^}}, znver3 +// X86-SAME: {{^}}, znver4 +// X86-SAME: {{^}}, x86-64 +// X86-SAME: {{^}}, x86-64-v2 +// X86-SAME: {{^}}, x86-64-v3 +// X86-SAME: {{^}}, x86-64-v4 +// X86-SAME: {{^}}, geode +// X86-SAME: {{$}} + +// RUN: not %clang_cc1 -triple x86_64--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix=X86_64 +// X86_64: error: unknown target CPU 'not-a-cpu' +// X86_64-NEXT: note: valid target CPU values are: +// X86_64-SAME: {{^}} nocona +// X86_64-SAME: {{^}}, core2 +// X86_64-SAME: {{^}}, penryn +// X86_64-SAME: {{^}}, bonnell +// X86_64-SAME: {{^}}, atom +// X86_64-SAME: {{^}}, silvermont +// X86_64-SAME: {{^}}, slm +// X86_64-SAME: {{^}}, goldmont +// X86_64-SAME: {{^}}, goldmont-plus +// X86_64-SAME: {{^}}, tremont +// X86_64-SAME: {{^}}, nehalem +// X86_64-SAME: {{^}}, corei7 +// X86_64-SAME: {{^}}, westmere +// X86_64-SAME: {{^}}, sandybridge +// X86_64-SAME: {{^}}, corei7-avx +// X86_64-SAME: {{^}}, ivybridge +// X86_64-SAME: {{^}}, core-avx-i +// X86_64-SAME: {{^}}, haswell +// X86_64-SAME: {{^}}, core-avx2 +// X86_64-SAME: {{^}}, broadwell +// X86_64-SAME: {{^}}, skylake +// X86_64-SAME: {{^}}, skylake-avx512 +// X86_64-SAME: {{^}}, skx +// X86_64-SAME: {{^}}, cascadelake +// X86_64-SAME: {{^}}, cooperlake +// X86_64-SAME: {{^}}, cannonlake +// X86_64-SAME: {{^}}, icelake-client +// X86_64-SAME: {{^}}, rocketlake +// X86_64-SAME: {{^}}, icelake-server +// X86_64-SAME: {{^}}, tigerlake +// X86_64-SAME: {{^}}, sapphirerapids +// X86_64-SAME: {{^}}, alderlake +// X86_64-SAME: {{^}}, raptorlake +// X86_64-SAME: {{^}}, meteorlake +// X86_64-SAME: {{^}}, arrowlake +// X86_64-SAME: {{^}}, arrowlake-s +// X86_64-SAME: {{^}}, lunarlake +// X86_64-SAME: {{^}}, gracemont +// X86_64-SAME: {{^}}, pantherlake +// X86_64-SAME: {{^}}, sierraforest +// X86_64-SAME: {{^}}, grandridge +// X86_64-SAME: {{^}}, graniterapids +// X86_64-SAME: {{^}}, graniterapids-d +// X86_64-SAME: {{^}}, emeraldrapids +// X86_64-SAME: {{^}}, clearwaterforest +// X86_64-SAME: {{^}}, knl +// X86_64-SAME: {{^}}, knm +// X86_64-SAME: {{^}}, k8 +// X86_64-SAME: {{^}}, athlon64 +// X86_64-SAME: {{^}}, athlon-fx +// X86_64-SAME: {{^}}, opteron +// X86_64-SAME: {{^}}, k8-sse3 +// X86_64-SAME: {{^}}, athlon64-sse3 +// X86_64-SAME: {{^}}, opteron-sse3 +// X86_64-SAME: {{^}}, amdfam10 +// X86_64-SAME: {{^}}, barcelona +// X86_64-SAME: {{^}}, btver1 +// X86_64-SAME: {{^}}, btver2 +// X86_64-SAME: {{^}}, bdver1 +// X86_64-SAME: {{^}}, bdver2 +// X86_64-SAME: {{^}}, bdver3 +// X86_64-SAME: {{^}}, bdver4 +// X86_64-SAME: {{^}}, znver1 +// X86_64-SAME: {{^}}, znver2 +// X86_64-SAME: {{^}}, znver3 +// X86_64-SAME: {{^}}, znver4 +// X86_64-SAME: {{^}}, x86-64 +// X86_64-SAME: {{^}}, x86-64-v2 +// X86_64-SAME: {{^}}, x86-64-v3 +// X86_64-SAME: {{^}}, x86-64-v4 +// X86_64-SAME: {{$}} + +// RUN: not %clang_cc1 -triple i386--- -tune-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix=TUNE_X86 +// TUNE_X86: error: unknown target CPU 'not-a-cpu' +// TUNE_X86-NEXT: note: valid target CPU values are: +// TUNE_X86-SAME: {{^}} i386 +// TUNE_X86-SAME: {{^}}, i486 +// TUNE_X86-SAME: {{^}}, winchip-c6 +// TUNE_X86-SAME: {{^}}, winchip2 +// TUNE_X86-SAME: {{^}}, c3 +// TUNE_X86-SAME: {{^}}, i586 +// TUNE_X86-SAME: {{^}}, pentium +// TUNE_X86-SAME: {{^}}, pentium-mmx +// TUNE_X86-SAME: {{^}}, pentiumpro +// TUNE_X86-SAME: {{^}}, i686 +// TUNE_X86-SAME: {{^}}, pentium2 +// TUNE_X86-SAME: {{^}}, pentium3 +// TUNE_X86-SAME: {{^}}, pentium3m +// TUNE_X86-SAME: {{^}}, pentium-m +// TUNE_X86-SAME: {{^}}, c3-2 +// TUNE_X86-SAME: {{^}}, yonah +// TUNE_X86-SAME: {{^}}, pentium4 +// TUNE_X86-SAME: {{^}}, pentium4m +// TUNE_X86-SAME: {{^}}, prescott +// TUNE_X86-SAME: {{^}}, nocona +// TUNE_X86-SAME: {{^}}, core2 +// TUNE_X86-SAME: {{^}}, penryn +// TUNE_X86-SAME: {{^}}, bonnell +// TUNE_X86-SAME: {{^}}, atom +// TUNE_X86-SAME: {{^}}, silvermont +// TUNE_X86-SAME: {{^}}, slm +// TUNE_X86-SAME: {{^}}, goldmont +// TUNE_X86-SAME: {{^}}, goldmont-plus +// TUNE_X86-SAME: {{^}}, tremont +// TUNE_X86-SAME: {{^}}, nehalem +// TUNE_X86-SAME: {{^}}, corei7 +// TUNE_X86-SAME: {{^}}, westmere +// TUNE_X86-SAME: {{^}}, sandybridge +// TUNE_X86-SAME: {{^}}, corei7-avx +// TUNE_X86-SAME: {{^}}, ivybridge +// TUNE_X86-SAME: {{^}}, core-avx-i +// TUNE_X86-SAME: {{^}}, haswell +// TUNE_X86-SAME: {{^}}, core-avx2 +// TUNE_X86-SAME: {{^}}, broadwell +// TUNE_X86-SAME: {{^}}, skylake +// TUNE_X86-SAME: {{^}}, skylake-avx512 +// TUNE_X86-SAME: {{^}}, skx +// TUNE_X86-SAME: {{^}}, cascadelake +// TUNE_X86-SAME: {{^}}, cooperlake +// TUNE_X86-SAME: {{^}}, cannonlake +// TUNE_X86-SAME: {{^}}, icelake-client +// TUNE_X86-SAME: {{^}}, rocketlake +// TUNE_X86-SAME: {{^}}, icelake-server +// TUNE_X86-SAME: {{^}}, tigerlake +// TUNE_X86-SAME: {{^}}, sapphirerapids +// TUNE_X86-SAME: {{^}}, alderlake +// TUNE_X86-SAME: {{^}}, raptorlake +// TUNE_X86-SAME: {{^}}, meteorlake +// TUNE_X86-SAME: {{^}}, arrowlake +// TUNE_X86-SAME: {{^}}, arrowlake-s +// TUNE_X86-SAME: {{^}}, lunarlake +// TUNE_X86-SAME: {{^}}, gracemont +// TUNE_X86-SAME: {{^}}, pantherlake +// TUNE_X86-SAME: {{^}}, sierraforest +// TUNE_X86-SAME: {{^}}, grandridge +// TUNE_X86-SAME: {{^}}, graniterapids +// TUNE_X86-SAME: {{^}}, graniterapids-d +// TUNE_X86-SAME: {{^}}, emeraldrapids +// TUNE_X86-SAME: {{^}}, clearwaterforest +// TUNE_X86-SAME: {{^}}, knl +// TUNE_X86-SAME: {{^}}, knm +// TUNE_X86-SAME: {{^}}, lakemont +// TUNE_X86-SAME: {{^}}, k6 +// TUNE_X86-SAME: {{^}}, k6-2 +// TUNE_X86-SAME: {{^}}, k6-3 +// TUNE_X86-SAME: {{^}}, athlon +// TUNE_X86-SAME: {{^}}, athlon-tbird +// TUNE_X86-SAME: {{^}}, athlon-xp +// TUNE_X86-SAME: {{^}}, athlon-mp +// TUNE_X86-SAME: {{^}}, athlon-4 +// TUNE_X86-SAME: {{^}}, k8 +// TUNE_X86-SAME: {{^}}, athlon64 +// TUNE_X86-SAME: {{^}}, athlon-fx +// TUNE_X86-SAME: {{^}}, opteron +// TUNE_X86-SAME: {{^}}, k8-sse3 +// TUNE_X86-SAME: {{^}}, athlon64-sse3 +// TUNE_X86-SAME: {{^}}, opteron-sse3 +// TUNE_X86-SAME: {{^}}, amdfam10 +// TUNE_X86-SAME: {{^}}, barcelona +// TUNE_X86-SAME: {{^}}, btver1 +// TUNE_X86-SAME: {{^}}, btver2 +// TUNE_X86-SAME: {{^}}, bdver1 +// TUNE_X86-SAME: {{^}}, bdver2 +// TUNE_X86-SAME: {{^}}, bdver3 +// TUNE_X86-SAME: {{^}}, bdver4 +// TUNE_X86-SAME: {{^}}, znver1 +// TUNE_X86-SAME: {{^}}, znver2 +// TUNE_X86-SAME: {{^}}, znver3 +// TUNE_X86-SAME: {{^}}, znver4 +// TUNE_X86-SAME: {{^}}, x86-64 +// TUNE_X86-SAME: {{^}}, geode +// TUNE_X86-SAME: {{$}} + +// RUN: not %clang_cc1 -triple x86_64--- -tune-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix=TUNE_X86_64 +// TUNE_X86_64: error: unknown target CPU 'not-a-cpu' +// TUNE_X86_64-NEXT: note: valid target CPU values are: +// TUNE_X86_64-SAME: {{^}} i386 +// TUNE_X86_64-SAME: {{^}}, i486 +// TUNE_X86_64-SAME: {{^}}, winchip-c6 +// TUNE_X86_64-SAME: {{^}}, winchip2 +// TUNE_X86_64-SAME: {{^}}, c3 +// TUNE_X86_64-SAME: {{^}}, i586 +// TUNE_X86_64-SAME: {{^}}, pentium +// TUNE_X86_64-SAME: {{^}}, pentium-mmx +// TUNE_X86_64-SAME: {{^}}, pentiumpro +// TUNE_X86_64-SAME: {{^}}, i686 +// TUNE_X86_64-SAME: {{^}}, pentium2 +// TUNE_X86_64-SAME: {{^}}, pentium3 +// TUNE_X86_64-SAME: {{^}}, pentium3m +// TUNE_X86_64-SAME: {{^}}, pentium-m +// TUNE_X86_64-SAME: {{^}}, c3-2 +// TUNE_X86_64-SAME: {{^}}, yonah +// TUNE_X86_64-SAME: {{^}}, pentium4 +// TUNE_X86_64-SAME: {{^}}, pentium4m +// TUNE_X86_64-SAME: {{^}}, prescott +// TUNE_X86_64-SAME: {{^}}, nocona +// TUNE_X86_64-SAME: {{^}}, core2 +// TUNE_X86_64-SAME: {{^}}, penryn +// TUNE_X86_64-SAME: {{^}}, bonnell +// TUNE_X86_64-SAME: {{^}}, atom +// TUNE_X86_64-SAME: {{^}}, silvermont +// TUNE_X86_64-SAME: {{^}}, slm +// TUNE_X86_64-SAME: {{^}}, goldmont +// TUNE_X86_64-SAME: {{^}}, goldmont-plus +// TUNE_X86_64-SAME: {{^}}, tremont +// TUNE_X86_64-SAME: {{^}}, nehalem +// TUNE_X86_64-SAME: {{^}}, corei7 +// TUNE_X86_64-SAME: {{^}}, westmere +// TUNE_X86_64-SAME: {{^}}, sandybridge +// TUNE_X86_64-SAME: {{^}}, corei7-avx +// TUNE_X86_64-SAME: {{^}}, ivybridge +// TUNE_X86_64-SAME: {{^}}, core-avx-i +// TUNE_X86_64-SAME: {{^}}, haswell +// TUNE_X86_64-SAME: {{^}}, core-avx2 +// TUNE_X86_64-SAME: {{^}}, broadwell +// TUNE_X86_64-SAME: {{^}}, skylake +// TUNE_X86_64-SAME: {{^}}, skylake-avx512 +// TUNE_X86_64-SAME: {{^}}, skx +// TUNE_X86_64-SAME: {{^}}, cascadelake +// TUNE_X86_64-SAME: {{^}}, cooperlake +// TUNE_X86_64-SAME: {{^}}, cannonlake +// TUNE_X86_64-SAME: {{^}}, icelake-client +// TUNE_X86_64-SAME: {{^}}, rocketlake +// TUNE_X86_64-SAME: {{^}}, icelake-server +// TUNE_X86_64-SAME: {{^}}, tigerlake +// TUNE_X86_64-SAME: {{^}}, sapphirerapids +// TUNE_X86_64-SAME: {{^}}, alderlake +// TUNE_X86_64-SAME: {{^}}, raptorlake +// TUNE_X86_64-SAME: {{^}}, meteorlake +// TUNE_X86_64-SAME: {{^}}, arrowlake +// TUNE_X86_64-SAME: {{^}}, arrowlake-s +// TUNE_X86_64-SAME: {{^}}, lunarlake +// TUNE_X86_64-SAME: {{^}}, gracemont +// TUNE_X86_64-SAME: {{^}}, pantherlake +// TUNE_X86_64-SAME: {{^}}, sierraforest +// TUNE_X86_64-SAME: {{^}}, grandridge +// TUNE_X86_64-SAME: {{^}}, graniterapids +// TUNE_X86_64-SAME: {{^}}, graniterapids-d +// TUNE_X86_64-SAME: {{^}}, emeraldrapids +// TUNE_X86_64-SAME: {{^}}, clearwaterforest +// TUNE_X86_64-SAME: {{^}}, knl +// TUNE_X86_64-SAME: {{^}}, knm +// TUNE_X86_64-SAME: {{^}}, lakemont +// TUNE_X86_64-SAME: {{^}}, k6 +// TUNE_X86_64-SAME: {{^}}, k6-2 +// TUNE_X86_64-SAME: {{^}}, k6-3 +// TUNE_X86_64-SAME: {{^}}, athlon +// TUNE_X86_64-SAME: {{^}}, athlon-tbird +// TUNE_X86_64-SAME: {{^}}, athlon-xp +// TUNE_X86_64-SAME: {{^}}, athlon-mp +// TUNE_X86_64-SAME: {{^}}, athlon-4 +// TUNE_X86_64-SAME: {{^}}, k8 +// TUNE_X86_64-SAME: {{^}}, athlon64 +// TUNE_X86_64-SAME: {{^}}, athlon-fx +// TUNE_X86_64-SAME: {{^}}, opteron +// TUNE_X86_64-SAME: {{^}}, k8-sse3 +// TUNE_X86_64-SAME: {{^}}, athlon64-sse3 +// TUNE_X86_64-SAME: {{^}}, opteron-sse3 +// TUNE_X86_64-SAME: {{^}}, amdfam10 +// TUNE_X86_64-SAME: {{^}}, barcelona +// TUNE_X86_64-SAME: {{^}}, btver1 +// TUNE_X86_64-SAME: {{^}}, btver2 +// TUNE_X86_64-SAME: {{^}}, bdver1 +// TUNE_X86_64-SAME: {{^}}, bdver2 +// TUNE_X86_64-SAME: {{^}}, bdver3 +// TUNE_X86_64-SAME: {{^}}, bdver4 +// TUNE_X86_64-SAME: {{^}}, znver1 +// TUNE_X86_64-SAME: {{^}}, znver2 +// TUNE_X86_64-SAME: {{^}}, znver3 +// TUNE_X86_64-SAME: {{^}}, znver4 +// TUNE_X86_64-SAME: {{^}}, x86-64 +// TUNE_X86_64-SAME: {{^}}, geode +// TUNE_X86_64-SAME: {{$}} diff --git a/clang/test/OpenMP/nvptx_allocate_codegen.cpp b/clang/test/OpenMP/nvptx_allocate_codegen.cpp index 3f3457dab33c2d..4f38e2c50efe3c 100644 --- a/clang/test/OpenMP/nvptx_allocate_codegen.cpp +++ b/clang/test/OpenMP/nvptx_allocate_codegen.cpp @@ -87,10 +87,9 @@ void bar() { // CHECK1-SAME: () #[[ATTR0:[0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 -// CHECK1-NEXT: [[B:%.*]] = alloca double, align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: store i32 2, ptr @_ZZ4mainE1a, align 4 -// CHECK1-NEXT: store double 3.000000e+00, ptr [[B]], align 8 +// CHECK1-NEXT: store double 3.000000e+00, ptr @b1, align 8 // CHECK1-NEXT: [[CALL:%.*]] = call noundef i32 @_Z3fooIiET_v() #[[ATTR7:[0-9]+]] // CHECK1-NEXT: ret i32 [[CALL]] // diff --git a/clang/test/Sema/format-pointer.c b/clang/test/Sema/format-pointer.c new file mode 100644 index 00000000000000..2a94df01124eec --- /dev/null +++ b/clang/test/Sema/format-pointer.c @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -Wformat %s -verify +// RUN: %clang_cc1 -Wformat -std=c23 %s -verify +// RUN: %clang_cc1 -xc++ -Wformat %s -verify +// RUN: %clang_cc1 -xobjective-c -Wformat -fblocks %s -verify +// RUN: %clang_cc1 -xobjective-c++ -Wformat -fblocks %s -verify +// RUN: %clang_cc1 -std=c23 -Wformat %s -pedantic -verify=expected,pedantic +// RUN: %clang_cc1 -xc++ -Wformat %s -pedantic -verify=expected,pedantic +// RUN: %clang_cc1 -xobjective-c -Wformat -fblocks -pedantic %s -verify=expected,pedantic + +__attribute__((__format__(__printf__, 1, 2))) +int printf(const char *, ...); +__attribute__((__format__(__scanf__, 1, 2))) +int scanf(const char *, ...); + +void f(void *vp, const void *cvp, char *cp, signed char *scp, int *ip) { + int arr[2]; + + printf("%p", cp); + printf("%p", cvp); + printf("%p", vp); + printf("%p", scp); + printf("%p", ip); // pedantic-warning {{format specifies type 'void *' but the argument has type 'int *'}} + printf("%p", arr); // pedantic-warning {{format specifies type 'void *' but the argument has type 'int *'}} + + scanf("%p", &vp); + scanf("%p", &cvp); + scanf("%p", (void *volatile*)&vp); + scanf("%p", (const void *volatile*)&cvp); + scanf("%p", &cp); // pedantic-warning {{format specifies type 'void **' but the argument has type 'char **'}} + scanf("%p", &ip); // pedantic-warning {{format specifies type 'void **' but the argument has type 'int **'}} + scanf("%p", &arr); // expected-warning {{format specifies type 'void **' but the argument has type 'int (*)[2]'}} + +#if !__is_identifier(nullptr) + typedef __typeof__(nullptr) nullptr_t; + nullptr_t np = nullptr; + nullptr_t *npp = &np; + + printf("%p", np); + scanf("%p", &np); // expected-warning {{format specifies type 'void **' but the argument has type 'nullptr_t *'}} + scanf("%p", &npp); // pedantic-warning {{format specifies type 'void **' but the argument has type 'nullptr_t **'}} +#endif + +#ifdef __OBJC__ + id i = 0; + void (^b)(void) = ^{}; + + printf("%p", i); // pedantic-warning {{format specifies type 'void *' but the argument has type 'id'}} + printf("%p", b); // pedantic-warning {{format specifies type 'void *' but the argument has type 'void (^)(void)'}} + scanf("%p", &i); // pedantic-warning {{format specifies type 'void **' but the argument has type 'id *'}} + scanf("%p", &b); // pedantic-warning {{format specifies type 'void **' but the argument has type 'void (^*)(void)'}} +#endif + +} diff --git a/clang/test/Sema/format-strings-pedantic.c b/clang/test/Sema/format-strings-pedantic.c index 76668978fadfe1..65387837e272a0 100644 --- a/clang/test/Sema/format-strings-pedantic.c +++ b/clang/test/Sema/format-strings-pedantic.c @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify -Wno-format -Wformat-pedantic %s // RUN: %clang_cc1 -xobjective-c -fblocks -fsyntax-only -verify -Wno-format -Wformat-pedantic %s // RUN: %clang_cc1 -xc++ -fsyntax-only -verify -Wno-format -Wformat-pedantic %s +// RUN: %clang_cc1 -std=c23 -fsyntax-only -verify -Wno-format -Wformat-pedantic %s __attribute__((format(printf, 1, 2))) int printf(const char *restrict, ...); @@ -14,7 +15,7 @@ int main(void) { printf("%p", (id)0); // expected-warning {{format specifies type 'void *' but the argument has type 'id'}} #endif -#ifdef __cplusplus - printf("%p", nullptr); // expected-warning {{format specifies type 'void *' but the argument has type 'std::nullptr_t'}} +#if !__is_identifier(nullptr) + printf("%p", nullptr); #endif } diff --git a/clang/test/SemaHLSL/BuiltIns/saturate-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/saturate-errors.hlsl new file mode 100644 index 00000000000000..721b28f86f950f --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/saturate-errors.hlsl @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -verify-ignore-unexpected -Werror + +float2 test_no_arg() { + return saturate(); + // expected-error@-1 {{no matching function for call to 'saturate'}} +} + +float2 test_too_many_arg(float2 p0) { + return saturate(p0, p0, p0, p0); + // expected-error@-1 {{no matching function for call to 'saturate'}} +} + +float2 test_saturate_vector_size_mismatch(float3 p0) { + return saturate(p0); + // expected-error@-1 {{implicit conversion truncates vector: 'float3' (aka 'vector') to 'vector'}} +} + +float2 test_saturate_float2_int_splat(int p0) { + return saturate(p0); + // expected-error@-1 {{call to 'saturate' is ambiguous}} +} + +float2 test_saturate_int_vect_to_float_vec_promotion(int2 p0) { + return saturate(p0); + // expected-error@-1 {{call to 'saturate' is ambiguous}} +} + +float test_saturate_bool_type_promotion(bool p0) { + return saturate(p0); + // expected-error@-1 {{call to 'saturate' is ambiguous}} +} diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp index 47a71134d50273..028392f499da3b 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -1745,6 +1745,18 @@ TEST(MatchBinaryOperator, HasOperands) { EXPECT_TRUE(notMatches("void x() { 0 + 1; }", HasOperands)); } +TEST(MatchBinaryOperator, HasOperandsEnsureOrdering) { + StatementMatcher HasOperandsWithBindings = binaryOperator(hasOperands( + cStyleCastExpr(has(declRefExpr(hasDeclaration(valueDecl().bind("d"))))), + declRefExpr(hasDeclaration(valueDecl(equalsBoundNode("d")))))); + EXPECT_TRUE(matches( + "int a; int b = ((int) a) + a;", + traverse(TK_IgnoreUnlessSpelledInSource, HasOperandsWithBindings))); + EXPECT_TRUE(matches( + "int a; int b = a + ((int) a);", + traverse(TK_IgnoreUnlessSpelledInSource, HasOperandsWithBindings))); +} + TEST(Matcher, BinaryOperatorTypes) { // Integration test that verifies the AST provides all binary operators in // a way we expect. diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html index 23657431233860..e6c955a5c0e255 100755 --- a/clang/www/cxx_dr_status.html +++ b/clang/www/cxx_dr_status.html @@ -4381,7 +4381,7 @@

C++ defect report implementation status

722 CD2 Can nullptr be passed to an ellipsis? - Unknown + Clang 20 726 diff --git a/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp b/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp index eefa0b326e51b5..fe79e1908d6029 100644 --- a/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp @@ -607,13 +607,7 @@ size_t PageSize() { } void SetThreadName(std::thread &thread, const std::string &name) { - if (name.size() > 31) - name.resize(31); - zx_status_t s; - if ((s = zx_object_set_property(thread.native_handle(), ZX_PROP_NAME, - name.c_str(), name.size())) != ZX_OK) - Printf("SetThreadName for name %s failed: %s", name.c_str(), - zx_status_get_string(s)); + // TODO ? } } // namespace fuzzer diff --git a/flang/include/flang/Evaluate/real.h b/flang/include/flang/Evaluate/real.h index cb3c0036e0cfae..11cc8f776b0e95 100644 --- a/flang/include/flang/Evaluate/real.h +++ b/flang/include/flang/Evaluate/real.h @@ -281,7 +281,7 @@ template class Real { } if constexpr (bits == 80) { // x87 // 7FFF8000000000000000 is Infinity, not NaN, on 80387 & later. - infinity.IBSET(63); + infinity = infinity.IBSET(63); } return {infinity}; } diff --git a/flang/lib/Evaluate/fold-real.cpp b/flang/lib/Evaluate/fold-real.cpp index 15a9bcf6dbd854..fd8eca28a679c1 100644 --- a/flang/lib/Evaluate/fold-real.cpp +++ b/flang/lib/Evaluate/fold-real.cpp @@ -468,11 +468,9 @@ Expr> FoldIntrinsicFunction( return FoldElementalIntrinsic(context, std::move(funcRef), ScalarFunc([&](const Scalar &x, const Scalar &y) -> Scalar { - bool reverseCompare{ - Scalar::binaryPrecision < Scalar::binaryPrecision}; - switch (reverseCompare - ? y.Compare(Scalar::Convert(x).value) - : x.Compare(Scalar::Convert(y).value)) { + auto xBig{Scalar::Convert(x).value}; + auto yBig{Scalar::Convert(y).value}; + switch (xBig.Compare(yBig)) { case Relation::Unordered: if (context.languageFeatures().ShouldWarn( common::UsageWarning::FoldingValueChecks)) { @@ -483,9 +481,9 @@ Expr> FoldIntrinsicFunction( case Relation::Equal: break; case Relation::Less: - return x.NEAREST(!reverseCompare).value; + return x.NEAREST(true).value; case Relation::Greater: - return x.NEAREST(reverseCompare).value; + return x.NEAREST(false).value; } return x; // dodge bogus "missing return" GCC warning })); diff --git a/flang/lib/Lower/OpenMP/Decomposer.cpp b/flang/lib/Lower/OpenMP/Decomposer.cpp index dfd85897469e28..33568bf96b5dfb 100644 --- a/flang/lib/Lower/OpenMP/Decomposer.cpp +++ b/flang/lib/Lower/OpenMP/Decomposer.cpp @@ -22,7 +22,6 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Frontend/OpenMP/ClauseT.h" -#include "llvm/Frontend/OpenMP/ConstructCompositionT.h" #include "llvm/Frontend/OpenMP/ConstructDecompositionT.h" #include "llvm/Frontend/OpenMP/OMP.h" #include "llvm/Support/raw_ostream.h" @@ -68,12 +67,6 @@ struct ConstructDecomposition { }; } // namespace -static UnitConstruct mergeConstructs(uint32_t version, - llvm::ArrayRef units) { - tomp::ConstructCompositionT compose(version, units); - return compose.merged; -} - namespace Fortran::lower::omp { LLVM_DUMP_METHOD llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const UnitConstruct &uc) { @@ -90,38 +83,37 @@ ConstructQueue buildConstructQueue( Fortran::lower::pft::Evaluation &eval, const parser::CharBlock &source, llvm::omp::Directive compound, const List &clauses) { - List constructs; - ConstructDecomposition decompose(modOp, semaCtx, eval, compound, clauses); assert(!decompose.output.empty() && "Construct decomposition failed"); - llvm::SmallVector loweringUnits; - std::ignore = - llvm::omp::getLeafOrCompositeConstructs(compound, loweringUnits); - uint32_t version = getOpenMPVersionAttribute(modOp); - - int leafIndex = 0; - for (llvm::omp::Directive dir_id : loweringUnits) { - llvm::ArrayRef leafsOrSelf = - llvm::omp::getLeafConstructsOrSelf(dir_id); - size_t numLeafs = leafsOrSelf.size(); - - llvm::ArrayRef toMerge{&decompose.output[leafIndex], - numLeafs}; - auto &uc = constructs.emplace_back(mergeConstructs(version, toMerge)); - - if (!transferLocations(clauses, uc.clauses)) { - // If some clauses are left without source information, use the - // directive's source. - for (auto &clause : uc.clauses) { - if (clause.source.empty()) - clause.source = source; - } - } - leafIndex += numLeafs; + for (UnitConstruct &uc : decompose.output) { + assert(getLeafConstructs(uc.id).empty() && "unexpected compound directive"); + // If some clauses are left without source information, use the directive's + // source. + for (auto &clause : uc.clauses) + if (clause.source.empty()) + clause.source = source; + } + + return decompose.output; +} + +bool matchLeafSequence(ConstructQueue::const_iterator item, + const ConstructQueue &queue, + llvm::omp::Directive directive) { + llvm::ArrayRef leafDirs = + llvm::omp::getLeafConstructsOrSelf(directive); + + for (auto [dir, leaf] : + llvm::zip_longest(leafDirs, llvm::make_range(item, queue.end()))) { + if (!dir.has_value() || !leaf.has_value()) + return false; + + if (*dir != leaf->id) + return false; } - return constructs; + return true; } bool isLastItemInQueue(ConstructQueue::const_iterator item, diff --git a/flang/lib/Lower/OpenMP/Decomposer.h b/flang/lib/Lower/OpenMP/Decomposer.h index e85956ffe1a231..e3291b7c59e216 100644 --- a/flang/lib/Lower/OpenMP/Decomposer.h +++ b/flang/lib/Lower/OpenMP/Decomposer.h @@ -10,7 +10,6 @@ #include "Clauses.h" #include "mlir/IR/BuiltinOps.h" -#include "llvm/Frontend/OpenMP/ConstructCompositionT.h" #include "llvm/Frontend/OpenMP/ConstructDecompositionT.h" #include "llvm/Frontend/OpenMP/OMP.h" #include "llvm/Support/Compiler.h" @@ -49,6 +48,15 @@ ConstructQueue buildConstructQueue(mlir::ModuleOp modOp, bool isLastItemInQueue(ConstructQueue::const_iterator item, const ConstructQueue &queue); + +/// Try to match the leaf constructs conforming the given \c directive to the +/// range of leaf constructs starting from \c item to the end of the \c queue. +/// If \c directive doesn't represent a compound directive, check that \c item +/// matches that directive and is the only element before the end of the +/// \c queue. +bool matchLeafSequence(ConstructQueue::const_iterator item, + const ConstructQueue &queue, + llvm::omp::Directive directive); } // namespace Fortran::lower::omp #endif // FORTRAN_LOWER_OPENMP_DECOMPOSER_H diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index 64b581e8910d07..d614db8b68ef65 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -2044,6 +2044,7 @@ static void genCompositeDistributeParallelDoSimd( semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, mlir::Location loc, const ConstructQueue &queue, ConstructQueue::const_iterator item, DataSharingProcessor &dsp) { + assert(std::distance(item, queue.end()) == 4 && "Invalid leaf constructs"); TODO(loc, "Composite DISTRIBUTE PARALLEL DO SIMD"); } @@ -2054,17 +2055,23 @@ static void genCompositeDistributeSimd( ConstructQueue::const_iterator item, DataSharingProcessor &dsp) { lower::StatementContext stmtCtx; + assert(std::distance(item, queue.end()) == 2 && "Invalid leaf constructs"); + ConstructQueue::const_iterator distributeItem = item; + ConstructQueue::const_iterator simdItem = std::next(distributeItem); + // Clause processing. mlir::omp::DistributeOperands distributeClauseOps; - genDistributeClauses(converter, semaCtx, stmtCtx, item->clauses, loc, - distributeClauseOps); + genDistributeClauses(converter, semaCtx, stmtCtx, distributeItem->clauses, + loc, distributeClauseOps); mlir::omp::SimdOperands simdClauseOps; - genSimdClauses(converter, semaCtx, item->clauses, loc, simdClauseOps); + genSimdClauses(converter, semaCtx, simdItem->clauses, loc, simdClauseOps); + // Pass the innermost leaf construct's clauses because that's where COLLAPSE + // is placed by construct decomposition. mlir::omp::LoopNestOperands loopNestClauseOps; llvm::SmallVector iv; - genLoopNestClauses(converter, semaCtx, eval, item->clauses, loc, + genLoopNestClauses(converter, semaCtx, eval, simdItem->clauses, loc, loopNestClauseOps, iv); // Operation creation. @@ -2086,7 +2093,7 @@ static void genCompositeDistributeSimd( llvm::concat(distributeOp.getRegion().getArguments(), simdOp.getRegion().getArguments())); - genLoopNestOp(converter, symTable, semaCtx, eval, loc, queue, item, + genLoopNestOp(converter, symTable, semaCtx, eval, loc, queue, simdItem, loopNestClauseOps, iv, /*wrapperSyms=*/{}, wrapperArgs, llvm::omp::Directive::OMPD_distribute_simd, dsp); } @@ -2100,19 +2107,25 @@ static void genCompositeDoSimd(lower::AbstractConverter &converter, DataSharingProcessor &dsp) { lower::StatementContext stmtCtx; + assert(std::distance(item, queue.end()) == 2 && "Invalid leaf constructs"); + ConstructQueue::const_iterator doItem = item; + ConstructQueue::const_iterator simdItem = std::next(doItem); + // Clause processing. mlir::omp::WsloopOperands wsloopClauseOps; llvm::SmallVector wsloopReductionSyms; llvm::SmallVector wsloopReductionTypes; - genWsloopClauses(converter, semaCtx, stmtCtx, item->clauses, loc, + genWsloopClauses(converter, semaCtx, stmtCtx, doItem->clauses, loc, wsloopClauseOps, wsloopReductionTypes, wsloopReductionSyms); mlir::omp::SimdOperands simdClauseOps; - genSimdClauses(converter, semaCtx, item->clauses, loc, simdClauseOps); + genSimdClauses(converter, semaCtx, simdItem->clauses, loc, simdClauseOps); + // Pass the innermost leaf construct's clauses because that's where COLLAPSE + // is placed by construct decomposition. mlir::omp::LoopNestOperands loopNestClauseOps; llvm::SmallVector iv; - genLoopNestClauses(converter, semaCtx, eval, item->clauses, loc, + genLoopNestClauses(converter, semaCtx, eval, simdItem->clauses, loc, loopNestClauseOps, iv); // Operation creation. @@ -2133,7 +2146,7 @@ static void genCompositeDoSimd(lower::AbstractConverter &converter, auto wrapperArgs = llvm::to_vector(llvm::concat( wsloopOp.getRegion().getArguments(), simdOp.getRegion().getArguments())); - genLoopNestOp(converter, symTable, semaCtx, eval, loc, queue, item, + genLoopNestOp(converter, symTable, semaCtx, eval, loc, queue, simdItem, loopNestClauseOps, iv, wsloopReductionSyms, wrapperArgs, llvm::omp::Directive::OMPD_do_simd, dsp); } @@ -2143,6 +2156,7 @@ static void genCompositeTaskloopSimd( semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, mlir::Location loc, const ConstructQueue &queue, ConstructQueue::const_iterator item, DataSharingProcessor &dsp) { + assert(std::distance(item, queue.end()) == 2 && "Invalid leaf constructs"); TODO(loc, "Composite TASKLOOP SIMD"); } @@ -2150,6 +2164,36 @@ static void genCompositeTaskloopSimd( // Dispatch //===----------------------------------------------------------------------===// +static bool genOMPCompositeDispatch( + lower::AbstractConverter &converter, lower::SymMap &symTable, + semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, + mlir::Location loc, const ConstructQueue &queue, + ConstructQueue::const_iterator item, DataSharingProcessor &dsp) { + using llvm::omp::Directive; + using lower::omp::matchLeafSequence; + + if (matchLeafSequence(item, queue, Directive::OMPD_distribute_parallel_do)) + genCompositeDistributeParallelDo(converter, symTable, semaCtx, eval, loc, + queue, item, dsp); + else if (matchLeafSequence(item, queue, + Directive::OMPD_distribute_parallel_do_simd)) + genCompositeDistributeParallelDoSimd(converter, symTable, semaCtx, eval, + loc, queue, item, dsp); + else if (matchLeafSequence(item, queue, Directive::OMPD_distribute_simd)) + genCompositeDistributeSimd(converter, symTable, semaCtx, eval, loc, queue, + item, dsp); + else if (matchLeafSequence(item, queue, Directive::OMPD_do_simd)) + genCompositeDoSimd(converter, symTable, semaCtx, eval, loc, queue, item, + dsp); + else if (matchLeafSequence(item, queue, Directive::OMPD_taskloop_simd)) + genCompositeTaskloopSimd(converter, symTable, semaCtx, eval, loc, queue, + item, dsp); + else + return false; + + return true; +} + static void genOMPDispatch(lower::AbstractConverter &converter, lower::SymMap &symTable, semantics::SemanticsContext &semaCtx, @@ -2163,10 +2207,18 @@ static void genOMPDispatch(lower::AbstractConverter &converter, llvm::omp::Association::Loop; if (loopLeaf) { symTable.pushScope(); + // TODO: Use one DataSharingProcessor for each leaf of a composite + // construct. loopDsp.emplace(converter, semaCtx, item->clauses, eval, /*shouldCollectPreDeterminedSymbols=*/true, /*useDelayedPrivatization=*/false, &symTable); loopDsp->processStep1(); + + if (genOMPCompositeDispatch(converter, symTable, semaCtx, eval, loc, queue, + item, *loopDsp)) { + symTable.popScope(); + return; + } } switch (llvm::omp::Directive dir = item->id) { @@ -2262,29 +2314,11 @@ static void genOMPDispatch(lower::AbstractConverter &converter, // that use this construct, add a single construct for now. genSingleOp(converter, symTable, semaCtx, eval, loc, queue, item); break; - - // Composite constructs - case llvm::omp::Directive::OMPD_distribute_parallel_do: - genCompositeDistributeParallelDo(converter, symTable, semaCtx, eval, loc, - queue, item, *loopDsp); - break; - case llvm::omp::Directive::OMPD_distribute_parallel_do_simd: - genCompositeDistributeParallelDoSimd(converter, symTable, semaCtx, eval, - loc, queue, item, *loopDsp); - break; - case llvm::omp::Directive::OMPD_distribute_simd: - genCompositeDistributeSimd(converter, symTable, semaCtx, eval, loc, queue, - item, *loopDsp); - break; - case llvm::omp::Directive::OMPD_do_simd: - genCompositeDoSimd(converter, symTable, semaCtx, eval, loc, queue, item, - *loopDsp); - break; - case llvm::omp::Directive::OMPD_taskloop_simd: - genCompositeTaskloopSimd(converter, symTable, semaCtx, eval, loc, queue, - item, *loopDsp); - break; default: + // Combined and composite constructs should have been split into a sequence + // of leaf constructs when building the construct queue. + assert(!llvm::omp::isLeafConstruct(dir) && + "Unexpected compound construct."); break; } diff --git a/flang/lib/Semantics/definable.cpp b/flang/lib/Semantics/definable.cpp index 62fed63df4475c..5c41376d2a42bf 100644 --- a/flang/lib/Semantics/definable.cpp +++ b/flang/lib/Semantics/definable.cpp @@ -127,7 +127,7 @@ static std::optional WhyNotDefinableBase(parser::CharBlock at, (!IsPointer(ultimate) || (isWholeSymbol && isPointerDefinition))) { return BlameSymbol( at, "'%s' is an INTENT(IN) dummy argument"_en_US, original); - } else if (acceptAllocatable && + } else if (acceptAllocatable && IsAllocatable(ultimate) && !flags.test(DefinabilityFlag::SourcedAllocation)) { // allocating a function result doesn't count as a def'n // unless there's SOURCE= diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp index 4f1c53f1bb53fc..4f8632a2055d99 100644 --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -2015,6 +2015,15 @@ MaybeExpr ExpressionAnalyzer::Analyze( // initialize X or A by name, but not both. auto components{semantics::OrderedComponentIterator{spec}}; auto nextAnonymous{components.begin()}; + auto afterLastParentComponentIter{components.end()}; + if (parentComponent) { + for (auto iter{components.begin()}; iter != components.end(); ++iter) { + if (iter->test(Symbol::Flag::ParentComp)) { + afterLastParentComponentIter = iter; + ++afterLastParentComponentIter; + } + } + } std::set unavailable; bool anyKeyword{false}; @@ -2060,20 +2069,22 @@ MaybeExpr ExpressionAnalyzer::Analyze( } // Here's a regrettably common extension of the standard: anonymous // initialization of parent components, e.g., T(PT(1)) rather than - // T(1) or T(PT=PT(1)). - if (nextAnonymous == components.begin() && parentComponent && - valueType == DynamicType::From(*parentComponent) && + // T(1) or T(PT=PT(1)). There may be multiple parent components. + if (nextAnonymous == components.begin() && parentComponent && valueType && context().IsEnabled(LanguageFeature::AnonymousParents)) { - auto iter{ - std::find(components.begin(), components.end(), *parentComponent)}; - if (iter != components.end()) { - symbol = parentComponent; - nextAnonymous = ++iter; - if (context().ShouldWarn(LanguageFeature::AnonymousParents)) { - Say(source, - "Whole parent component '%s' in structure " - "constructor should not be anonymous"_port_en_US, - symbol->name()); + for (auto parent{components.begin()}; + parent != afterLastParentComponentIter; ++parent) { + if (auto parentType{DynamicType::From(*parent)}; parentType && + parent->test(Symbol::Flag::ParentComp) && + valueType->IsEquivalentTo(*parentType)) { + symbol = &*parent; + nextAnonymous = ++parent; + if (context().ShouldWarn(LanguageFeature::AnonymousParents)) { + Say(source, + "Whole parent component '%s' in structure constructor should not be anonymous"_port_en_US, + symbol->name()); + } + break; } } } diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index b4875d87d172c2..c0478fd4390076 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -62,10 +62,9 @@ class ScopeHandler; // When inheritFromParent is set, defaults come from the parent rules. class ImplicitRules { public: - ImplicitRules(SemanticsContext &context, ImplicitRules *parent) - : parent_{parent}, context_{context} { - inheritFromParent_ = parent != nullptr; - } + ImplicitRules(SemanticsContext &context, const ImplicitRules *parent) + : parent_{parent}, context_{context}, + inheritFromParent_{parent != nullptr} {} bool isImplicitNoneType() const; bool isImplicitNoneExternal() const; void set_isImplicitNoneType(bool x) { isImplicitNoneType_ = x; } @@ -82,7 +81,7 @@ class ImplicitRules { private: static char Incr(char ch); - ImplicitRules *parent_; + const ImplicitRules *parent_; SemanticsContext &context_; bool inheritFromParent_{false}; // look in parent if not specified here bool isImplicitNoneType_{ @@ -3380,6 +3379,7 @@ bool ModuleVisitor::BeginSubmodule( parentScope = &currScope(); } BeginModule(name, true); + set_inheritFromParent(false); // submodules don't inherit parents' implicits if (ancestor && !ancestor->AddSubmodule(name.source, currScope())) { Say(name, "Module '%s' already has a submodule named '%s'"_err_en_US, ancestorName.source, name.source); @@ -4487,7 +4487,7 @@ Symbol &SubprogramVisitor::PushSubprogramScope(const parser::Name &name, CHECK(context().HasError(genericSymbol)); } } - set_inheritFromParent(hasModulePrefix); + set_inheritFromParent(false); // interfaces don't inherit, even if MODULE } if (Symbol * found{FindSymbol(name)}; found && found->has()) { diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp index 57d84bde60b43c..845183f2d9b253 100644 --- a/flang/lib/Semantics/tools.cpp +++ b/flang/lib/Semantics/tools.cpp @@ -1558,8 +1558,9 @@ bool IsAutomaticallyDestroyed(const Symbol &symbol) { return symbol.has() && (symbol.owner().kind() == Scope::Kind::Subprogram || symbol.owner().kind() == Scope::Kind::BlockConstruct) && - (!IsDummy(symbol) || IsIntentOut(symbol)) && !IsPointer(symbol) && - !IsSaved(symbol) && !FindCommonBlockContaining(symbol); + !IsNamedConstant(symbol) && (!IsDummy(symbol) || IsIntentOut(symbol)) && + !IsPointer(symbol) && !IsSaved(symbol) && + !FindCommonBlockContaining(symbol); } const std::optional &MaybeGetNodeName( diff --git a/flang/test/Evaluate/fold-nearest.f90 b/flang/test/Evaluate/fold-nearest.f90 index 7ca7757f79664e..48b9ef37840e3c 100644 --- a/flang/test/Evaluate/fold-nearest.f90 +++ b/flang/test/Evaluate/fold-nearest.f90 @@ -91,3 +91,24 @@ module m3 real(kind(0.d0)), parameter :: x14 = ieee_next_down(nan) logical, parameter :: test_14 = .not. (x14 == x14) end module + +module m4 + use ieee_arithmetic + real(2), parameter :: neg_inf_2 = real(z'fc00',2) + real(2), parameter :: neg_huge_2 = real(z'fbff',2) + real(3), parameter :: neg_huge_3 = real(z'ff7f',3) + logical, parameter :: test_1 = ieee_next_after(neg_inf_2, neg_huge_3) == neg_huge_2 +end module + +#if __x86_64__ +module m5 + use ieee_arithmetic + real(8), parameter :: neg_inf_8 = real(z'fff0000000000000',8) + real(8), parameter :: neg_huge_8 = real(z'ffefffffffffffff',8) + real(10), parameter :: neg_one_10 = real(z'bfff8000000000000000',10) + real(10), parameter :: neg_inf_10 = real(z'ffff8000000000000000',10) + logical, parameter :: test_1 = ieee_next_after(neg_inf_8, neg_one_10) == neg_huge_8 + logical, parameter :: test_2 = ieee_next_after(neg_one_10, neg_inf_10) == & + real(z'bfff8000000000000001', 10) +end module +#endif diff --git a/flang/test/Lower/OpenMP/Todo/omp-do-simd-linear.f90 b/flang/test/Lower/OpenMP/Todo/omp-do-simd-linear.f90 index 2f5366c2a5b368..4caf12a0169c42 100644 --- a/flang/test/Lower/OpenMP/Todo/omp-do-simd-linear.f90 +++ b/flang/test/Lower/OpenMP/Todo/omp-do-simd-linear.f90 @@ -4,7 +4,7 @@ ! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s subroutine testDoSimdLinear(int_array) integer :: int_array(*) -!CHECK: not yet implemented: Unhandled clause LINEAR in DO construct +!CHECK: not yet implemented: Unhandled clause LINEAR in SIMD construct !$omp do simd linear(int_array) do index_ = 1, 10 end do diff --git a/flang/test/Lower/OpenMP/default-clause-byref.f90 b/flang/test/Lower/OpenMP/default-clause-byref.f90 index d9f0eff4e6fde1..626ba3335a8c10 100644 --- a/flang/test/Lower/OpenMP/default-clause-byref.f90 +++ b/flang/test/Lower/OpenMP/default-clause-byref.f90 @@ -197,9 +197,9 @@ subroutine nested_default_clause_tests !CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %[[Y]] {uniq_name = "_QFnested_default_clause_testsEy"} : (!fir.ref) -> (!fir.ref, !fir.ref) !CHECK: %[[Z:.*]] = fir.alloca i32 {bindc_name = "z", uniq_name = "_QFnested_default_clause_testsEz"} !CHECK: %[[Z_DECL:.*]]:2 = hlfir.declare %[[Z]] {uniq_name = "_QFnested_default_clause_testsEz"} : (!fir.ref) -> (!fir.ref, !fir.ref) -!CHECK: omp.parallel private({{.*}} {{.*}}#0 -> %[[PRIVATE_Y:.*]] : {{.*}}, {{.*firstprivate.*}} {{.*}}#0 -> %[[PRIVATE_X:.*]] : {{.*}}, {{.*}} {{.*}}#0 -> %[[PRIVATE_Z:.*]] : {{.*}}, {{.*}} {{.*}}#0 -> %[[PRIVATE_K:.*]] : {{.*}}) { -!CHECK: %[[PRIVATE_Y_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_Y]] {uniq_name = "_QFnested_default_clause_testsEy"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: omp.parallel private({{.*firstprivate.*}} {{.*}}#0 -> %[[PRIVATE_X:.*]] : {{.*}}, {{.*}} {{.*}}#0 -> %[[PRIVATE_Y:.*]] : {{.*}}, {{.*}} {{.*}}#0 -> %[[PRIVATE_Z:.*]] : {{.*}}, {{.*}} {{.*}}#0 -> %[[PRIVATE_K:.*]] : {{.*}}) { !CHECK: %[[PRIVATE_X_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_X]] {uniq_name = "_QFnested_default_clause_testsEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: %[[PRIVATE_Y_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_Y]] {uniq_name = "_QFnested_default_clause_testsEy"} : (!fir.ref) -> (!fir.ref, !fir.ref) !CHECK: %[[PRIVATE_Z_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_Z]] {uniq_name = "_QFnested_default_clause_testsEz"} : (!fir.ref) -> (!fir.ref, !fir.ref) !CHECK: %[[PRIVATE_K_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_K]] {uniq_name = "_QFnested_default_clause_testsEk"} : (!fir.ref) -> (!fir.ref, !fir.ref) !CHECK: omp.parallel private({{.*}} {{.*}}#0 -> %[[INNER_PRIVATE_Y:.*]] : {{.*}}, {{.*}} {{.*}}#0 -> %[[INNER_PRIVATE_X:.*]] : {{.*}}) { diff --git a/flang/test/Lower/OpenMP/default-clause.f90 b/flang/test/Lower/OpenMP/default-clause.f90 index 775ce9ac801934..fefb5fcc4239e6 100644 --- a/flang/test/Lower/OpenMP/default-clause.f90 +++ b/flang/test/Lower/OpenMP/default-clause.f90 @@ -134,9 +134,9 @@ end program default_clause_lowering !CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %[[Y]] {uniq_name = "_QFnested_default_clause_test1Ey"} : (!fir.ref) -> (!fir.ref, !fir.ref) !CHECK: %[[Z:.*]] = fir.alloca i32 {bindc_name = "z", uniq_name = "_QFnested_default_clause_test1Ez"} !CHECK: %[[Z_DECL:.*]]:2 = hlfir.declare %[[Z]] {uniq_name = "_QFnested_default_clause_test1Ez"} : (!fir.ref) -> (!fir.ref, !fir.ref) -!CHECK: omp.parallel private({{.*}} {{.*}}#0 -> %[[PRIVATE_Y:.*]] : {{.*}}, {{.*firstprivate.*}} {{.*}}#0 -> %[[PRIVATE_X:.*]] : {{.*}}, {{.*}} {{.*}}#0 -> %[[PRIVATE_Z:.*]] : {{.*}}, {{.*}} {{.*}}#0 -> %[[PRIVATE_K:.*]] : {{.*}}) { -!CHECK: %[[PRIVATE_Y_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_Y]] {uniq_name = "_QFnested_default_clause_test1Ey"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: omp.parallel private({{.*firstprivate.*}} {{.*}}#0 -> %[[PRIVATE_X:.*]] : {{.*}}, {{.*}} {{.*}}#0 -> %[[PRIVATE_Y:.*]] : {{.*}}, {{.*}} {{.*}}#0 -> %[[PRIVATE_Z:.*]] : {{.*}}, {{.*}} {{.*}}#0 -> %[[PRIVATE_K:.*]] : {{.*}}) { !CHECK: %[[PRIVATE_X_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_X]] {uniq_name = "_QFnested_default_clause_test1Ex"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: %[[PRIVATE_Y_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_Y]] {uniq_name = "_QFnested_default_clause_test1Ey"} : (!fir.ref) -> (!fir.ref, !fir.ref) !CHECK: %[[PRIVATE_Z_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_Z]] {uniq_name = "_QFnested_default_clause_test1Ez"} : (!fir.ref) -> (!fir.ref, !fir.ref) !CHECK: %[[PRIVATE_K_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_K]] {uniq_name = "_QFnested_default_clause_test1Ek"} : (!fir.ref) -> (!fir.ref, !fir.ref) !CHECK: omp.parallel private({{.*}} {{.*}}#0 -> %[[INNER_PRIVATE_Y:.*]] : {{.*}}, {{.*}} {{.*}}#0 -> %[[INNER_PRIVATE_X:.*]] : {{.*}}) { diff --git a/flang/test/Semantics/declarations05.f90 b/flang/test/Semantics/declarations05.f90 index 5144f0b91ab9de..b6dab7aeea0bc8 100644 --- a/flang/test/Semantics/declarations05.f90 +++ b/flang/test/Semantics/declarations05.f90 @@ -29,6 +29,7 @@ pure subroutine test type(t1) x1 !WARNING: 'x1a' of derived type 't1' does not have a FINAL subroutine for its rank (1) type(t1), allocatable :: x1a(:) + type(t1), parameter :: namedConst = t1() ! ok !ERROR: 'x2' may not be a local variable in a pure subprogram !BECAUSE: 'x2' has an impure FINAL procedure 'final' type(t2) x2 diff --git a/flang/test/Semantics/implicit15.f90 b/flang/test/Semantics/implicit15.f90 new file mode 100644 index 00000000000000..d7cfa543e84a51 --- /dev/null +++ b/flang/test/Semantics/implicit15.f90 @@ -0,0 +1,50 @@ +!RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s +!Test inheritance of implicit rules in submodules and separate module +!procedures. + +module m + implicit integer(1)(a-z) + interface + module subroutine mp(da) ! integer(2) + implicit integer(2)(a-z) + end + end interface + save :: mv ! integer(1) +end + +submodule(m) sm1 + implicit integer(8)(a-z) + save :: sm1v ! integer(8) + interface + module subroutine sm1p(da) ! default real + end + end interface +end + +submodule(m:sm1) sm2 + implicit integer(2)(a-c,e-z) + save :: sm2v ! integer(2) + contains + module subroutine sm1p(da) ! default real + save :: sm1pv ! inherited integer(2) + !CHECK: PRINT *, 1_4, 8_4, 2_4, 4_4, 2_4 + print *, kind(mv), kind(sm1v), kind(sm2v), kind(da), kind(sm1pv) + end +end + +submodule(m:sm2) sm3 + implicit integer(8)(a-z) + save :: sm3v ! integer(8) + contains + module procedure mp + save :: mpv ! inherited integer(8) + call sm1p(1.) + !CHECK: PRINT *, 1_4, 8_4, 2_4, 8_4, 2_4, 8_4 + print *, kind(mv), kind(sm1v), kind(sm2v), kind(sm3v), kind(da), kind(mpv) + end +end + +program main + use m + call mp(1_2) +end diff --git a/flang/test/Semantics/structconst10.f90 b/flang/test/Semantics/structconst10.f90 new file mode 100644 index 00000000000000..582f8fc15704f4 --- /dev/null +++ b/flang/test/Semantics/structconst10.f90 @@ -0,0 +1,25 @@ +! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic -Werror +module m1 + type a1 + integer ::x1=1 + end type a1 + type,extends(a1)::a2 + integer ::x2=3 + end type a2 + type,extends(a2)::a3 + integer ::x3=3 + end type a3 +end module m1 + +program test + use m1 + type(a3) v + !PORTABILITY: Whole parent component 'a2' in structure constructor should not be anonymous + v=a3(a2(x1=18,x2=6),x3=6) + !PORTABILITY: Whole parent component 'a1' in structure constructor should not be anonymous + v=a3(a1(x1=18),x2=6,x3=6) + !PORTABILITY: Whole parent component 'a2' in structure constructor should not be anonymous + !PORTABILITY: Whole parent component 'a1' in structure constructor should not be anonymous + v=a3(a2(a1(x1=18),x2=6),x3=6) + v=a3(a2=a2(a1=a1(x1=18),x2=6),x3=6) ! ok +end diff --git a/flang/test/Semantics/undef-result01.f90 b/flang/test/Semantics/undef-result01.f90 index dd73f9c76df0a5..bf6af11a8d7b92 100644 --- a/flang/test/Semantics/undef-result01.f90 +++ b/flang/test/Semantics/undef-result01.f90 @@ -44,6 +44,11 @@ function basicAlloc() allocate(basicAlloc) end +function allocPtr() + real, pointer :: allocPtr + allocate(allocPtr) ! good enough for pointer +end + function sourcedAlloc() real, allocatable :: sourcedAlloc allocate(sourcedAlloc, source=0.) diff --git a/flang/unittests/Runtime/Time.cpp b/flang/unittests/Runtime/Time.cpp index 5c93282bca6115..9309d7b1ceffa0 100644 --- a/flang/unittests/Runtime/Time.cpp +++ b/flang/unittests/Runtime/Time.cpp @@ -6,8 +6,6 @@ // //===----------------------------------------------------------------------===// -#ifndef __clang__ // 16.0.3 lacks - #include "gtest/gtest.h" #include "flang/Runtime/time-intrinsic.h" #include @@ -89,6 +87,7 @@ TEST(TimeIntrinsics, SystemClock) { } TEST(TimeIntrinsics, DateAndTime) { + errno = 0; constexpr std::size_t bufferSize{16}; std::string date(bufferSize, 'Z'), time(bufferSize, 'Z'), zone(bufferSize, 'Z'); @@ -163,4 +162,3 @@ TEST(TimeIntrinsics, DateAndTime) { EXPECT_LE(minutes, 59); } } -#endif // __clang__ diff --git a/libc/newhdrgen/yaml_to_classes.py b/libc/newhdrgen/yaml_to_classes.py index 3eb5e4ef2546c1..237dd21aa5dff5 100644 --- a/libc/newhdrgen/yaml_to_classes.py +++ b/libc/newhdrgen/yaml_to_classes.py @@ -118,7 +118,7 @@ def load_yaml_file(yaml_file, header_class, entry_points): HeaderFile: An instance of HeaderFile populated with the data. """ with open(yaml_file, "r") as f: - yaml_data = yaml.load(f, Loader=yaml.FullLoader) + yaml_data = yaml.safe_load(f) return yaml_to_classes(yaml_data, header_class, entry_points) @@ -173,7 +173,7 @@ def add_function_to_yaml(yaml_file, function_details): new_function = parse_function_details(function_details) with open(yaml_file, "r") as f: - yaml_data = yaml.load(f, Loader=yaml.FullLoader) + yaml_data = yaml.safe_load(f) if "functions" not in yaml_data: yaml_data["functions"] = [] diff --git a/libc/startup/linux/CMakeLists.txt b/libc/startup/linux/CMakeLists.txt index 71f187ca05f29f..eaa724e41f1685 100644 --- a/libc/startup/linux/CMakeLists.txt +++ b/libc/startup/linux/CMakeLists.txt @@ -138,6 +138,5 @@ foreach(target IN LISTS startup_components) install(FILES $ DESTINATION ${LIBC_INSTALL_LIBRARY_DIR} RENAME $ - EXCLUDE_FROM_ALL COMPONENT libc) endforeach() diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv index 60c6dc532dc719..be0621caaa9c69 100644 --- a/libcxx/docs/Status/Cxx2cIssues.csv +++ b/libcxx/docs/Status/Cxx2cIssues.csv @@ -77,4 +77,5 @@ "`LWG4106 `__","``basic_format_args`` should not be default-constructible","2024-06 (St. Louis)","|Complete|","19.0","|format|" "","","","","","" "`LWG3343 `__","Ordering of calls to ``unlock()`` and ``notify_all()`` in Effects element of ``notify_all_at_thread_exit()`` should be reversed","Not Adopted Yet","|Complete|","16.0","" +"`LWG4139 `__","§[time.zone.leap] recursive constraint in <=>","Not Adopted Yet","|Complete|","20.0","" "","","","","","" diff --git a/libcxx/include/__algorithm/partition.h b/libcxx/include/__algorithm/partition.h index 824e49b9ec2149..bd0dccfaf92abe 100644 --- a/libcxx/include/__algorithm/partition.h +++ b/libcxx/include/__algorithm/partition.h @@ -29,7 +29,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _Forw __partition_impl(_ForwardIterator __first, _Sentinel __last, _Predicate __pred, forward_iterator_tag) { while (true) { if (__first == __last) - return std::make_pair(std::move(__first), std::move(__first)); + return std::make_pair(__first, __first); if (!__pred(*__first)) break; ++__first; diff --git a/libcxx/include/__chrono/leap_second.h b/libcxx/include/__chrono/leap_second.h index 1a0e7f3107de81..d79111ed8eecfc 100644 --- a/libcxx/include/__chrono/leap_second.h +++ b/libcxx/include/__chrono/leap_second.h @@ -50,70 +50,75 @@ class leap_second { private: sys_seconds __date_; seconds __value_; -}; -_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator==(const leap_second& __x, const leap_second& __y) { - return __x.date() == __y.date(); -} - -_LIBCPP_HIDE_FROM_ABI inline constexpr strong_ordering operator<=>(const leap_second& __x, const leap_second& __y) { - return __x.date() <=> __y.date(); -} - -template -_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const leap_second& __x, const sys_time<_Duration>& __y) { - return __x.date() == __y; -} - -template -_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const leap_second& __x, const sys_time<_Duration>& __y) { - return __x.date() < __y; -} - -template -_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const sys_time<_Duration>& __x, const leap_second& __y) { - return __x < __y.date(); -} - -template -_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const leap_second& __x, const sys_time<_Duration>& __y) { - return __y < __x; -} - -template -_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const sys_time<_Duration>& __x, const leap_second& __y) { - return __y < __x; -} - -template -_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const leap_second& __x, const sys_time<_Duration>& __y) { - return !(__y < __x); -} - -template -_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const sys_time<_Duration>& __x, const leap_second& __y) { - return !(__y < __x); -} - -template -_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const leap_second& __x, const sys_time<_Duration>& __y) { - return !(__x < __y); -} - -template -_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const sys_time<_Duration>& __x, const leap_second& __y) { - return !(__x < __y); -} - -# ifndef _LIBCPP_COMPILER_GCC -// This requirement cause a compilation loop in GCC-13 and running out of memory. -// TODO TZDB Test whether GCC-14 fixes this. -template - requires three_way_comparable_with> -_LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>(const leap_second& __x, const sys_time<_Duration>& __y) { - return __x.date() <=> __y; -} -# endif + // The function + // template + // requires three_way_comparable_with> + // constexpr auto operator<=>(const leap_second& x, const sys_time& y) noexcept; + // + // Has constraints that are recursive (LWG4139). The proposed resolution is + // to make the funcion a hidden friend. For consistency make this change for + // all comparison functions. + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const leap_second& __x, const leap_second& __y) { + return __x.date() == __y.date(); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering operator<=>(const leap_second& __x, const leap_second& __y) { + return __x.date() <=> __y.date(); + } + + template + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const leap_second& __x, const sys_time<_Duration>& __y) { + return __x.date() == __y; + } + + template + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const leap_second& __x, const sys_time<_Duration>& __y) { + return __x.date() < __y; + } + + template + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const sys_time<_Duration>& __x, const leap_second& __y) { + return __x < __y.date(); + } + + template + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const leap_second& __x, const sys_time<_Duration>& __y) { + return __y < __x; + } + + template + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const sys_time<_Duration>& __x, const leap_second& __y) { + return __y < __x; + } + + template + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const leap_second& __x, const sys_time<_Duration>& __y) { + return !(__y < __x); + } + + template + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const sys_time<_Duration>& __x, const leap_second& __y) { + return !(__y < __x); + } + + template + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const leap_second& __x, const sys_time<_Duration>& __y) { + return !(__x < __y); + } + + template + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const sys_time<_Duration>& __x, const leap_second& __y) { + return !(__x < __y); + } + + template + requires three_way_comparable_with> + _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const leap_second& __x, const sys_time<_Duration>& __y) { + return __x.date() <=> __y; + } +}; } // namespace chrono diff --git a/libcxx/include/__pstl/backends/default.h b/libcxx/include/__pstl/backends/default.h index 61a128805f8549..b655da51fe340b 100644 --- a/libcxx/include/__pstl/backends/default.h +++ b/libcxx/include/__pstl/backends/default.h @@ -163,7 +163,7 @@ struct __is_partitioned<__default_backend_tag, _ExecutionPolicy> { [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept { using _FindIfNot = __dispatch<__find_if_not, __current_configuration, _ExecutionPolicy>; - auto __maybe_first = _FindIfNot()(__policy, std::move(__first), std::move(__last), __pred); + auto __maybe_first = _FindIfNot()(__policy, std::move(__first), __last, __pred); if (__maybe_first == nullopt) return nullopt; diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/partition.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/partition.pass.cpp index 3eaeaa432c490f..87beba183a2842 100644 --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/partition.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/partition.pass.cpp @@ -98,11 +98,13 @@ test() int main(int, char**) { + test >(); test >(); test >(); test(); #if TEST_STD_VER >= 20 + static_assert(test>()); static_assert(test>()); static_assert(test>()); static_assert(test()); diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains.pass.cpp index f710ca2c319dd6..08d8e119a4d24b 100644 --- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains.pass.cpp +++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains.pass.cpp @@ -65,12 +65,12 @@ constexpr void test_iterators() { using ValueT = std::iter_value_t; { // simple tests ValueT a[] = {1, 2, 3, 4, 5, 6}; - auto whole = std::ranges::subrange(Iter(a), Sent(Iter(a + 6))); { - std::same_as decltype(auto) ret = std::ranges::contains(whole.begin(), whole.end(), 3); + std::same_as decltype(auto) ret = std::ranges::contains(Iter(a), Sent(Iter(a + 6)), 3); assert(ret); } { + auto whole = std::ranges::subrange(Iter(a), Sent(Iter(a + 6))); std::same_as decltype(auto) ret = std::ranges::contains(whole, 3); assert(ret); } @@ -78,65 +78,65 @@ constexpr void test_iterators() { { // check that a range with a single element works ValueT a[] = {32}; - auto whole = std::ranges::subrange(Iter(a), Sent(Iter(a + 1))); { - bool ret = std::ranges::contains(whole.begin(), whole.end(), 32); + bool ret = std::ranges::contains(Iter(a), Sent(Iter(a + 1)), 32); assert(ret); } { - bool ret = std::ranges::contains(whole, 32); + auto whole = std::ranges::subrange(Iter(a), Sent(Iter(a + 1))); + bool ret = std::ranges::contains(whole, 32); assert(ret); } } { // check that an empty range works std::array a = {}; - auto whole = std::ranges::subrange(Iter(a.data()), Sent(Iter(a.data()))); { - bool ret = std::ranges::contains(whole.begin(), whole.end(), 1); + bool ret = std::ranges::contains(Iter(a.data()), Sent(Iter(a.data())), 1); assert(!ret); } { - bool ret = std::ranges::contains(whole, 1); + auto whole = std::ranges::subrange(Iter(a.data()), Sent(Iter(a.data()))); + bool ret = std::ranges::contains(whole, 1); assert(!ret); } } { // check that the first element matches ValueT a[] = {32, 3, 2, 1, 0, 23, 21, 9, 40, 100}; - auto whole = std::ranges::subrange(Iter(a), Sent(Iter(a + 10))); { - bool ret = std::ranges::contains(whole.begin(), whole.end(), 32); + bool ret = std::ranges::contains(Iter(a), Sent(Iter(a + 10)), 32); assert(ret); } { - bool ret = std::ranges::contains(whole, 32); + auto whole = std::ranges::subrange(Iter(a), Sent(Iter(a + 10))); + bool ret = std::ranges::contains(whole, 32); assert(ret); } } { // check that the last element matches ValueT a[] = {3, 22, 1, 43, 99, 0, 56, 100, 32}; - auto whole = std::ranges::subrange(Iter(a), Sent(Iter(a + 9))); { - bool ret = std::ranges::contains(whole.begin(), whole.end(), 32); + bool ret = std::ranges::contains(Iter(a), Sent(Iter(a + 9)), 32); assert(ret); } { - bool ret = std::ranges::contains(whole, 32); + auto whole = std::ranges::subrange(Iter(a), Sent(Iter(a + 9))); + bool ret = std::ranges::contains(whole, 32); assert(ret); } } { // no match ValueT a[] = {13, 1, 21, 4, 5}; - auto whole = std::ranges::subrange(Iter(a), Sent(Iter(a + 5))); { - bool ret = std::ranges::contains(whole.begin(), whole.end(), 10); + bool ret = std::ranges::contains(Iter(a), Sent(Iter(a + 5)), 10); assert(!ret); } { - bool ret = std::ranges::contains(whole, 10); + auto whole = std::ranges::subrange(Iter(a), Sent(Iter(a + 5))); + bool ret = std::ranges::contains(whole, 10); assert(!ret); } } diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.ends_with/ranges.ends_with.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.ends_with/ranges.ends_with.pass.cpp index 685bd692422ac8..199e6a786e5ba3 100644 --- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.ends_with/ranges.ends_with.pass.cpp +++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.ends_with/ranges.ends_with.pass.cpp @@ -49,7 +49,8 @@ static_assert(!HasEndsWithIt> concept HasEndsWithR = requires(Range1&& range1, Range2&& range2) { - std::ranges::ends_with(std::forward(range1), std::forward(range2)); }; + std::ranges::ends_with(std::forward(range1), std::forward(range2)); +}; static_assert(HasEndsWithR>); static_assert(!HasEndsWithR); @@ -61,19 +62,21 @@ static_assert(!HasEndsWithR, UncheckedRange>); // no static_assert(!HasEndsWithR, ForwardRangeNotDerivedFrom>); static_assert(!HasEndsWithR, ForwardRangeNotSentinelSemiregular>); -// clang-format off template constexpr void test_iterators() { { // simple tests - int a[] = {1, 2, 3, 4, 5, 6}; - int p[] = {4, 5, 6}; - auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); - auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 3))); + int a[] = {1, 2, 3, 4, 5, 6}; + int p[] = {4, 5, 6}; { - [[maybe_unused]] std::same_as decltype(auto) ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end()); + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 3))); + [[maybe_unused]] std::same_as decltype(auto) ret = + std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end()); assert(ret); } { + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 3))); [[maybe_unused]] std::same_as decltype(auto) ret = std::ranges::ends_with(whole, suffix); assert(ret); } @@ -82,14 +85,16 @@ constexpr void test_iterators() { { // suffix doesn't match int a[] = {1, 2, 3, 4, 5, 6}; int p[] = {1, 2, 3}; - auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); - auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 3))); { - bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end()); + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 3))); + bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end()); assert(!ret); } { - bool ret = std::ranges::ends_with(whole, suffix); + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 3))); + bool ret = std::ranges::ends_with(whole, suffix); assert(!ret); } } @@ -97,14 +102,16 @@ constexpr void test_iterators() { { // range consists of just one element int a[] = {1}; int p[] = {1}; - auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 1))); - auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 1))); { - bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end()); + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 1))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 1))); + bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end()); assert(ret); } { - bool ret = std::ranges::ends_with(whole, suffix); + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 1))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 1))); + bool ret = std::ranges::ends_with(whole, suffix); assert(ret); } } @@ -112,14 +119,16 @@ constexpr void test_iterators() { { // suffix consists of just one element int a[] = {5, 1, 2, 4, 3}; int p[] = {3}; - auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 5))); - auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 1))); { - bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end()); + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 5))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 1))); + bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end()); assert(ret); } { - bool ret = std::ranges::ends_with(whole, suffix); + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 5))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 1))); + bool ret = std::ranges::ends_with(whole, suffix); assert(ret); } } @@ -127,14 +136,16 @@ constexpr void test_iterators() { { // range and suffix are identical int a[] = {1, 2, 3, 4, 5, 6}; int p[] = {1, 2, 3, 4, 5, 6}; - auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); - auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 6))); { - bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end()); + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 6))); + bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end()); assert(ret); } { - bool ret = std::ranges::ends_with(whole, suffix); + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 6))); + bool ret = std::ranges::ends_with(whole, suffix); assert(ret); } } @@ -142,111 +153,128 @@ constexpr void test_iterators() { { // suffix is longer than range int a[] = {3, 4, 5, 6, 7, 8}; int p[] = {1, 2, 3, 4, 5, 6, 7, 8}; - auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); - auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 8))); { - bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end()); + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 8))); + bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end()); assert(!ret); } { - bool ret = std::ranges::ends_with(whole, suffix); + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 8))); + bool ret = std::ranges::ends_with(whole, suffix); assert(!ret); } - } + } - { // suffix has zero length - int a[] = {1, 2, 3, 4, 5, 6}; - std::array p = {}; - auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); - auto suffix = std::ranges::subrange(Iter2(p.data()), Sent2(Iter2(p.data()))); - { - bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end()); - assert(ret); - } - { - bool ret = std::ranges::ends_with(whole, suffix); - assert(ret); - } - } + { // suffix has zero length + int a[] = {1, 2, 3, 4, 5, 6}; + std::array p = {}; + { + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); + auto suffix = std::ranges::subrange(Iter2(p.data()), Sent2(Iter2(p.data()))); + bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end()); + assert(ret); + } + { + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); + auto suffix = std::ranges::subrange(Iter2(p.data()), Sent2(Iter2(p.data()))); + bool ret = std::ranges::ends_with(whole, suffix); + assert(ret); + } + } - { // range has zero length - std::array a = {}; - int p[] = {1, 2, 3, 4, 5, 6, 7, 8}; - auto whole = std::ranges::subrange(Iter1(a.data()), Sent1(Iter1(a.data()))); - auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 8))); - { - bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end()); - assert(!ret); - } - { - bool ret = std::ranges::ends_with(whole, suffix); - assert(!ret); - } - } + { // range has zero length + std::array a = {}; + int p[] = {1, 2, 3, 4, 5, 6, 7, 8}; + { + auto whole = std::ranges::subrange(Iter1(a.data()), Sent1(Iter1(a.data()))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 8))); + bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end()); + assert(!ret); + } + { + auto whole = std::ranges::subrange(Iter1(a.data()), Sent1(Iter1(a.data()))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 8))); + bool ret = std::ranges::ends_with(whole, suffix); + assert(!ret); + } + } - { // subarray - int a[] = {0, 3, 5, 10, 7, 3, 5, 89, 3, 5, 2, 1, 8, 6}; - int p[] = {3, 5}; - auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 13))); - auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 2))); - { - bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end()); - assert(!ret); - } - { - bool ret = std::ranges::ends_with(whole, suffix); - assert(!ret); - } - } + { // subarray + int a[] = {0, 3, 5, 10, 7, 3, 5, 89, 3, 5, 2, 1, 8, 6}; + int p[] = {3, 5}; + { + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 13))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 2))); + bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end()); + assert(!ret); + } + { + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 13))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 2))); + bool ret = std::ranges::ends_with(whole, suffix); + assert(!ret); + } + } - { // repeated suffix - int a[] = {8, 6, 3, 5, 1, 2}; - int p[] = {1, 2, 1, 2}; - auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); - auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 4))); - { - bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end()); - assert(!ret); - } - { - bool ret = std::ranges::ends_with(whole, suffix); - assert(!ret); - } - } + { // repeated suffix + int a[] = {8, 6, 3, 5, 1, 2}; + int p[] = {1, 2, 1, 2}; + { + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 4))); + bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end()); + assert(!ret); + } + { + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 4))); + bool ret = std::ranges::ends_with(whole, suffix); + assert(!ret); + } + } - { // check that the predicate is used - int a[] = {5, 1, 3, 2, 7}; - int p[] = {-2, -7}; - auto pred = [](int l, int r) { return l * -1 == r; }; - auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 5))); - auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 2))); - { - bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end(), pred); - assert(ret); - } - { - bool ret = std::ranges::ends_with(whole, suffix, pred); - assert(ret); - } - } + { // check that the predicate is used + int a[] = {5, 1, 3, 2, 7}; + int p[] = {-2, -7}; + auto pred = [](int l, int r) { return l * -1 == r; }; + { + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 5))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 2))); + bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end(), pred); + assert(ret); + } + { + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 5))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 2))); + bool ret = std::ranges::ends_with(whole, suffix, pred); + assert(ret); + } + } - { // check that the projections are used - int a[] = {1, 3, 15, 1, 2, 1}; - int p[] = {2, 1, 2}; - auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); - auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 3))); - { - bool ret = std::ranges::ends_with(whole.begin(), whole.end(), suffix.begin(), suffix.end(), {}, - [](int i) { return i - 3; }, - [](int i) { return i * -1; }); - assert(ret); - } - { - bool ret = std::ranges::ends_with(whole, suffix, {}, - [](int i) { return i - 3; }, - [](int i) { return i * -1; }); - assert(ret); - } + { // check that the projections are used + int a[] = {1, 3, 15, 1, 2, 1}; + int p[] = {2, 1, 2}; + { + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 3))); + bool ret = std::ranges::ends_with( + whole.begin(), + whole.end(), + suffix.begin(), + suffix.end(), + {}, + [](int i) { return i - 3; }, + [](int i) { return i * -1; }); + assert(ret); + } + { + auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6))); + auto suffix = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 3))); + bool ret = std::ranges::ends_with(whole, suffix, {}, [](int i) { return i - 3; }, [](int i) { return i * -1; }); + assert(ret); + } } } diff --git a/libcxx/test/std/containers/associative/from_range_associative_containers.h b/libcxx/test/std/containers/associative/from_range_associative_containers.h index 6d2d6e6874aaa2..d227c41f6d84a8 100644 --- a/libcxx/test/std/containers/associative/from_range_associative_containers.h +++ b/libcxx/test/std/containers/associative/from_range_associative_containers.h @@ -59,9 +59,8 @@ template