https://github.com/bob80905 updated https://github.com/llvm/llvm-project/pull/86175
>From 5e10b1e42a20a39c9a3d5ff332591713511832c8 Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Wed, 20 Mar 2024 13:24:07 -0700 Subject: [PATCH 1/5] make elemnetwise alias an alias of builtin alias --- clang/include/clang/Basic/Attr.td | 9 ++++++++ clang/include/clang/Basic/AttrDocs.td | 22 +++++++++++++++++++ .../clang/Basic/DiagnosticSemaKinds.td | 3 ++- clang/lib/AST/Decl.cpp | 2 ++ clang/lib/Headers/hlsl/hlsl_intrinsics.h | 2 ++ 5 files changed, 37 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index fd7970d0451acd..160e8ef730ef92 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -759,6 +759,15 @@ def BuiltinAlias : Attr { let Documentation = [BuiltinAliasDocs]; } +def ElementwiseBuiltinAlias : Attr { + let Spellings = [CXX11<"clang", "elementwise_builtin_alias">, + C23<"clang", "elementwise_builtin_alias">, + GNU<"clang_elementwise_builtin_alias">]; + let Args = [IdentifierArgument<"BuiltinName">]; + let Subjects = SubjectList<[Function], ErrorDiag>; + let Documentation = [ElementwiseBuiltinAliasDocs]; +} + def ArmBuiltinAlias : InheritableAttr, TargetSpecificAttr<TargetAnyArm> { let Spellings = [Clang<"__clang_arm_builtin_alias">]; let Args = [IdentifierArgument<"BuiltinName">]; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 2c07cd09b0d5b7..7ce83bc881f064 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -5462,6 +5462,28 @@ for clang builtin functions. }]; } +def ElementwiseBuiltinAliasDocs : Documentation { + let Category = DocCatFunction; + let Heading = "clang::elementwise_builtin_alias, clang_elementwise_builtin_alias"; + let Content = [{ +This attribute is used in the implementation of the C intrinsics. +It allows the C intrinsic functions to be declared using the names defined +in target builtins, and still be recognized as clang builtins equivalent to the +underlying name. It also declares that the given C intrinsic can accept +vector arguments. For example, ``hlsl_intrinsics.h`` declares the function ``abs`` +with ``__attribute__((clang_elementwise_builtin_alias(__builtin_abs)))``. +This ensures that both functions are recognized as that clang builtin, +and in the latter case, the choice of which builtin to identify the +function as can be deferred until after overload resolution. It also enables +the ``abs`` function to take vector arguments. + +This attribute can only be used to set up the aliases for certain ARM/RISC-V +C intrinsic functions; it is intended for use only inside ``arm_*.h`` and +``riscv_*.h`` and is not a general mechanism for declaring arbitrary aliases +for clang builtin functions. + }]; +} + def PreferredNameDocs : Documentation { let Category = DocCatDecl; let Content = [{ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index c54105507753eb..1252d3804131a6 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4412,7 +4412,8 @@ def err_attribute_preferred_name_arg_invalid : Error< "a specialization of %1">; def err_attribute_builtin_alias : Error< "%0 attribute can only be applied to a ARM, HLSL or RISC-V builtin">; - +def err_attribute_elementwise_builtin_alias : Error< + "%0 attribute can only be applied to a ARM, HLSL or RISC-V builtin">; // called-once attribute diagnostics. def err_called_once_attribute_wrong_type : Error< "'called_once' attribute only applies to function-like parameters">; diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 8626f04012f7d4..cb2c5cf6ceaf49 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3598,6 +3598,8 @@ unsigned FunctionDecl::getBuiltinID(bool ConsiderWrapperFunctions) const { BuiltinID = ABAA->getBuiltinName()->getBuiltinID(); } else if (const auto *BAA = getAttr<BuiltinAliasAttr>()) { BuiltinID = BAA->getBuiltinName()->getBuiltinID(); + } else if (const auto *EBAA = getAttr<ElementwiseBuiltinAliasAttr>()) { + BuiltinID = EBAA->getBuiltinName()->getBuiltinID(); } else if (const auto *A = getAttr<BuiltinAttr>()) { BuiltinID = A->getID(); } diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 45f8544392584e..b37c4d13b26e62 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -18,6 +18,8 @@ namespace hlsl { #define _HLSL_BUILTIN_ALIAS(builtin) \ __attribute__((clang_builtin_alias(builtin))) +#define _HLSL_ELEMENTWISE_BUILTIN_ALIAS(builtin) \ + __attribute__((clang_elementwise_builtin_alias(builtin))) #define _HLSL_AVAILABILITY(environment, version) \ __attribute__((availability(environment, introduced = version))) >From 4cb34745b6d51e71fed1036009730f92cd4d36e9 Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Wed, 20 Mar 2024 13:54:06 -0700 Subject: [PATCH 2/5] my alias is now a verified alias! --- clang/lib/Headers/hlsl/hlsl_intrinsics.h | 2 +- clang/lib/Sema/SemaDeclAttr.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index b37c4d13b26e62..f646522e35e84c 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -99,7 +99,7 @@ _HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs) double2 abs(double2); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs) double3 abs(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs) +_HLSL_ELEMENTWISE_BUILTIN_ALIAS(__builtin_elementwise_abs) double4 abs(double4); //===----------------------------------------------------------------------===// diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index c00120b59d396e..4710bd61a78e14 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -9851,6 +9851,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_BuiltinAlias: handleBuiltinAliasAttr(S, D, AL); break; + case ParsedAttr::AT_ElementwiseBuiltinAlias: + handleBuiltinAliasAttr(S, D, AL); + break; case ParsedAttr::AT_PreferredType: handlePreferredTypeAttr(S, D, AL); >From 4c8ba70909906e13b8b997d406d3f4a0e006015b Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Wed, 20 Mar 2024 17:39:43 -0700 Subject: [PATCH 3/5] attempt to implement 1 --- clang/lib/Sema/SemaChecking.cpp | 632 +++++++++++++++++--------------- clang/lib/Sema/SemaDeclAttr.cpp | 31 +- 2 files changed, 364 insertions(+), 299 deletions(-) diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a5f42b630c3fa2..f60a38980549e9 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2240,317 +2240,353 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, ICEArguments &= ~(1 << ArgNo); } - FPOptions FPO; - switch (BuiltinID) { - case Builtin::BI__builtin_cpu_supports: - case Builtin::BI__builtin_cpu_is: - if (SemaBuiltinCpu(*this, Context.getTargetInfo(), TheCall, - Context.getAuxTargetInfo(), BuiltinID)) - return ExprError(); - break; - case Builtin::BI__builtin_cpu_init: - if (!Context.getTargetInfo().supportsCpuInit()) { - Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported) - << SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc()); - return ExprError(); + // if the call has the elementwise attribute, then + // make sure that an elementwise expr is emitted. + if (FDecl->hasAttr(Attr::AT_ElementwiseBuiltinAlias)) { + switch (FDecl->getNumParams()) { + case 1: { + if (PrepareBuiltinElementwiseMathOneArgCall(TheCall)) + return ExprError(); + + QualType ArgTy = TheCall->getArg(0)->getType(); + if (checkFPMathBuiltinElementType( + *this, TheCall->getArg(0)->getBeginLoc(), ArgTy, 1)) + return ExprError(); + break; } - break; - case Builtin::BI__builtin___CFStringMakeConstantString: - // CFStringMakeConstantString is currently not implemented for GOFF (i.e., - // on z/OS) and for XCOFF (i.e., on AIX). Emit unsupported - if (CheckBuiltinTargetNotInUnsupported( - *this, BuiltinID, TheCall, - {llvm::Triple::GOFF, llvm::Triple::XCOFF})) - return ExprError(); - assert(TheCall->getNumArgs() == 1 && - "Wrong # arguments to builtin CFStringMakeConstantString"); - if (CheckObjCString(TheCall->getArg(0))) - return ExprError(); - break; - case Builtin::BI__builtin_ms_va_start: - case Builtin::BI__builtin_stdarg_start: - case Builtin::BI__builtin_va_start: - if (SemaBuiltinVAStart(BuiltinID, TheCall)) - return ExprError(); - break; - case Builtin::BI__va_start: { - switch (Context.getTargetInfo().getTriple().getArch()) { - case llvm::Triple::aarch64: - case llvm::Triple::arm: - case llvm::Triple::thumb: - if (SemaBuiltinVAStartARMMicrosoft(TheCall)) + case 2: { + if (SemaBuiltinElementwiseMath(TheCall)) + return ExprError(); + + QualType ArgTy = TheCall->getArg(0)->getType(); + if (checkFPMathBuiltinElementType( + *this, TheCall->getArg(0)->getBeginLoc(), ArgTy, 1) || + checkFPMathBuiltinElementType( + *this, TheCall->getArg(1)->getBeginLoc(), ArgTy, 2)) return ExprError(); break; - default: + } + case 3: { + if (SemaBuiltinElementwiseTernaryMath(TheCall)) + return ExprError(); + break; + } + } + + FPOptions FPO; + switch (BuiltinID) { + case Builtin::BI__builtin_cpu_supports: + case Builtin::BI__builtin_cpu_is: + if (SemaBuiltinCpu(*this, Context.getTargetInfo(), TheCall, + Context.getAuxTargetInfo(), BuiltinID)) + return ExprError(); + break; + case Builtin::BI__builtin_cpu_init: + if (!Context.getTargetInfo().supportsCpuInit()) { + Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported) + << SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc()); + return ExprError(); + } + break; + case Builtin::BI__builtin___CFStringMakeConstantString: + // CFStringMakeConstantString is currently not implemented for GOFF (i.e., + // on z/OS) and for XCOFF (i.e., on AIX). Emit unsupported + if (CheckBuiltinTargetNotInUnsupported( + *this, BuiltinID, TheCall, + {llvm::Triple::GOFF, llvm::Triple::XCOFF})) + return ExprError(); + assert(TheCall->getNumArgs() == 1 && + "Wrong # arguments to builtin CFStringMakeConstantString"); + if (CheckObjCString(TheCall->getArg(0))) + return ExprError(); + break; + case Builtin::BI__builtin_ms_va_start: + case Builtin::BI__builtin_stdarg_start: + case Builtin::BI__builtin_va_start: if (SemaBuiltinVAStart(BuiltinID, TheCall)) return ExprError(); break; + case Builtin::BI__va_start: { + switch (Context.getTargetInfo().getTriple().getArch()) { + case llvm::Triple::aarch64: + case llvm::Triple::arm: + case llvm::Triple::thumb: + if (SemaBuiltinVAStartARMMicrosoft(TheCall)) + return ExprError(); + break; + default: + if (SemaBuiltinVAStart(BuiltinID, TheCall)) + return ExprError(); + break; + } + break; } - break; - } - // The acquire, release, and no fence variants are ARM and AArch64 only. - case Builtin::BI_interlockedbittestandset_acq: - case Builtin::BI_interlockedbittestandset_rel: - case Builtin::BI_interlockedbittestandset_nf: - case Builtin::BI_interlockedbittestandreset_acq: - case Builtin::BI_interlockedbittestandreset_rel: - case Builtin::BI_interlockedbittestandreset_nf: - if (CheckBuiltinTargetInSupported( - *this, BuiltinID, TheCall, - {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64})) - return ExprError(); - break; + // The acquire, release, and no fence variants are ARM and AArch64 only. + case Builtin::BI_interlockedbittestandset_acq: + case Builtin::BI_interlockedbittestandset_rel: + case Builtin::BI_interlockedbittestandset_nf: + case Builtin::BI_interlockedbittestandreset_acq: + case Builtin::BI_interlockedbittestandreset_rel: + case Builtin::BI_interlockedbittestandreset_nf: + if (CheckBuiltinTargetInSupported( + *this, BuiltinID, TheCall, + {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64})) + return ExprError(); + break; - // The 64-bit bittest variants are x64, ARM, and AArch64 only. - case Builtin::BI_bittest64: - case Builtin::BI_bittestandcomplement64: - case Builtin::BI_bittestandreset64: - case Builtin::BI_bittestandset64: - case Builtin::BI_interlockedbittestandreset64: - case Builtin::BI_interlockedbittestandset64: - if (CheckBuiltinTargetInSupported(*this, BuiltinID, TheCall, - {llvm::Triple::x86_64, llvm::Triple::arm, - llvm::Triple::thumb, - llvm::Triple::aarch64})) - return ExprError(); - break; + // The 64-bit bittest variants are x64, ARM, and AArch64 only. + case Builtin::BI_bittest64: + case Builtin::BI_bittestandcomplement64: + case Builtin::BI_bittestandreset64: + case Builtin::BI_bittestandset64: + case Builtin::BI_interlockedbittestandreset64: + case Builtin::BI_interlockedbittestandset64: + if (CheckBuiltinTargetInSupported(*this, BuiltinID, TheCall, + {llvm::Triple::x86_64, + llvm::Triple::arm, llvm::Triple::thumb, + llvm::Triple::aarch64})) + return ExprError(); + break; - case Builtin::BI__builtin_set_flt_rounds: - if (CheckBuiltinTargetInSupported(*this, BuiltinID, TheCall, - {llvm::Triple::x86, llvm::Triple::x86_64, - llvm::Triple::arm, llvm::Triple::thumb, - llvm::Triple::aarch64})) - return ExprError(); - break; + case Builtin::BI__builtin_set_flt_rounds: + if (CheckBuiltinTargetInSupported( + *this, BuiltinID, TheCall, + {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm, + llvm::Triple::thumb, llvm::Triple::aarch64})) + return ExprError(); + break; - case Builtin::BI__builtin_isgreater: - case Builtin::BI__builtin_isgreaterequal: - case Builtin::BI__builtin_isless: - case Builtin::BI__builtin_islessequal: - case Builtin::BI__builtin_islessgreater: - case Builtin::BI__builtin_isunordered: - if (SemaBuiltinUnorderedCompare(TheCall, BuiltinID)) - return ExprError(); - break; - case Builtin::BI__builtin_fpclassify: - if (SemaBuiltinFPClassification(TheCall, 6, BuiltinID)) - return ExprError(); - break; - case Builtin::BI__builtin_isfpclass: - if (SemaBuiltinFPClassification(TheCall, 2, BuiltinID)) - return ExprError(); - break; - case Builtin::BI__builtin_isfinite: - case Builtin::BI__builtin_isinf: - case Builtin::BI__builtin_isinf_sign: - case Builtin::BI__builtin_isnan: - case Builtin::BI__builtin_issignaling: - case Builtin::BI__builtin_isnormal: - case Builtin::BI__builtin_issubnormal: - case Builtin::BI__builtin_iszero: - case Builtin::BI__builtin_signbit: - case Builtin::BI__builtin_signbitf: - case Builtin::BI__builtin_signbitl: - if (SemaBuiltinFPClassification(TheCall, 1, BuiltinID)) - return ExprError(); - break; - case Builtin::BI__builtin_shufflevector: - return SemaBuiltinShuffleVector(TheCall); - // TheCall will be freed by the smart pointer here, but that's fine, since - // SemaBuiltinShuffleVector guts it, but then doesn't release it. - case Builtin::BI__builtin_prefetch: - if (SemaBuiltinPrefetch(TheCall)) - return ExprError(); - break; - case Builtin::BI__builtin_alloca_with_align: - case Builtin::BI__builtin_alloca_with_align_uninitialized: - if (SemaBuiltinAllocaWithAlign(TheCall)) - return ExprError(); - [[fallthrough]]; - case Builtin::BI__builtin_alloca: - case Builtin::BI__builtin_alloca_uninitialized: - Diag(TheCall->getBeginLoc(), diag::warn_alloca) - << TheCall->getDirectCallee(); - break; - case Builtin::BI__arithmetic_fence: - if (SemaBuiltinArithmeticFence(TheCall)) - return ExprError(); - break; - case Builtin::BI__assume: - case Builtin::BI__builtin_assume: - if (SemaBuiltinAssume(TheCall)) - return ExprError(); - break; - case Builtin::BI__builtin_assume_aligned: - if (SemaBuiltinAssumeAligned(TheCall)) - return ExprError(); - break; - case Builtin::BI__builtin_dynamic_object_size: - case Builtin::BI__builtin_object_size: - if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3)) - return ExprError(); - break; - case Builtin::BI__builtin_longjmp: - if (SemaBuiltinLongjmp(TheCall)) - return ExprError(); - break; - case Builtin::BI__builtin_setjmp: - if (SemaBuiltinSetjmp(TheCall)) - return ExprError(); - break; - case Builtin::BI__builtin_classify_type: - if (checkArgCount(*this, TheCall, 1)) return true; - TheCall->setType(Context.IntTy); - break; - case Builtin::BI__builtin_complex: - if (SemaBuiltinComplex(TheCall)) - return ExprError(); - break; - case Builtin::BI__builtin_constant_p: { - if (checkArgCount(*this, TheCall, 1)) return true; - ExprResult Arg = DefaultFunctionArrayLvalueConversion(TheCall->getArg(0)); - if (Arg.isInvalid()) return true; - TheCall->setArg(0, Arg.get()); - TheCall->setType(Context.IntTy); - break; - } - case Builtin::BI__builtin_launder: - return SemaBuiltinLaunder(*this, TheCall); - case Builtin::BI__sync_fetch_and_add: - case Builtin::BI__sync_fetch_and_add_1: - case Builtin::BI__sync_fetch_and_add_2: - case Builtin::BI__sync_fetch_and_add_4: - case Builtin::BI__sync_fetch_and_add_8: - case Builtin::BI__sync_fetch_and_add_16: - case Builtin::BI__sync_fetch_and_sub: - case Builtin::BI__sync_fetch_and_sub_1: - case Builtin::BI__sync_fetch_and_sub_2: - case Builtin::BI__sync_fetch_and_sub_4: - case Builtin::BI__sync_fetch_and_sub_8: - case Builtin::BI__sync_fetch_and_sub_16: - case Builtin::BI__sync_fetch_and_or: - case Builtin::BI__sync_fetch_and_or_1: - case Builtin::BI__sync_fetch_and_or_2: - case Builtin::BI__sync_fetch_and_or_4: - case Builtin::BI__sync_fetch_and_or_8: - case Builtin::BI__sync_fetch_and_or_16: - case Builtin::BI__sync_fetch_and_and: - case Builtin::BI__sync_fetch_and_and_1: - case Builtin::BI__sync_fetch_and_and_2: - case Builtin::BI__sync_fetch_and_and_4: - case Builtin::BI__sync_fetch_and_and_8: - case Builtin::BI__sync_fetch_and_and_16: - case Builtin::BI__sync_fetch_and_xor: - case Builtin::BI__sync_fetch_and_xor_1: - case Builtin::BI__sync_fetch_and_xor_2: - case Builtin::BI__sync_fetch_and_xor_4: - case Builtin::BI__sync_fetch_and_xor_8: - case Builtin::BI__sync_fetch_and_xor_16: - case Builtin::BI__sync_fetch_and_nand: - case Builtin::BI__sync_fetch_and_nand_1: - case Builtin::BI__sync_fetch_and_nand_2: - case Builtin::BI__sync_fetch_and_nand_4: - case Builtin::BI__sync_fetch_and_nand_8: - case Builtin::BI__sync_fetch_and_nand_16: - case Builtin::BI__sync_add_and_fetch: - case Builtin::BI__sync_add_and_fetch_1: - case Builtin::BI__sync_add_and_fetch_2: - case Builtin::BI__sync_add_and_fetch_4: - case Builtin::BI__sync_add_and_fetch_8: - case Builtin::BI__sync_add_and_fetch_16: - case Builtin::BI__sync_sub_and_fetch: - case Builtin::BI__sync_sub_and_fetch_1: - case Builtin::BI__sync_sub_and_fetch_2: - case Builtin::BI__sync_sub_and_fetch_4: - case Builtin::BI__sync_sub_and_fetch_8: - case Builtin::BI__sync_sub_and_fetch_16: - case Builtin::BI__sync_and_and_fetch: - case Builtin::BI__sync_and_and_fetch_1: - case Builtin::BI__sync_and_and_fetch_2: - case Builtin::BI__sync_and_and_fetch_4: - case Builtin::BI__sync_and_and_fetch_8: - case Builtin::BI__sync_and_and_fetch_16: - case Builtin::BI__sync_or_and_fetch: - case Builtin::BI__sync_or_and_fetch_1: - case Builtin::BI__sync_or_and_fetch_2: - case Builtin::BI__sync_or_and_fetch_4: - case Builtin::BI__sync_or_and_fetch_8: - case Builtin::BI__sync_or_and_fetch_16: - case Builtin::BI__sync_xor_and_fetch: - case Builtin::BI__sync_xor_and_fetch_1: - case Builtin::BI__sync_xor_and_fetch_2: - case Builtin::BI__sync_xor_and_fetch_4: - case Builtin::BI__sync_xor_and_fetch_8: - case Builtin::BI__sync_xor_and_fetch_16: - case Builtin::BI__sync_nand_and_fetch: - case Builtin::BI__sync_nand_and_fetch_1: - case Builtin::BI__sync_nand_and_fetch_2: - case Builtin::BI__sync_nand_and_fetch_4: - case Builtin::BI__sync_nand_and_fetch_8: - case Builtin::BI__sync_nand_and_fetch_16: - case Builtin::BI__sync_val_compare_and_swap: - case Builtin::BI__sync_val_compare_and_swap_1: - case Builtin::BI__sync_val_compare_and_swap_2: - case Builtin::BI__sync_val_compare_and_swap_4: - case Builtin::BI__sync_val_compare_and_swap_8: - case Builtin::BI__sync_val_compare_and_swap_16: - case Builtin::BI__sync_bool_compare_and_swap: - case Builtin::BI__sync_bool_compare_and_swap_1: - case Builtin::BI__sync_bool_compare_and_swap_2: - case Builtin::BI__sync_bool_compare_and_swap_4: - case Builtin::BI__sync_bool_compare_and_swap_8: - case Builtin::BI__sync_bool_compare_and_swap_16: - case Builtin::BI__sync_lock_test_and_set: - case Builtin::BI__sync_lock_test_and_set_1: - case Builtin::BI__sync_lock_test_and_set_2: - case Builtin::BI__sync_lock_test_and_set_4: - case Builtin::BI__sync_lock_test_and_set_8: - case Builtin::BI__sync_lock_test_and_set_16: - case Builtin::BI__sync_lock_release: - case Builtin::BI__sync_lock_release_1: - case Builtin::BI__sync_lock_release_2: - case Builtin::BI__sync_lock_release_4: - case Builtin::BI__sync_lock_release_8: - case Builtin::BI__sync_lock_release_16: - case Builtin::BI__sync_swap: - case Builtin::BI__sync_swap_1: - case Builtin::BI__sync_swap_2: - case Builtin::BI__sync_swap_4: - case Builtin::BI__sync_swap_8: - case Builtin::BI__sync_swap_16: - return SemaBuiltinAtomicOverloaded(TheCallResult); - case Builtin::BI__sync_synchronize: - Diag(TheCall->getBeginLoc(), diag::warn_atomic_implicit_seq_cst) - << TheCall->getCallee()->getSourceRange(); - break; - case Builtin::BI__builtin_nontemporal_load: - case Builtin::BI__builtin_nontemporal_store: - return SemaBuiltinNontemporalOverloaded(TheCallResult); - case Builtin::BI__builtin_memcpy_inline: { - clang::Expr *SizeOp = TheCall->getArg(2); - // We warn about copying to or from `nullptr` pointers when `size` is - // greater than 0. When `size` is value dependent we cannot evaluate its - // value so we bail out. - if (SizeOp->isValueDependent()) + case Builtin::BI__builtin_isgreater: + case Builtin::BI__builtin_isgreaterequal: + case Builtin::BI__builtin_isless: + case Builtin::BI__builtin_islessequal: + case Builtin::BI__builtin_islessgreater: + case Builtin::BI__builtin_isunordered: + if (SemaBuiltinUnorderedCompare(TheCall, BuiltinID)) + return ExprError(); + break; + case Builtin::BI__builtin_fpclassify: + if (SemaBuiltinFPClassification(TheCall, 6, BuiltinID)) + return ExprError(); + break; + case Builtin::BI__builtin_isfpclass: + if (SemaBuiltinFPClassification(TheCall, 2, BuiltinID)) + return ExprError(); + break; + case Builtin::BI__builtin_isfinite: + case Builtin::BI__builtin_isinf: + case Builtin::BI__builtin_isinf_sign: + case Builtin::BI__builtin_isnan: + case Builtin::BI__builtin_issignaling: + case Builtin::BI__builtin_isnormal: + case Builtin::BI__builtin_issubnormal: + case Builtin::BI__builtin_iszero: + case Builtin::BI__builtin_signbit: + case Builtin::BI__builtin_signbitf: + case Builtin::BI__builtin_signbitl: + if (SemaBuiltinFPClassification(TheCall, 1, BuiltinID)) + return ExprError(); + break; + case Builtin::BI__builtin_shufflevector: + return SemaBuiltinShuffleVector(TheCall); + // TheCall will be freed by the smart pointer here, but that's fine, since + // SemaBuiltinShuffleVector guts it, but then doesn't release it. + case Builtin::BI__builtin_prefetch: + if (SemaBuiltinPrefetch(TheCall)) + return ExprError(); + break; + case Builtin::BI__builtin_alloca_with_align: + case Builtin::BI__builtin_alloca_with_align_uninitialized: + if (SemaBuiltinAllocaWithAlign(TheCall)) + return ExprError(); + [[fallthrough]]; + case Builtin::BI__builtin_alloca: + case Builtin::BI__builtin_alloca_uninitialized: + Diag(TheCall->getBeginLoc(), diag::warn_alloca) + << TheCall->getDirectCallee(); + break; + case Builtin::BI__arithmetic_fence: + if (SemaBuiltinArithmeticFence(TheCall)) + return ExprError(); + break; + case Builtin::BI__assume: + case Builtin::BI__builtin_assume: + if (SemaBuiltinAssume(TheCall)) + return ExprError(); + break; + case Builtin::BI__builtin_assume_aligned: + if (SemaBuiltinAssumeAligned(TheCall)) + return ExprError(); + break; + case Builtin::BI__builtin_dynamic_object_size: + case Builtin::BI__builtin_object_size: + if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3)) + return ExprError(); + break; + case Builtin::BI__builtin_longjmp: + if (SemaBuiltinLongjmp(TheCall)) + return ExprError(); + break; + case Builtin::BI__builtin_setjmp: + if (SemaBuiltinSetjmp(TheCall)) + return ExprError(); + break; + case Builtin::BI__builtin_classify_type: + if (checkArgCount(*this, TheCall, 1)) + return true; + TheCall->setType(Context.IntTy); + break; + case Builtin::BI__builtin_complex: + if (SemaBuiltinComplex(TheCall)) + return ExprError(); + break; + case Builtin::BI__builtin_constant_p: { + if (checkArgCount(*this, TheCall, 1)) + return true; + ExprResult Arg = DefaultFunctionArrayLvalueConversion(TheCall->getArg(0)); + if (Arg.isInvalid()) + return true; + TheCall->setArg(0, Arg.get()); + TheCall->setType(Context.IntTy); break; - if (!SizeOp->EvaluateKnownConstInt(Context).isZero()) { - CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc()); - CheckNonNullArgument(*this, TheCall->getArg(1), TheCall->getExprLoc()); } - break; - } - case Builtin::BI__builtin_memset_inline: { - clang::Expr *SizeOp = TheCall->getArg(2); - // We warn about filling to `nullptr` pointers when `size` is greater than - // 0. When `size` is value dependent we cannot evaluate its value so we bail - // out. - if (SizeOp->isValueDependent()) + case Builtin::BI__builtin_launder: + return SemaBuiltinLaunder(*this, TheCall); + case Builtin::BI__sync_fetch_and_add: + case Builtin::BI__sync_fetch_and_add_1: + case Builtin::BI__sync_fetch_and_add_2: + case Builtin::BI__sync_fetch_and_add_4: + case Builtin::BI__sync_fetch_and_add_8: + case Builtin::BI__sync_fetch_and_add_16: + case Builtin::BI__sync_fetch_and_sub: + case Builtin::BI__sync_fetch_and_sub_1: + case Builtin::BI__sync_fetch_and_sub_2: + case Builtin::BI__sync_fetch_and_sub_4: + case Builtin::BI__sync_fetch_and_sub_8: + case Builtin::BI__sync_fetch_and_sub_16: + case Builtin::BI__sync_fetch_and_or: + case Builtin::BI__sync_fetch_and_or_1: + case Builtin::BI__sync_fetch_and_or_2: + case Builtin::BI__sync_fetch_and_or_4: + case Builtin::BI__sync_fetch_and_or_8: + case Builtin::BI__sync_fetch_and_or_16: + case Builtin::BI__sync_fetch_and_and: + case Builtin::BI__sync_fetch_and_and_1: + case Builtin::BI__sync_fetch_and_and_2: + case Builtin::BI__sync_fetch_and_and_4: + case Builtin::BI__sync_fetch_and_and_8: + case Builtin::BI__sync_fetch_and_and_16: + case Builtin::BI__sync_fetch_and_xor: + case Builtin::BI__sync_fetch_and_xor_1: + case Builtin::BI__sync_fetch_and_xor_2: + case Builtin::BI__sync_fetch_and_xor_4: + case Builtin::BI__sync_fetch_and_xor_8: + case Builtin::BI__sync_fetch_and_xor_16: + case Builtin::BI__sync_fetch_and_nand: + case Builtin::BI__sync_fetch_and_nand_1: + case Builtin::BI__sync_fetch_and_nand_2: + case Builtin::BI__sync_fetch_and_nand_4: + case Builtin::BI__sync_fetch_and_nand_8: + case Builtin::BI__sync_fetch_and_nand_16: + case Builtin::BI__sync_add_and_fetch: + case Builtin::BI__sync_add_and_fetch_1: + case Builtin::BI__sync_add_and_fetch_2: + case Builtin::BI__sync_add_and_fetch_4: + case Builtin::BI__sync_add_and_fetch_8: + case Builtin::BI__sync_add_and_fetch_16: + case Builtin::BI__sync_sub_and_fetch: + case Builtin::BI__sync_sub_and_fetch_1: + case Builtin::BI__sync_sub_and_fetch_2: + case Builtin::BI__sync_sub_and_fetch_4: + case Builtin::BI__sync_sub_and_fetch_8: + case Builtin::BI__sync_sub_and_fetch_16: + case Builtin::BI__sync_and_and_fetch: + case Builtin::BI__sync_and_and_fetch_1: + case Builtin::BI__sync_and_and_fetch_2: + case Builtin::BI__sync_and_and_fetch_4: + case Builtin::BI__sync_and_and_fetch_8: + case Builtin::BI__sync_and_and_fetch_16: + case Builtin::BI__sync_or_and_fetch: + case Builtin::BI__sync_or_and_fetch_1: + case Builtin::BI__sync_or_and_fetch_2: + case Builtin::BI__sync_or_and_fetch_4: + case Builtin::BI__sync_or_and_fetch_8: + case Builtin::BI__sync_or_and_fetch_16: + case Builtin::BI__sync_xor_and_fetch: + case Builtin::BI__sync_xor_and_fetch_1: + case Builtin::BI__sync_xor_and_fetch_2: + case Builtin::BI__sync_xor_and_fetch_4: + case Builtin::BI__sync_xor_and_fetch_8: + case Builtin::BI__sync_xor_and_fetch_16: + case Builtin::BI__sync_nand_and_fetch: + case Builtin::BI__sync_nand_and_fetch_1: + case Builtin::BI__sync_nand_and_fetch_2: + case Builtin::BI__sync_nand_and_fetch_4: + case Builtin::BI__sync_nand_and_fetch_8: + case Builtin::BI__sync_nand_and_fetch_16: + case Builtin::BI__sync_val_compare_and_swap: + case Builtin::BI__sync_val_compare_and_swap_1: + case Builtin::BI__sync_val_compare_and_swap_2: + case Builtin::BI__sync_val_compare_and_swap_4: + case Builtin::BI__sync_val_compare_and_swap_8: + case Builtin::BI__sync_val_compare_and_swap_16: + case Builtin::BI__sync_bool_compare_and_swap: + case Builtin::BI__sync_bool_compare_and_swap_1: + case Builtin::BI__sync_bool_compare_and_swap_2: + case Builtin::BI__sync_bool_compare_and_swap_4: + case Builtin::BI__sync_bool_compare_and_swap_8: + case Builtin::BI__sync_bool_compare_and_swap_16: + case Builtin::BI__sync_lock_test_and_set: + case Builtin::BI__sync_lock_test_and_set_1: + case Builtin::BI__sync_lock_test_and_set_2: + case Builtin::BI__sync_lock_test_and_set_4: + case Builtin::BI__sync_lock_test_and_set_8: + case Builtin::BI__sync_lock_test_and_set_16: + case Builtin::BI__sync_lock_release: + case Builtin::BI__sync_lock_release_1: + case Builtin::BI__sync_lock_release_2: + case Builtin::BI__sync_lock_release_4: + case Builtin::BI__sync_lock_release_8: + case Builtin::BI__sync_lock_release_16: + case Builtin::BI__sync_swap: + case Builtin::BI__sync_swap_1: + case Builtin::BI__sync_swap_2: + case Builtin::BI__sync_swap_4: + case Builtin::BI__sync_swap_8: + case Builtin::BI__sync_swap_16: + return SemaBuiltinAtomicOverloaded(TheCallResult); + case Builtin::BI__sync_synchronize: + Diag(TheCall->getBeginLoc(), diag::warn_atomic_implicit_seq_cst) + << TheCall->getCallee()->getSourceRange(); break; - if (!SizeOp->EvaluateKnownConstInt(Context).isZero()) - CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc()); - break; - } + case Builtin::BI__builtin_nontemporal_load: + case Builtin::BI__builtin_nontemporal_store: + return SemaBuiltinNontemporalOverloaded(TheCallResult); + case Builtin::BI__builtin_memcpy_inline: { + clang::Expr *SizeOp = TheCall->getArg(2); + // We warn about copying to or from `nullptr` pointers when `size` is + // greater than 0. When `size` is value dependent we cannot evaluate its + // value so we bail out. + if (SizeOp->isValueDependent()) + break; + if (!SizeOp->EvaluateKnownConstInt(Context).isZero()) { + CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc()); + CheckNonNullArgument(*this, TheCall->getArg(1), TheCall->getExprLoc()); + } + break; + } + case Builtin::BI__builtin_memset_inline: { + clang::Expr *SizeOp = TheCall->getArg(2); + // We warn about filling to `nullptr` pointers when `size` is greater than + // 0. When `size` is value dependent we cannot evaluate its value so we + // bail out. + if (SizeOp->isValueDependent()) + break; + if (!SizeOp->EvaluateKnownConstInt(Context).isZero()) + CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc()); + break; + } #define BUILTIN(ID, TYPE, ATTRS) #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \ case Builtin::BI##ID: \ @@ -3014,7 +3050,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, } return TheCallResult; -} + } // Get the valid immediate range for the specified NEON type code. static unsigned RFT(unsigned t, bool shift = false, bool ForceQuad = false) { diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 4710bd61a78e14..8f5ca271242d5b 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -5952,6 +5952,35 @@ static void handleBuiltinAliasAttr(Sema &S, Decl *D, D->addAttr(::new (S.Context) BuiltinAliasAttr(S.Context, AL, Ident)); } +static void handleElementwiseBuiltinAliasAttr(Sema &S, Decl *D, + const ParsedAttr &AL) { + if (!AL.isArgIdent(0)) { + S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type) + << AL << 1 << AANT_ArgumentIdentifier; + return; + } + + IdentifierInfo *Ident = AL.getArgAsIdent(0)->Ident; + unsigned BuiltinID = Ident->getBuiltinID(); + StringRef AliasName = cast<FunctionDecl>(D)->getIdentifier()->getName(); + + bool IsAArch64 = S.Context.getTargetInfo().getTriple().isAArch64(); + bool IsARM = S.Context.getTargetInfo().getTriple().isARM(); + bool IsRISCV = S.Context.getTargetInfo().getTriple().isRISCV(); + bool IsHLSL = S.Context.getLangOpts().HLSL; + if ((IsAArch64 && !ArmSveAliasValid(S.Context, BuiltinID, AliasName)) || + (IsARM && !ArmMveAliasValid(BuiltinID, AliasName) && + !ArmCdeAliasValid(BuiltinID, AliasName)) || + (IsRISCV && !RISCVAliasValid(BuiltinID, AliasName)) || + (!IsAArch64 && !IsARM && !IsRISCV && !IsHLSL)) { + S.Diag(AL.getLoc(), diag::err_attribute_elementwise_builtin_alias) << AL; + return; + } + + D->addAttr(::new (S.Context) + ElementwiseBuiltinAliasAttr(S.Context, AL, Ident)); +} + static void handlePreferredTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { if (!AL.hasParsedType()) { S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1; @@ -9852,7 +9881,7 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, handleBuiltinAliasAttr(S, D, AL); break; case ParsedAttr::AT_ElementwiseBuiltinAlias: - handleBuiltinAliasAttr(S, D, AL); + handleElementwiseBuiltinAliasAttr(S, D, AL); break; case ParsedAttr::AT_PreferredType: >From 866007083a306bd4785579b691bbf99143bc0548 Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Thu, 21 Mar 2024 11:43:18 -0700 Subject: [PATCH 4/5] IT WORKS ON CEIL!!! --- clang/lib/Headers/hlsl/hlsl_intrinsics.h | 4 ++-- clang/lib/Sema/SemaChecking.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index f646522e35e84c..1c8e4073026091 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -99,7 +99,7 @@ _HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs) double2 abs(double2); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs) double3 abs(double3); -_HLSL_ELEMENTWISE_BUILTIN_ALIAS(__builtin_elementwise_abs) +_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs) double4 abs(double4); //===----------------------------------------------------------------------===// @@ -251,7 +251,7 @@ _HLSL_BUILTIN_ALIAS(__builtin_elementwise_ceil) double2 ceil(double2); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_ceil) double3 ceil(double3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_ceil) +_HLSL_ELEMENTWISE_BUILTIN_ALIAS(__builtin_ceil) double4 ceil(double4); //===----------------------------------------------------------------------===// diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index f60a38980549e9..c2621bdd2f9ce9 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2242,7 +2242,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, // if the call has the elementwise attribute, then // make sure that an elementwise expr is emitted. - if (FDecl->hasAttr(Attr::AT_ElementwiseBuiltinAlias)) { + if (FDecl->hasAttr<ElementwiseBuiltinAliasAttr>()) { switch (FDecl->getNumParams()) { case 1: { if (PrepareBuiltinElementwiseMathOneArgCall(TheCall)) @@ -2272,7 +2272,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, break; } } - + } FPOptions FPO; switch (BuiltinID) { case Builtin::BI__builtin_cpu_supports: >From 74e4c62bc4d2e3ad6ccf0fe5d7f83db7d309db30 Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Thu, 21 Mar 2024 12:21:24 -0700 Subject: [PATCH 5/5] clang-format attempt --- clang/lib/Headers/hlsl/hlsl_intrinsics.h | 2 +- clang/lib/Sema/SemaChecking.cpp | 606 +++++++++++------------ 2 files changed, 302 insertions(+), 306 deletions(-) diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 1c8e4073026091..9ab34cc57ef322 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -18,7 +18,7 @@ namespace hlsl { #define _HLSL_BUILTIN_ALIAS(builtin) \ __attribute__((clang_builtin_alias(builtin))) -#define _HLSL_ELEMENTWISE_BUILTIN_ALIAS(builtin) \ +#define _HLSL_ELEMENTWISE_BUILTIN_ALIAS(builtin) \ __attribute__((clang_elementwise_builtin_alias(builtin))) #define _HLSL_AVAILABILITY(environment, version) \ __attribute__((availability(environment, introduced = version))) diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index c2621bdd2f9ce9..5460d32e10e343 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2239,10 +2239,9 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, return true; ICEArguments &= ~(1 << ArgNo); } - // if the call has the elementwise attribute, then // make sure that an elementwise expr is emitted. - if (FDecl->hasAttr<ElementwiseBuiltinAliasAttr>()) { + if (FDecl->hasAttr<ElementwiseBuiltinAlias>()) { switch (FDecl->getNumParams()) { case 1: { if (PrepareBuiltinElementwiseMathOneArgCall(TheCall)) @@ -2253,7 +2252,6 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, *this, TheCall->getArg(0)->getBeginLoc(), ArgTy, 1)) return ExprError(); break; - } case 2: { if (SemaBuiltinElementwiseMath(TheCall)) return ExprError(); @@ -2272,321 +2270,319 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, break; } } - } + } + FPOptions FPO; - switch (BuiltinID) { - case Builtin::BI__builtin_cpu_supports: - case Builtin::BI__builtin_cpu_is: - if (SemaBuiltinCpu(*this, Context.getTargetInfo(), TheCall, - Context.getAuxTargetInfo(), BuiltinID)) - return ExprError(); - break; - case Builtin::BI__builtin_cpu_init: - if (!Context.getTargetInfo().supportsCpuInit()) { - Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported) - << SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc()); - return ExprError(); - } - break; - case Builtin::BI__builtin___CFStringMakeConstantString: - // CFStringMakeConstantString is currently not implemented for GOFF (i.e., - // on z/OS) and for XCOFF (i.e., on AIX). Emit unsupported - if (CheckBuiltinTargetNotInUnsupported( - *this, BuiltinID, TheCall, - {llvm::Triple::GOFF, llvm::Triple::XCOFF})) - return ExprError(); - assert(TheCall->getNumArgs() == 1 && - "Wrong # arguments to builtin CFStringMakeConstantString"); - if (CheckObjCString(TheCall->getArg(0))) + switch (BuiltinID) { + case Builtin::BI__builtin_cpu_supports: + case Builtin::BI__builtin_cpu_is: + if (SemaBuiltinCpu(*this, Context.getTargetInfo(), TheCall, + Context.getAuxTargetInfo(), BuiltinID)) + return ExprError(); + break; + case Builtin::BI__builtin_cpu_init: + if (!Context.getTargetInfo().supportsCpuInit()) { + Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported) + << SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc()); + return ExprError(); + } + break; + case Builtin::BI__builtin___CFStringMakeConstantString: + // CFStringMakeConstantString is currently not implemented for GOFF (i.e., + // on z/OS) and for XCOFF (i.e., on AIX). Emit unsupported + if (CheckBuiltinTargetNotInUnsupported( + *this, BuiltinID, TheCall, + {llvm::Triple::GOFF, llvm::Triple::XCOFF})) + return ExprError(); + assert(TheCall->getNumArgs() == 1 && + "Wrong # arguments to builtin CFStringMakeConstantString"); + if (CheckObjCString(TheCall->getArg(0))) + return ExprError(); + break; + case Builtin::BI__builtin_ms_va_start: + case Builtin::BI__builtin_stdarg_start: + case Builtin::BI__builtin_va_start: + if (SemaBuiltinVAStart(BuiltinID, TheCall)) + return ExprError(); + break; + case Builtin::BI__va_start: { + switch (Context.getTargetInfo().getTriple().getArch()) { + case llvm::Triple::aarch64: + case llvm::Triple::arm: + case llvm::Triple::thumb: + if (SemaBuiltinVAStartARMMicrosoft(TheCall)) return ExprError(); break; - case Builtin::BI__builtin_ms_va_start: - case Builtin::BI__builtin_stdarg_start: - case Builtin::BI__builtin_va_start: + default: if (SemaBuiltinVAStart(BuiltinID, TheCall)) return ExprError(); break; - case Builtin::BI__va_start: { - switch (Context.getTargetInfo().getTriple().getArch()) { - case llvm::Triple::aarch64: - case llvm::Triple::arm: - case llvm::Triple::thumb: - if (SemaBuiltinVAStartARMMicrosoft(TheCall)) - return ExprError(); - break; - default: - if (SemaBuiltinVAStart(BuiltinID, TheCall)) - return ExprError(); - break; - } - break; } + break; + } - // The acquire, release, and no fence variants are ARM and AArch64 only. - case Builtin::BI_interlockedbittestandset_acq: - case Builtin::BI_interlockedbittestandset_rel: - case Builtin::BI_interlockedbittestandset_nf: - case Builtin::BI_interlockedbittestandreset_acq: - case Builtin::BI_interlockedbittestandreset_rel: - case Builtin::BI_interlockedbittestandreset_nf: - if (CheckBuiltinTargetInSupported( - *this, BuiltinID, TheCall, - {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64})) - return ExprError(); - break; + // The acquire, release, and no fence variants are ARM and AArch64 only. + case Builtin::BI_interlockedbittestandset_acq: + case Builtin::BI_interlockedbittestandset_rel: + case Builtin::BI_interlockedbittestandset_nf: + case Builtin::BI_interlockedbittestandreset_acq: + case Builtin::BI_interlockedbittestandreset_rel: + case Builtin::BI_interlockedbittestandreset_nf: + if (CheckBuiltinTargetInSupported( + *this, BuiltinID, TheCall, + {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64})) + return ExprError(); + break; - // The 64-bit bittest variants are x64, ARM, and AArch64 only. - case Builtin::BI_bittest64: - case Builtin::BI_bittestandcomplement64: - case Builtin::BI_bittestandreset64: - case Builtin::BI_bittestandset64: - case Builtin::BI_interlockedbittestandreset64: - case Builtin::BI_interlockedbittestandset64: - if (CheckBuiltinTargetInSupported(*this, BuiltinID, TheCall, - {llvm::Triple::x86_64, - llvm::Triple::arm, llvm::Triple::thumb, - llvm::Triple::aarch64})) - return ExprError(); - break; + // The 64-bit bittest variants are x64, ARM, and AArch64 only. + case Builtin::BI_bittest64: + case Builtin::BI_bittestandcomplement64: + case Builtin::BI_bittestandreset64: + case Builtin::BI_bittestandset64: + case Builtin::BI_interlockedbittestandreset64: + case Builtin::BI_interlockedbittestandset64: + if (CheckBuiltinTargetInSupported(*this, BuiltinID, TheCall, + {llvm::Triple::x86_64, llvm::Triple::arm, + llvm::Triple::thumb, + llvm::Triple::aarch64})) + return ExprError(); + break; - case Builtin::BI__builtin_set_flt_rounds: - if (CheckBuiltinTargetInSupported( - *this, BuiltinID, TheCall, - {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm, - llvm::Triple::thumb, llvm::Triple::aarch64})) - return ExprError(); - break; + case Builtin::BI__builtin_set_flt_rounds: + if (CheckBuiltinTargetInSupported(*this, BuiltinID, TheCall, + {llvm::Triple::x86, llvm::Triple::x86_64, + llvm::Triple::arm, llvm::Triple::thumb, + llvm::Triple::aarch64})) + return ExprError(); + break; - case Builtin::BI__builtin_isgreater: - case Builtin::BI__builtin_isgreaterequal: - case Builtin::BI__builtin_isless: - case Builtin::BI__builtin_islessequal: - case Builtin::BI__builtin_islessgreater: - case Builtin::BI__builtin_isunordered: - if (SemaBuiltinUnorderedCompare(TheCall, BuiltinID)) - return ExprError(); - break; - case Builtin::BI__builtin_fpclassify: - if (SemaBuiltinFPClassification(TheCall, 6, BuiltinID)) - return ExprError(); - break; - case Builtin::BI__builtin_isfpclass: - if (SemaBuiltinFPClassification(TheCall, 2, BuiltinID)) - return ExprError(); - break; - case Builtin::BI__builtin_isfinite: - case Builtin::BI__builtin_isinf: - case Builtin::BI__builtin_isinf_sign: - case Builtin::BI__builtin_isnan: - case Builtin::BI__builtin_issignaling: - case Builtin::BI__builtin_isnormal: - case Builtin::BI__builtin_issubnormal: - case Builtin::BI__builtin_iszero: - case Builtin::BI__builtin_signbit: - case Builtin::BI__builtin_signbitf: - case Builtin::BI__builtin_signbitl: - if (SemaBuiltinFPClassification(TheCall, 1, BuiltinID)) - return ExprError(); - break; - case Builtin::BI__builtin_shufflevector: - return SemaBuiltinShuffleVector(TheCall); - // TheCall will be freed by the smart pointer here, but that's fine, since - // SemaBuiltinShuffleVector guts it, but then doesn't release it. - case Builtin::BI__builtin_prefetch: - if (SemaBuiltinPrefetch(TheCall)) - return ExprError(); - break; - case Builtin::BI__builtin_alloca_with_align: - case Builtin::BI__builtin_alloca_with_align_uninitialized: - if (SemaBuiltinAllocaWithAlign(TheCall)) - return ExprError(); - [[fallthrough]]; - case Builtin::BI__builtin_alloca: - case Builtin::BI__builtin_alloca_uninitialized: - Diag(TheCall->getBeginLoc(), diag::warn_alloca) - << TheCall->getDirectCallee(); - break; - case Builtin::BI__arithmetic_fence: - if (SemaBuiltinArithmeticFence(TheCall)) - return ExprError(); - break; - case Builtin::BI__assume: - case Builtin::BI__builtin_assume: - if (SemaBuiltinAssume(TheCall)) - return ExprError(); - break; - case Builtin::BI__builtin_assume_aligned: - if (SemaBuiltinAssumeAligned(TheCall)) - return ExprError(); - break; - case Builtin::BI__builtin_dynamic_object_size: - case Builtin::BI__builtin_object_size: - if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3)) - return ExprError(); - break; - case Builtin::BI__builtin_longjmp: - if (SemaBuiltinLongjmp(TheCall)) - return ExprError(); - break; - case Builtin::BI__builtin_setjmp: - if (SemaBuiltinSetjmp(TheCall)) - return ExprError(); - break; - case Builtin::BI__builtin_classify_type: - if (checkArgCount(*this, TheCall, 1)) - return true; - TheCall->setType(Context.IntTy); - break; - case Builtin::BI__builtin_complex: - if (SemaBuiltinComplex(TheCall)) - return ExprError(); - break; - case Builtin::BI__builtin_constant_p: { - if (checkArgCount(*this, TheCall, 1)) - return true; - ExprResult Arg = DefaultFunctionArrayLvalueConversion(TheCall->getArg(0)); - if (Arg.isInvalid()) - return true; - TheCall->setArg(0, Arg.get()); - TheCall->setType(Context.IntTy); - break; - } - case Builtin::BI__builtin_launder: - return SemaBuiltinLaunder(*this, TheCall); - case Builtin::BI__sync_fetch_and_add: - case Builtin::BI__sync_fetch_and_add_1: - case Builtin::BI__sync_fetch_and_add_2: - case Builtin::BI__sync_fetch_and_add_4: - case Builtin::BI__sync_fetch_and_add_8: - case Builtin::BI__sync_fetch_and_add_16: - case Builtin::BI__sync_fetch_and_sub: - case Builtin::BI__sync_fetch_and_sub_1: - case Builtin::BI__sync_fetch_and_sub_2: - case Builtin::BI__sync_fetch_and_sub_4: - case Builtin::BI__sync_fetch_and_sub_8: - case Builtin::BI__sync_fetch_and_sub_16: - case Builtin::BI__sync_fetch_and_or: - case Builtin::BI__sync_fetch_and_or_1: - case Builtin::BI__sync_fetch_and_or_2: - case Builtin::BI__sync_fetch_and_or_4: - case Builtin::BI__sync_fetch_and_or_8: - case Builtin::BI__sync_fetch_and_or_16: - case Builtin::BI__sync_fetch_and_and: - case Builtin::BI__sync_fetch_and_and_1: - case Builtin::BI__sync_fetch_and_and_2: - case Builtin::BI__sync_fetch_and_and_4: - case Builtin::BI__sync_fetch_and_and_8: - case Builtin::BI__sync_fetch_and_and_16: - case Builtin::BI__sync_fetch_and_xor: - case Builtin::BI__sync_fetch_and_xor_1: - case Builtin::BI__sync_fetch_and_xor_2: - case Builtin::BI__sync_fetch_and_xor_4: - case Builtin::BI__sync_fetch_and_xor_8: - case Builtin::BI__sync_fetch_and_xor_16: - case Builtin::BI__sync_fetch_and_nand: - case Builtin::BI__sync_fetch_and_nand_1: - case Builtin::BI__sync_fetch_and_nand_2: - case Builtin::BI__sync_fetch_and_nand_4: - case Builtin::BI__sync_fetch_and_nand_8: - case Builtin::BI__sync_fetch_and_nand_16: - case Builtin::BI__sync_add_and_fetch: - case Builtin::BI__sync_add_and_fetch_1: - case Builtin::BI__sync_add_and_fetch_2: - case Builtin::BI__sync_add_and_fetch_4: - case Builtin::BI__sync_add_and_fetch_8: - case Builtin::BI__sync_add_and_fetch_16: - case Builtin::BI__sync_sub_and_fetch: - case Builtin::BI__sync_sub_and_fetch_1: - case Builtin::BI__sync_sub_and_fetch_2: - case Builtin::BI__sync_sub_and_fetch_4: - case Builtin::BI__sync_sub_and_fetch_8: - case Builtin::BI__sync_sub_and_fetch_16: - case Builtin::BI__sync_and_and_fetch: - case Builtin::BI__sync_and_and_fetch_1: - case Builtin::BI__sync_and_and_fetch_2: - case Builtin::BI__sync_and_and_fetch_4: - case Builtin::BI__sync_and_and_fetch_8: - case Builtin::BI__sync_and_and_fetch_16: - case Builtin::BI__sync_or_and_fetch: - case Builtin::BI__sync_or_and_fetch_1: - case Builtin::BI__sync_or_and_fetch_2: - case Builtin::BI__sync_or_and_fetch_4: - case Builtin::BI__sync_or_and_fetch_8: - case Builtin::BI__sync_or_and_fetch_16: - case Builtin::BI__sync_xor_and_fetch: - case Builtin::BI__sync_xor_and_fetch_1: - case Builtin::BI__sync_xor_and_fetch_2: - case Builtin::BI__sync_xor_and_fetch_4: - case Builtin::BI__sync_xor_and_fetch_8: - case Builtin::BI__sync_xor_and_fetch_16: - case Builtin::BI__sync_nand_and_fetch: - case Builtin::BI__sync_nand_and_fetch_1: - case Builtin::BI__sync_nand_and_fetch_2: - case Builtin::BI__sync_nand_and_fetch_4: - case Builtin::BI__sync_nand_and_fetch_8: - case Builtin::BI__sync_nand_and_fetch_16: - case Builtin::BI__sync_val_compare_and_swap: - case Builtin::BI__sync_val_compare_and_swap_1: - case Builtin::BI__sync_val_compare_and_swap_2: - case Builtin::BI__sync_val_compare_and_swap_4: - case Builtin::BI__sync_val_compare_and_swap_8: - case Builtin::BI__sync_val_compare_and_swap_16: - case Builtin::BI__sync_bool_compare_and_swap: - case Builtin::BI__sync_bool_compare_and_swap_1: - case Builtin::BI__sync_bool_compare_and_swap_2: - case Builtin::BI__sync_bool_compare_and_swap_4: - case Builtin::BI__sync_bool_compare_and_swap_8: - case Builtin::BI__sync_bool_compare_and_swap_16: - case Builtin::BI__sync_lock_test_and_set: - case Builtin::BI__sync_lock_test_and_set_1: - case Builtin::BI__sync_lock_test_and_set_2: - case Builtin::BI__sync_lock_test_and_set_4: - case Builtin::BI__sync_lock_test_and_set_8: - case Builtin::BI__sync_lock_test_and_set_16: - case Builtin::BI__sync_lock_release: - case Builtin::BI__sync_lock_release_1: - case Builtin::BI__sync_lock_release_2: - case Builtin::BI__sync_lock_release_4: - case Builtin::BI__sync_lock_release_8: - case Builtin::BI__sync_lock_release_16: - case Builtin::BI__sync_swap: - case Builtin::BI__sync_swap_1: - case Builtin::BI__sync_swap_2: - case Builtin::BI__sync_swap_4: - case Builtin::BI__sync_swap_8: - case Builtin::BI__sync_swap_16: - return SemaBuiltinAtomicOverloaded(TheCallResult); - case Builtin::BI__sync_synchronize: - Diag(TheCall->getBeginLoc(), diag::warn_atomic_implicit_seq_cst) - << TheCall->getCallee()->getSourceRange(); - break; - case Builtin::BI__builtin_nontemporal_load: - case Builtin::BI__builtin_nontemporal_store: - return SemaBuiltinNontemporalOverloaded(TheCallResult); - case Builtin::BI__builtin_memcpy_inline: { - clang::Expr *SizeOp = TheCall->getArg(2); - // We warn about copying to or from `nullptr` pointers when `size` is - // greater than 0. When `size` is value dependent we cannot evaluate its - // value so we bail out. - if (SizeOp->isValueDependent()) - break; - if (!SizeOp->EvaluateKnownConstInt(Context).isZero()) { - CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc()); - CheckNonNullArgument(*this, TheCall->getArg(1), TheCall->getExprLoc()); - } + case Builtin::BI__builtin_isgreater: + case Builtin::BI__builtin_isgreaterequal: + case Builtin::BI__builtin_isless: + case Builtin::BI__builtin_islessequal: + case Builtin::BI__builtin_islessgreater: + case Builtin::BI__builtin_isunordered: + if (SemaBuiltinUnorderedCompare(TheCall, BuiltinID)) + return ExprError(); + break; + case Builtin::BI__builtin_fpclassify: + if (SemaBuiltinFPClassification(TheCall, 6, BuiltinID)) + return ExprError(); + break; + case Builtin::BI__builtin_isfpclass: + if (SemaBuiltinFPClassification(TheCall, 2, BuiltinID)) + return ExprError(); + break; + case Builtin::BI__builtin_isfinite: + case Builtin::BI__builtin_isinf: + case Builtin::BI__builtin_isinf_sign: + case Builtin::BI__builtin_isnan: + case Builtin::BI__builtin_issignaling: + case Builtin::BI__builtin_isnormal: + case Builtin::BI__builtin_issubnormal: + case Builtin::BI__builtin_iszero: + case Builtin::BI__builtin_signbit: + case Builtin::BI__builtin_signbitf: + case Builtin::BI__builtin_signbitl: + if (SemaBuiltinFPClassification(TheCall, 1, BuiltinID)) + return ExprError(); + break; + case Builtin::BI__builtin_shufflevector: + return SemaBuiltinShuffleVector(TheCall); + // TheCall will be freed by the smart pointer here, but that's fine, since + // SemaBuiltinShuffleVector guts it, but then doesn't release it. + case Builtin::BI__builtin_prefetch: + if (SemaBuiltinPrefetch(TheCall)) + return ExprError(); + break; + case Builtin::BI__builtin_alloca_with_align: + case Builtin::BI__builtin_alloca_with_align_uninitialized: + if (SemaBuiltinAllocaWithAlign(TheCall)) + return ExprError(); + [[fallthrough]]; + case Builtin::BI__builtin_alloca: + case Builtin::BI__builtin_alloca_uninitialized: + Diag(TheCall->getBeginLoc(), diag::warn_alloca) + << TheCall->getDirectCallee(); + break; + case Builtin::BI__arithmetic_fence: + if (SemaBuiltinArithmeticFence(TheCall)) + return ExprError(); + break; + case Builtin::BI__assume: + case Builtin::BI__builtin_assume: + if (SemaBuiltinAssume(TheCall)) + return ExprError(); + break; + case Builtin::BI__builtin_assume_aligned: + if (SemaBuiltinAssumeAligned(TheCall)) + return ExprError(); + break; + case Builtin::BI__builtin_dynamic_object_size: + case Builtin::BI__builtin_object_size: + if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3)) + return ExprError(); + break; + case Builtin::BI__builtin_longjmp: + if (SemaBuiltinLongjmp(TheCall)) + return ExprError(); + break; + case Builtin::BI__builtin_setjmp: + if (SemaBuiltinSetjmp(TheCall)) + return ExprError(); + break; + case Builtin::BI__builtin_classify_type: + if (checkArgCount(*this, TheCall, 1)) return true; + TheCall->setType(Context.IntTy); + break; + case Builtin::BI__builtin_complex: + if (SemaBuiltinComplex(TheCall)) + return ExprError(); + break; + case Builtin::BI__builtin_constant_p: { + if (checkArgCount(*this, TheCall, 1)) return true; + ExprResult Arg = DefaultFunctionArrayLvalueConversion(TheCall->getArg(0)); + if (Arg.isInvalid()) return true; + TheCall->setArg(0, Arg.get()); + TheCall->setType(Context.IntTy); + break; + } + case Builtin::BI__builtin_launder: + return SemaBuiltinLaunder(*this, TheCall); + case Builtin::BI__sync_fetch_and_add: + case Builtin::BI__sync_fetch_and_add_1: + case Builtin::BI__sync_fetch_and_add_2: + case Builtin::BI__sync_fetch_and_add_4: + case Builtin::BI__sync_fetch_and_add_8: + case Builtin::BI__sync_fetch_and_add_16: + case Builtin::BI__sync_fetch_and_sub: + case Builtin::BI__sync_fetch_and_sub_1: + case Builtin::BI__sync_fetch_and_sub_2: + case Builtin::BI__sync_fetch_and_sub_4: + case Builtin::BI__sync_fetch_and_sub_8: + case Builtin::BI__sync_fetch_and_sub_16: + case Builtin::BI__sync_fetch_and_or: + case Builtin::BI__sync_fetch_and_or_1: + case Builtin::BI__sync_fetch_and_or_2: + case Builtin::BI__sync_fetch_and_or_4: + case Builtin::BI__sync_fetch_and_or_8: + case Builtin::BI__sync_fetch_and_or_16: + case Builtin::BI__sync_fetch_and_and: + case Builtin::BI__sync_fetch_and_and_1: + case Builtin::BI__sync_fetch_and_and_2: + case Builtin::BI__sync_fetch_and_and_4: + case Builtin::BI__sync_fetch_and_and_8: + case Builtin::BI__sync_fetch_and_and_16: + case Builtin::BI__sync_fetch_and_xor: + case Builtin::BI__sync_fetch_and_xor_1: + case Builtin::BI__sync_fetch_and_xor_2: + case Builtin::BI__sync_fetch_and_xor_4: + case Builtin::BI__sync_fetch_and_xor_8: + case Builtin::BI__sync_fetch_and_xor_16: + case Builtin::BI__sync_fetch_and_nand: + case Builtin::BI__sync_fetch_and_nand_1: + case Builtin::BI__sync_fetch_and_nand_2: + case Builtin::BI__sync_fetch_and_nand_4: + case Builtin::BI__sync_fetch_and_nand_8: + case Builtin::BI__sync_fetch_and_nand_16: + case Builtin::BI__sync_add_and_fetch: + case Builtin::BI__sync_add_and_fetch_1: + case Builtin::BI__sync_add_and_fetch_2: + case Builtin::BI__sync_add_and_fetch_4: + case Builtin::BI__sync_add_and_fetch_8: + case Builtin::BI__sync_add_and_fetch_16: + case Builtin::BI__sync_sub_and_fetch: + case Builtin::BI__sync_sub_and_fetch_1: + case Builtin::BI__sync_sub_and_fetch_2: + case Builtin::BI__sync_sub_and_fetch_4: + case Builtin::BI__sync_sub_and_fetch_8: + case Builtin::BI__sync_sub_and_fetch_16: + case Builtin::BI__sync_and_and_fetch: + case Builtin::BI__sync_and_and_fetch_1: + case Builtin::BI__sync_and_and_fetch_2: + case Builtin::BI__sync_and_and_fetch_4: + case Builtin::BI__sync_and_and_fetch_8: + case Builtin::BI__sync_and_and_fetch_16: + case Builtin::BI__sync_or_and_fetch: + case Builtin::BI__sync_or_and_fetch_1: + case Builtin::BI__sync_or_and_fetch_2: + case Builtin::BI__sync_or_and_fetch_4: + case Builtin::BI__sync_or_and_fetch_8: + case Builtin::BI__sync_or_and_fetch_16: + case Builtin::BI__sync_xor_and_fetch: + case Builtin::BI__sync_xor_and_fetch_1: + case Builtin::BI__sync_xor_and_fetch_2: + case Builtin::BI__sync_xor_and_fetch_4: + case Builtin::BI__sync_xor_and_fetch_8: + case Builtin::BI__sync_xor_and_fetch_16: + case Builtin::BI__sync_nand_and_fetch: + case Builtin::BI__sync_nand_and_fetch_1: + case Builtin::BI__sync_nand_and_fetch_2: + case Builtin::BI__sync_nand_and_fetch_4: + case Builtin::BI__sync_nand_and_fetch_8: + case Builtin::BI__sync_nand_and_fetch_16: + case Builtin::BI__sync_val_compare_and_swap: + case Builtin::BI__sync_val_compare_and_swap_1: + case Builtin::BI__sync_val_compare_and_swap_2: + case Builtin::BI__sync_val_compare_and_swap_4: + case Builtin::BI__sync_val_compare_and_swap_8: + case Builtin::BI__sync_val_compare_and_swap_16: + case Builtin::BI__sync_bool_compare_and_swap: + case Builtin::BI__sync_bool_compare_and_swap_1: + case Builtin::BI__sync_bool_compare_and_swap_2: + case Builtin::BI__sync_bool_compare_and_swap_4: + case Builtin::BI__sync_bool_compare_and_swap_8: + case Builtin::BI__sync_bool_compare_and_swap_16: + case Builtin::BI__sync_lock_test_and_set: + case Builtin::BI__sync_lock_test_and_set_1: + case Builtin::BI__sync_lock_test_and_set_2: + case Builtin::BI__sync_lock_test_and_set_4: + case Builtin::BI__sync_lock_test_and_set_8: + case Builtin::BI__sync_lock_test_and_set_16: + case Builtin::BI__sync_lock_release: + case Builtin::BI__sync_lock_release_1: + case Builtin::BI__sync_lock_release_2: + case Builtin::BI__sync_lock_release_4: + case Builtin::BI__sync_lock_release_8: + case Builtin::BI__sync_lock_release_16: + case Builtin::BI__sync_swap: + case Builtin::BI__sync_swap_1: + case Builtin::BI__sync_swap_2: + case Builtin::BI__sync_swap_4: + case Builtin::BI__sync_swap_8: + case Builtin::BI__sync_swap_16: + return SemaBuiltinAtomicOverloaded(TheCallResult); + case Builtin::BI__sync_synchronize: + Diag(TheCall->getBeginLoc(), diag::warn_atomic_implicit_seq_cst) + << TheCall->getCallee()->getSourceRange(); + break; + case Builtin::BI__builtin_nontemporal_load: + case Builtin::BI__builtin_nontemporal_store: + return SemaBuiltinNontemporalOverloaded(TheCallResult); + case Builtin::BI__builtin_memcpy_inline: { + clang::Expr *SizeOp = TheCall->getArg(2); + // We warn about copying to or from `nullptr` pointers when `size` is + // greater than 0. When `size` is value dependent we cannot evaluate its + // value so we bail out. + if (SizeOp->isValueDependent()) break; + if (!SizeOp->EvaluateKnownConstInt(Context).isZero()) { + CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc()); + CheckNonNullArgument(*this, TheCall->getArg(1), TheCall->getExprLoc()); } - case Builtin::BI__builtin_memset_inline: { - clang::Expr *SizeOp = TheCall->getArg(2); - // We warn about filling to `nullptr` pointers when `size` is greater than - // 0. When `size` is value dependent we cannot evaluate its value so we - // bail out. - if (SizeOp->isValueDependent()) - break; - if (!SizeOp->EvaluateKnownConstInt(Context).isZero()) - CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc()); + break; + } + case Builtin::BI__builtin_memset_inline: { + clang::Expr *SizeOp = TheCall->getArg(2); + // We warn about filling to `nullptr` pointers when `size` is greater than + // 0. When `size` is value dependent we cannot evaluate its value so we bail + // out. + if (SizeOp->isValueDependent()) break; - } + if (!SizeOp->EvaluateKnownConstInt(Context).isZero()) + CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc()); + break; + } #define BUILTIN(ID, TYPE, ATTRS) #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \ case Builtin::BI##ID: \ @@ -3050,7 +3046,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, } return TheCallResult; - } +} // Get the valid immediate range for the specified NEON type code. static unsigned RFT(unsigned t, bool shift = false, bool ForceQuad = false) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits