}
// Since return type of reserve_read/write_pipe built-in function is
- // reserve_id_t, which is not defined in the builtin def file , we used int
- // as return type and need to override the return type of these functions.
- Call->setType(S.Context.OCLReserveIDTy);
-
- return false;
-}
-
-// Performs a semantic analysis on {work_group_/sub_group_
-// /_}commit_{read/write}_pipe
-// \param S Reference to the semantic analyzer.
-// \param Call The call to the builtin function to be analyzed.
-// \return True if a semantic error was found, false otherwise.
-static bool SemaBuiltinCommitRWPipe(Sema &S, CallExpr *Call) {
- if (checkArgCount(S, Call, 2))
- return true;
-
- if (checkOpenCLPipeArg(S, Call))
- return true;
-
- // Check reserve_id_t.
- if (!Call->getArg(1)->getType()->isReserveIDT()) {
- S.Diag(Call->getLocStart(), diag::err_opencl_builtin_pipe_invalid_arg)
- << Call->getDirectCallee() << S.Context.OCLReserveIDTy
- << Call->getArg(1)->getType() << Call->getArg(1)->getSourceRange();
- return true;
- }
-
- return false;
-}
-
-// Performs a semantic analysis on the call to built-in Pipe
-// Query Functions.
-// \param S Reference to the semantic analyzer.
-// \param Call The call to the builtin function to be analyzed.
-// \return True if a semantic error was found, false otherwise.
-static bool SemaBuiltinPipePackets(Sema &S, CallExpr *Call) {
- if (checkArgCount(S, Call, 1))
- return true;
-
- if (!Call->getArg(0)->getType()->isPipeType()) {
- S.Diag(Call->getLocStart(), diag::err_opencl_builtin_pipe_first_arg)
- << Call->getDirectCallee() << Call->getArg(0)->getSourceRange();
- return true;
- }
-
- return false;
-}
-
-// OpenCL v2.0 s6.13.9 - Address space qualifier functions.
-// Performs semantic analysis for the to_global/local/private call.
-// \param S Reference to the semantic analyzer.
-// \param BuiltinID ID of the builtin function.
-// \param Call A pointer to the builtin call.
-// \return True if a semantic error has been found, false otherwise.
-static bool SemaOpenCLBuiltinToAddr(Sema &S, unsigned BuiltinID,
- CallExpr *Call) {
- if (Call->getNumArgs() != 1) {
- S.Diag(Call->getLocStart(), diag::err_opencl_builtin_to_addr_arg_num)
- << Call->getDirectCallee() << Call->getSourceRange();
- return true;
- }
-
- auto RT = Call->getArg(0)->getType();
- if (!RT->isPointerType() || RT->getPointeeType()
- .getAddressSpace() == LangAS::opencl_constant) {
- S.Diag(Call->getLocStart(), diag::err_opencl_builtin_to_addr_invalid_arg)
- << Call->getArg(0) << Call->getDirectCallee() << Call->getSourceRange();
- return true;
- }
-
- RT = RT->getPointeeType();
- auto Qual = RT.getQualifiers();
- switch (BuiltinID) {
- case Builtin::BIto_global:
- Qual.setAddressSpace(LangAS::opencl_global);
- break;
- case Builtin::BIto_local:
- Qual.setAddressSpace(LangAS::opencl_local);
- break;
- case Builtin::BIto_private:
- Qual.setAddressSpace(LangAS::opencl_private);
- break;
- default:
- llvm_unreachable("Invalid builtin function");
- }
- Call->setType(S.Context.getPointerType(S.Context.getQualifiedType(
- RT.getUnqualifiedType(), Qual)));
-
- return false;
-}
-
-// Emit an error and return true if the current architecture is not in the list
-// of supported architectures.
-static bool
-CheckBuiltinTargetSupport(Sema &S, unsigned BuiltinID, CallExpr *TheCall,
- ArrayRef<llvm::Triple::ArchType> SupportedArchs) {
- llvm::Triple::ArchType CurArch =
- S.getASTContext().getTargetInfo().getTriple().getArch();
- if (llvm::is_contained(SupportedArchs, CurArch))
- return false;
- S.Diag(TheCall->getLocStart(), diag::err_builtin_target_unsupported)
- << TheCall->getSourceRange();
- return true;
-}
-
-ExprResult
-Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
- CallExpr *TheCall) {
- ExprResult TheCallResult(TheCall);
-
- // Find out if any arguments are required to be integer constant expressions.
- unsigned ICEArguments = 0;
- ASTContext::GetBuiltinTypeError Error;
- Context.GetBuiltinType(BuiltinID, Error, &ICEArguments);
- if (Error != ASTContext::GE_None)
- ICEArguments = 0; // Don't diagnose previously diagnosed errors.
-
- // If any arguments are required to be ICE's, check and diagnose.
- for (unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
- // Skip arguments not required to be ICE's.
- if ((ICEArguments & (1 << ArgNo)) == 0) continue;
-
- llvm::APSInt Result;
- if (SemaBuiltinConstantArg(TheCall, ArgNo, Result))
- return true;
- ICEArguments &= ~(1 << ArgNo);
- }
-
- switch (BuiltinID) {
- case Builtin::BI__builtin___CFStringMakeConstantString:
- 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::arm:
- case llvm::Triple::thumb:
- if (SemaBuiltinVAStartARMMicrosoft(TheCall))
- return ExprError();
- break;
- default:
- if (SemaBuiltinVAStart(BuiltinID, TheCall))
- return ExprError();
- 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 (CheckBuiltinTargetSupport(
- *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 (CheckBuiltinTargetSupport(*this, BuiltinID, TheCall,
- {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))
- return ExprError();
- break;
- case Builtin::BI__builtin_fpclassify:
- if (SemaBuiltinFPClassification(TheCall, 6))
- 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_isnormal:
- if (SemaBuiltinFPClassification(TheCall, 1))
- 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:
- if (SemaBuiltinAllocaWithAlign(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_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_setjmp:
- case Builtin::BI_setjmpex:
- if (checkArgCount(*this, TheCall, 1))
- return true;
- break;
- case Builtin::BI__builtin_classify_type:
- if (checkArgCount(*this, TheCall, 1)) return true;
- TheCall->setType(Context.IntTy);
- break;
- case Builtin::BI__builtin_constant_p:
- if (checkArgCount(*this, TheCall, 1)) return true;
- TheCall->setType(Context.IntTy);
- break;
- 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__builtin_nontemporal_load:
- case Builtin::BI__builtin_nontemporal_store:
- return SemaBuiltinNontemporalOverloaded(TheCallResult);
-#define BUILTIN(ID, TYPE, ATTRS)
-#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
- case Builtin::BI##ID: \
- return SemaAtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
-#include "clang/Basic/Builtins.def"
- case Builtin::BI__annotation:
- if (SemaBuiltinMSVCAnnotation(*this, TheCall))
- return ExprError();
- break;
- case Builtin::BI__builtin_annotation:
- if (SemaBuiltinAnnotation(*this, TheCall))
- return ExprError();
- break;
- case Builtin::BI__builtin_addressof:
- if (SemaBuiltinAddressof(*this, TheCall))
- return ExprError();
- break;
- case Builtin::BI__builtin_add_overflow:
- case Builtin::BI__builtin_sub_overflow:
- case Builtin::BI__builtin_mul_overflow:
- if (SemaBuiltinOverflow(*this, TheCall))
- return ExprError();
- break;
- case Builtin::BI__builtin_operator_new:
- case Builtin::BI__builtin_operator_delete: {
- bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
- ExprResult Res =
- SemaBuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
- if (Res.isInvalid())
- CorrectDelayedTyposInExpr(TheCallResult.get());
- return Res;
- }
- case Builtin::BI__builtin_dump_struct: {
- // We first want to ensure we are called with 2 arguments
- if (checkArgCount(*this, TheCall, 2))
- return ExprError();
- // Ensure that the first argument is of type 'struct XX *'
- const Expr *PtrArg = TheCall->getArg(0)->IgnoreParenImpCasts();
- const QualType PtrArgType = PtrArg->getType();
- if (!PtrArgType->isPointerType() ||
- !PtrArgType->getPointeeType()->isRecordType()) {
- Diag(PtrArg->getLocStart(), diag::err_typecheck_convert_incompatible)
- << PtrArgType << "structure pointer" << 1 << 0 << 3 << 1 << PtrArgType
- << "structure pointer";
- return ExprError();
+ // reserve_id_t, which is not defined in the builtin def file , we used int\r
+ // as return type and need to override the return type of these functions.\r
+ Call->setType(S.Context.OCLReserveIDTy);\r
+\r
+ return false;\r
+}\r
+\r
+// Performs a semantic analysis on {work_group_/sub_group_\r
+// /_}commit_{read/write}_pipe\r
+// \param S Reference to the semantic analyzer.\r
+// \param Call The call to the builtin function to be analyzed.\r
+// \return True if a semantic error was found, false otherwise.\r
+static bool SemaBuiltinCommitRWPipe(Sema &S, CallExpr *Call) {\r
+ if (checkArgCount(S, Call, 2))\r
+ return true;\r
+\r
+ if (checkOpenCLPipeArg(S, Call))\r
+ return true;\r
+\r
+ // Check reserve_id_t.\r
+ if (!Call->getArg(1)->getType()->isReserveIDT()) {\r
+ S.Diag(Call->getLocStart(), diag::err_opencl_builtin_pipe_invalid_arg)\r
+ << Call->getDirectCallee() << S.Context.OCLReserveIDTy\r
+ << Call->getArg(1)->getType() << Call->getArg(1)->getSourceRange();\r
+ return true;\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+// Performs a semantic analysis on the call to built-in Pipe\r
+// Query Functions.\r
+// \param S Reference to the semantic analyzer.\r
+// \param Call The call to the builtin function to be analyzed.\r
+// \return True if a semantic error was found, false otherwise.\r
+static bool SemaBuiltinPipePackets(Sema &S, CallExpr *Call) {\r
+ if (checkArgCount(S, Call, 1))\r
+ return true;\r
+\r
+ if (!Call->getArg(0)->getType()->isPipeType()) {\r
+ S.Diag(Call->getLocStart(), diag::err_opencl_builtin_pipe_first_arg)\r
+ << Call->getDirectCallee() << Call->getArg(0)->getSourceRange();\r
+ return true;\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+// OpenCL v2.0 s6.13.9 - Address space qualifier functions.\r
+// Performs semantic analysis for the to_global/local/private call.\r
+// \param S Reference to the semantic analyzer.\r
+// \param BuiltinID ID of the builtin function.\r
+// \param Call A pointer to the builtin call.\r
+// \return True if a semantic error has been found, false otherwise.\r
+static bool SemaOpenCLBuiltinToAddr(Sema &S, unsigned BuiltinID,\r
+ CallExpr *Call) {\r
+ if (Call->getNumArgs() != 1) {\r
+ S.Diag(Call->getLocStart(), diag::err_opencl_builtin_to_addr_arg_num)\r
+ << Call->getDirectCallee() << Call->getSourceRange();\r
+ return true;\r
+ }\r
+\r
+ auto RT = Call->getArg(0)->getType();\r
+ if (!RT->isPointerType() || RT->getPointeeType()\r
+ .getAddressSpace() == LangAS::opencl_constant) {\r
+ S.Diag(Call->getLocStart(), diag::err_opencl_builtin_to_addr_invalid_arg)\r
+ << Call->getArg(0) << Call->getDirectCallee() << Call->getSourceRange();\r
+ return true;\r
+ }\r
+\r
+ RT = RT->getPointeeType();\r
+ auto Qual = RT.getQualifiers();\r
+ switch (BuiltinID) {\r
+ case Builtin::BIto_global:\r
+ Qual.setAddressSpace(LangAS::opencl_global);\r
+ break;\r
+ case Builtin::BIto_local:\r
+ Qual.setAddressSpace(LangAS::opencl_local);\r
+ break;\r
+ case Builtin::BIto_private:\r
+ Qual.setAddressSpace(LangAS::opencl_private);\r
+ break;\r
+ default:\r
+ llvm_unreachable("Invalid builtin function");\r
+ }\r
+ Call->setType(S.Context.getPointerType(S.Context.getQualifiedType(\r
+ RT.getUnqualifiedType(), Qual)));\r
+\r
+ return false;\r
+}\r
+\r
+// Emit an error and return true if the current architecture is not in the list\r
+// of supported architectures.\r
+static bool\r
+CheckBuiltinTargetSupport(Sema &S, unsigned BuiltinID, CallExpr *TheCall,\r
+ ArrayRef<llvm::Triple::ArchType> SupportedArchs) {\r
+ llvm::Triple::ArchType CurArch =\r
+ S.getASTContext().getTargetInfo().getTriple().getArch();\r
+ if (llvm::is_contained(SupportedArchs, CurArch))\r
+ return false;\r
+ S.Diag(TheCall->getLocStart(), diag::err_builtin_target_unsupported)\r
+ << TheCall->getSourceRange();\r
+ return true;\r
+}\r
+\r
+ExprResult\r
+Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,\r
+ CallExpr *TheCall) {\r
+ ExprResult TheCallResult(TheCall);\r
+\r
+ // Find out if any arguments are required to be integer constant expressions.\r
+ unsigned ICEArguments = 0;\r
+ ASTContext::GetBuiltinTypeError Error;\r
+ Context.GetBuiltinType(BuiltinID, Error, &ICEArguments);\r
+ if (Error != ASTContext::GE_None)\r
+ ICEArguments = 0; // Don't diagnose previously diagnosed errors.\r
+ \r
+ // If any arguments are required to be ICE's, check and diagnose.\r
+ for (unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {\r
+ // Skip arguments not required to be ICE's.\r
+ if ((ICEArguments & (1 << ArgNo)) == 0) continue;\r
+ \r
+ llvm::APSInt Result;\r
+ if (SemaBuiltinConstantArg(TheCall, ArgNo, Result))\r
+ return true;\r
+ ICEArguments &= ~(1 << ArgNo);\r
+ }\r
+ \r
+ switch (BuiltinID) {\r
+ case Builtin::BI__builtin___CFStringMakeConstantString:\r
+ assert(TheCall->getNumArgs() == 1 &&\r
+ "Wrong # arguments to builtin CFStringMakeConstantString");\r
+ if (CheckObjCString(TheCall->getArg(0)))\r
+ return ExprError();\r
+ break;\r
+ case Builtin::BI__builtin_ms_va_start:\r
+ case Builtin::BI__builtin_stdarg_start:\r
+ case Builtin::BI__builtin_va_start:\r
+ if (SemaBuiltinVAStart(BuiltinID, TheCall))\r
+ return ExprError();\r
+ break;\r
+ case Builtin::BI__va_start: {\r
+ switch (Context.getTargetInfo().getTriple().getArch()) {\r
+ case llvm::Triple::arm:\r
+ case llvm::Triple::thumb:\r
+ if (SemaBuiltinVAStartARMMicrosoft(TheCall))\r
+ return ExprError();\r
+ break;\r
+ default:\r
+ if (SemaBuiltinVAStart(BuiltinID, TheCall))\r
+ return ExprError();\r
+ break;\r
+ }\r
+ break;\r
+ }\r
+\r
+ // The acquire, release, and no fence variants are ARM and AArch64 only.\r
+ case Builtin::BI_interlockedbittestandset_acq:\r
+ case Builtin::BI_interlockedbittestandset_rel:\r
+ case Builtin::BI_interlockedbittestandset_nf:\r
+ case Builtin::BI_interlockedbittestandreset_acq:\r
+ case Builtin::BI_interlockedbittestandreset_rel:\r
+ case Builtin::BI_interlockedbittestandreset_nf:\r
+ if (CheckBuiltinTargetSupport(\r
+ *this, BuiltinID, TheCall,\r
+ {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))\r
+ return ExprError();\r
+ break;\r
+\r
+ // The 64-bit bittest variants are x64, ARM, and AArch64 only.\r
+ case Builtin::BI_bittest64:\r
+ case Builtin::BI_bittestandcomplement64:\r
+ case Builtin::BI_bittestandreset64:\r
+ case Builtin::BI_bittestandset64:\r
+ case Builtin::BI_interlockedbittestandreset64:\r
+ case Builtin::BI_interlockedbittestandset64:\r
+ if (CheckBuiltinTargetSupport(*this, BuiltinID, TheCall,\r
+ {llvm::Triple::x86_64, llvm::Triple::arm,\r
+ llvm::Triple::thumb, llvm::Triple::aarch64}))\r
+ return ExprError();\r
+ break;\r
+\r
+ case Builtin::BI__builtin_isgreater:\r
+ case Builtin::BI__builtin_isgreaterequal:\r
+ case Builtin::BI__builtin_isless:\r
+ case Builtin::BI__builtin_islessequal:\r
+ case Builtin::BI__builtin_islessgreater:\r
+ case Builtin::BI__builtin_isunordered:\r
+ if (SemaBuiltinUnorderedCompare(TheCall))\r
+ return ExprError();\r
+ break;\r
+ case Builtin::BI__builtin_fpclassify:\r
+ if (SemaBuiltinFPClassification(TheCall, 6))\r
+ return ExprError();\r
+ break;\r
+ case Builtin::BI__builtin_isfinite:\r
+ case Builtin::BI__builtin_isinf:\r
+ case Builtin::BI__builtin_isinf_sign:\r
+ case Builtin::BI__builtin_isnan:\r
+ case Builtin::BI__builtin_isnormal:\r
+ case Builtin::BI__builtin_signbit:\r
+ case Builtin::BI__builtin_signbitf:\r
+ case Builtin::BI__builtin_signbitl:\r
+ if (SemaBuiltinFPClassification(TheCall, 1))\r
+ return ExprError();\r
+ break;\r
+ case Builtin::BI__builtin_shufflevector:\r
+ return SemaBuiltinShuffleVector(TheCall);\r
+ // TheCall will be freed by the smart pointer here, but that's fine, since\r
+ // SemaBuiltinShuffleVector guts it, but then doesn't release it.\r
+ case Builtin::BI__builtin_prefetch:\r
+ if (SemaBuiltinPrefetch(TheCall))\r
+ return ExprError();\r
+ break;\r
+ case Builtin::BI__builtin_alloca_with_align:\r
+ if (SemaBuiltinAllocaWithAlign(TheCall))\r
+ return ExprError();\r
+ break;\r
+ case Builtin::BI__assume:\r
+ case Builtin::BI__builtin_assume:\r
+ if (SemaBuiltinAssume(TheCall))\r
+ return ExprError();\r
+ break;\r
+ case Builtin::BI__builtin_assume_aligned:\r
+ if (SemaBuiltinAssumeAligned(TheCall))\r
+ return ExprError();\r
+ break;\r
+ case Builtin::BI__builtin_object_size:\r
+ if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3))\r
+ return ExprError();\r
+ break;\r
+ case Builtin::BI__builtin_longjmp:\r
+ if (SemaBuiltinLongjmp(TheCall))\r
+ return ExprError();\r
+ break;\r
+ case Builtin::BI__builtin_setjmp:\r
+ if (SemaBuiltinSetjmp(TheCall))\r
+ return ExprError();\r
+ break;\r
+ case Builtin::BI_setjmp:\r
+ case Builtin::BI_setjmpex:\r
+ if (checkArgCount(*this, TheCall, 1))\r
+ return true;\r
+ break;\r
+ case Builtin::BI__builtin_classify_type:\r
+ if (checkArgCount(*this, TheCall, 1)) return true;\r
+ TheCall->setType(Context.IntTy);\r
+ break;\r
+ case Builtin::BI__builtin_constant_p:\r
+ if (checkArgCount(*this, TheCall, 1)) return true;\r
+ TheCall->setType(Context.IntTy);\r
+ break;\r
+ case Builtin::BI__sync_fetch_and_add:\r
+ case Builtin::BI__sync_fetch_and_add_1:\r
+ case Builtin::BI__sync_fetch_and_add_2:\r
+ case Builtin::BI__sync_fetch_and_add_4:\r
+ case Builtin::BI__sync_fetch_and_add_8:\r
+ case Builtin::BI__sync_fetch_and_add_16:\r
+ case Builtin::BI__sync_fetch_and_sub:\r
+ case Builtin::BI__sync_fetch_and_sub_1:\r
+ case Builtin::BI__sync_fetch_and_sub_2:\r
+ case Builtin::BI__sync_fetch_and_sub_4:\r
+ case Builtin::BI__sync_fetch_and_sub_8:\r
+ case Builtin::BI__sync_fetch_and_sub_16:\r
+ case Builtin::BI__sync_fetch_and_or:\r
+ case Builtin::BI__sync_fetch_and_or_1:\r
+ case Builtin::BI__sync_fetch_and_or_2:\r
+ case Builtin::BI__sync_fetch_and_or_4:\r
+ case Builtin::BI__sync_fetch_and_or_8:\r
+ case Builtin::BI__sync_fetch_and_or_16:\r
+ case Builtin::BI__sync_fetch_and_and:\r
+ case Builtin::BI__sync_fetch_and_and_1:\r
+ case Builtin::BI__sync_fetch_and_and_2:\r
+ case Builtin::BI__sync_fetch_and_and_4:\r
+ case Builtin::BI__sync_fetch_and_and_8:\r
+ case Builtin::BI__sync_fetch_and_and_16:\r
+ case Builtin::BI__sync_fetch_and_xor:\r
+ case Builtin::BI__sync_fetch_and_xor_1:\r
+ case Builtin::BI__sync_fetch_and_xor_2:\r
+ case Builtin::BI__sync_fetch_and_xor_4:\r
+ case Builtin::BI__sync_fetch_and_xor_8:\r
+ case Builtin::BI__sync_fetch_and_xor_16:\r
+ case Builtin::BI__sync_fetch_and_nand:\r
+ case Builtin::BI__sync_fetch_and_nand_1:\r
+ case Builtin::BI__sync_fetch_and_nand_2:\r
+ case Builtin::BI__sync_fetch_and_nand_4:\r
+ case Builtin::BI__sync_fetch_and_nand_8:\r
+ case Builtin::BI__sync_fetch_and_nand_16:\r
+ case Builtin::BI__sync_add_and_fetch:\r
+ case Builtin::BI__sync_add_and_fetch_1:\r
+ case Builtin::BI__sync_add_and_fetch_2:\r
+ case Builtin::BI__sync_add_and_fetch_4:\r
+ case Builtin::BI__sync_add_and_fetch_8:\r
+ case Builtin::BI__sync_add_and_fetch_16:\r
+ case Builtin::BI__sync_sub_and_fetch:\r
+ case Builtin::BI__sync_sub_and_fetch_1:\r
+ case Builtin::BI__sync_sub_and_fetch_2:\r
+ case Builtin::BI__sync_sub_and_fetch_4:\r
+ case Builtin::BI__sync_sub_and_fetch_8:\r
+ case Builtin::BI__sync_sub_and_fetch_16:\r
+ case Builtin::BI__sync_and_and_fetch:\r
+ case Builtin::BI__sync_and_and_fetch_1:\r
+ case Builtin::BI__sync_and_and_fetch_2:\r
+ case Builtin::BI__sync_and_and_fetch_4:\r
+ case Builtin::BI__sync_and_and_fetch_8:\r
+ case Builtin::BI__sync_and_and_fetch_16:\r
+ case Builtin::BI__sync_or_and_fetch:\r
+ case Builtin::BI__sync_or_and_fetch_1:\r
+ case Builtin::BI__sync_or_and_fetch_2:\r
+ case Builtin::BI__sync_or_and_fetch_4:\r
+ case Builtin::BI__sync_or_and_fetch_8:\r
+ case Builtin::BI__sync_or_and_fetch_16:\r
+ case Builtin::BI__sync_xor_and_fetch:\r
+ case Builtin::BI__sync_xor_and_fetch_1:\r
+ case Builtin::BI__sync_xor_and_fetch_2:\r
+ case Builtin::BI__sync_xor_and_fetch_4:\r
+ case Builtin::BI__sync_xor_and_fetch_8:\r
+ case Builtin::BI__sync_xor_and_fetch_16:\r
+ case Builtin::BI__sync_nand_and_fetch:\r
+ case Builtin::BI__sync_nand_and_fetch_1:\r
+ case Builtin::BI__sync_nand_and_fetch_2:\r
+ case Builtin::BI__sync_nand_and_fetch_4:\r
+ case Builtin::BI__sync_nand_and_fetch_8:\r
+ case Builtin::BI__sync_nand_and_fetch_16:\r
+ case Builtin::BI__sync_val_compare_and_swap:\r
+ case Builtin::BI__sync_val_compare_and_swap_1:\r
+ case Builtin::BI__sync_val_compare_and_swap_2:\r
+ case Builtin::BI__sync_val_compare_and_swap_4:\r
+ case Builtin::BI__sync_val_compare_and_swap_8:\r
+ case Builtin::BI__sync_val_compare_and_swap_16:\r
+ case Builtin::BI__sync_bool_compare_and_swap:\r
+ case Builtin::BI__sync_bool_compare_and_swap_1:\r
+ case Builtin::BI__sync_bool_compare_and_swap_2:\r
+ case Builtin::BI__sync_bool_compare_and_swap_4:\r
+ case Builtin::BI__sync_bool_compare_and_swap_8:\r
+ case Builtin::BI__sync_bool_compare_and_swap_16:\r
+ case Builtin::BI__sync_lock_test_and_set:\r
+ case Builtin::BI__sync_lock_test_and_set_1:\r
+ case Builtin::BI__sync_lock_test_and_set_2:\r
+ case Builtin::BI__sync_lock_test_and_set_4:\r
+ case Builtin::BI__sync_lock_test_and_set_8:\r
+ case Builtin::BI__sync_lock_test_and_set_16:\r
+ case Builtin::BI__sync_lock_release:\r
+ case Builtin::BI__sync_lock_release_1:\r
+ case Builtin::BI__sync_lock_release_2:\r
+ case Builtin::BI__sync_lock_release_4:\r
+ case Builtin::BI__sync_lock_release_8:\r
+ case Builtin::BI__sync_lock_release_16:\r
+ case Builtin::BI__sync_swap:\r
+ case Builtin::BI__sync_swap_1:\r
+ case Builtin::BI__sync_swap_2:\r
+ case Builtin::BI__sync_swap_4:\r
+ case Builtin::BI__sync_swap_8:\r
+ case Builtin::BI__sync_swap_16:\r
+ return SemaBuiltinAtomicOverloaded(TheCallResult);\r
+ case Builtin::BI__builtin_nontemporal_load:\r
+ case Builtin::BI__builtin_nontemporal_store:\r
+ return SemaBuiltinNontemporalOverloaded(TheCallResult);\r
+#define BUILTIN(ID, TYPE, ATTRS)\r
+#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \\r
+ case Builtin::BI##ID: \\r
+ return SemaAtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);\r
+#include "clang/Basic/Builtins.def"\r
+ case Builtin::BI__annotation:\r
+ if (SemaBuiltinMSVCAnnotation(*this, TheCall))\r
+ return ExprError();\r
+ break;\r
+ case Builtin::BI__builtin_annotation:\r
+ if (SemaBuiltinAnnotation(*this, TheCall))\r
+ return ExprError();\r
+ break;\r
+ case Builtin::BI__builtin_addressof:\r
+ if (SemaBuiltinAddressof(*this, TheCall))\r
+ return ExprError();\r
+ break;\r
+ case Builtin::BI__builtin_add_overflow:\r
+ case Builtin::BI__builtin_sub_overflow:\r
+ case Builtin::BI__builtin_mul_overflow:\r
+ if (SemaBuiltinOverflow(*this, TheCall))\r
+ return ExprError();\r
+ break;\r
+ case Builtin::BI__builtin_operator_new:\r
+ case Builtin::BI__builtin_operator_delete: {\r
+ bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;\r
+ ExprResult Res =\r
+ SemaBuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);\r
+ if (Res.isInvalid())\r
+ CorrectDelayedTyposInExpr(TheCallResult.get());\r
+ return Res;\r
+ }\r
+ case Builtin::BI__builtin_dump_struct: {\r
+ // We first want to ensure we are called with 2 arguments\r
+ if (checkArgCount(*this, TheCall, 2))\r
+ return ExprError();\r
+ // Ensure that the first argument is of type 'struct XX *'\r
+ const Expr *PtrArg = TheCall->getArg(0)->IgnoreParenImpCasts();\r
+ const QualType PtrArgType = PtrArg->getType();\r
+ if (!PtrArgType->isPointerType() ||\r
+ !PtrArgType->getPointeeType()->isRecordType()) {\r
+ Diag(PtrArg->getLocStart(), diag::err_typecheck_convert_incompatible)\r
+ << PtrArgType << "structure pointer" << 1 << 0 << 3 << 1 << PtrArgType\r
+ << "structure pointer";\r
+ return ExprError();\r
}
// Ensure that the second argument is of type 'FunctionType'
return false;
}
-/// Check the arguments to '__builtin_va_start' or '__builtin_ms_va_start'
-/// for validity. Emit an error and return true on failure; return false
-/// on success.
-bool Sema::SemaBuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall) {
- Expr *Fn = TheCall->getCallee();
-
- if (checkVAStartABI(*this, BuiltinID, Fn))
- return true;
-
- if (TheCall->getNumArgs() > 2) {
- Diag(TheCall->getArg(2)->getLocStart(),
- diag::err_typecheck_call_too_many_args)
- << 0 /*function call*/ << 2 << TheCall->getNumArgs()
- << Fn->getSourceRange()
- << SourceRange(TheCall->getArg(2)->getLocStart(),
- (*(TheCall->arg_end()-1))->getLocEnd());
- return true;
- }
-
- if (TheCall->getNumArgs() < 2) {
- return Diag(TheCall->getLocEnd(),
- diag::err_typecheck_call_too_few_args_at_least)
- << 0 /*function call*/ << 2 << TheCall->getNumArgs();
- }
-
- // Type-check the first argument normally.
- if (checkBuiltinArgument(*this, TheCall, 0))
- return true;
-
- // Check that the current function is variadic, and get its last parameter.
- ParmVarDecl *LastParam;
- if (checkVAStartIsInVariadicFunction(*this, Fn, &LastParam))
- return true;
-
- // Verify that the second argument to the builtin is the last argument of the
- // current function or method.
- bool SecondArgIsLastNamedArgument = false;
- const Expr *Arg = TheCall->getArg(1)->IgnoreParenCasts();
-
- // These are valid if SecondArgIsLastNamedArgument is false after the next
- // block.
- QualType Type;
- SourceLocation ParamLoc;
- bool IsCRegister = false;
-
- if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
- if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
- SecondArgIsLastNamedArgument = PV == LastParam;
-
- Type = PV->getType();
- ParamLoc = PV->getLocation();
- IsCRegister =
- PV->getStorageClass() == SC_Register && !getLangOpts().CPlusPlus;
- }
- }
-
- if (!SecondArgIsLastNamedArgument)
- Diag(TheCall->getArg(1)->getLocStart(),
- diag::warn_second_arg_of_va_start_not_last_named_param);
- else if (IsCRegister || Type->isReferenceType() ||
- Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
- // Promotable integers are UB, but enumerations need a bit of
- // extra checking to see what their promotable type actually is.
- if (!Type->isPromotableIntegerType())
- return false;
- if (!Type->isEnumeralType())
- return true;
- const EnumDecl *ED = Type->getAs<EnumType>()->getDecl();
- return !(ED &&
- Context.typesAreCompatible(ED->getPromotionType(), Type));
- }()) {
- unsigned Reason = 0;
- if (Type->isReferenceType()) Reason = 1;
- else if (IsCRegister) Reason = 2;
- Diag(Arg->getLocStart(), diag::warn_va_start_type_is_undefined) << Reason;
- Diag(ParamLoc, diag::note_parameter_type) << Type;
- }
-
- TheCall->setType(Context.VoidTy);
- return false;
-}
-
-bool Sema::SemaBuiltinVAStartARMMicrosoft(CallExpr *Call) {
- // void __va_start(va_list *ap, const char *named_addr, size_t slot_size,
- // const char *named_addr);
-
- Expr *Func = Call->getCallee();
-
- if (Call->getNumArgs() < 3)
- return Diag(Call->getLocEnd(),
- diag::err_typecheck_call_too_few_args_at_least)
- << 0 /*function call*/ << 3 << Call->getNumArgs();
-
- // Type-check the first argument normally.
- if (checkBuiltinArgument(*this, Call, 0))
- return true;
-
- // Check that the current function is variadic.
- if (checkVAStartIsInVariadicFunction(*this, Func))
- return true;
-
- // __va_start on Windows does not validate the parameter qualifiers
-
- const Expr *Arg1 = Call->getArg(1)->IgnoreParens();
- const Type *Arg1Ty = Arg1->getType().getCanonicalType().getTypePtr();
-
- const Expr *Arg2 = Call->getArg(2)->IgnoreParens();
- const Type *Arg2Ty = Arg2->getType().getCanonicalType().getTypePtr();
-
- const QualType &ConstCharPtrTy =
- Context.getPointerType(Context.CharTy.withConst());
- if (!Arg1Ty->isPointerType() ||
- Arg1Ty->getPointeeType().withoutLocalFastQualifiers() != Context.CharTy)
- Diag(Arg1->getLocStart(), diag::err_typecheck_convert_incompatible)
- << Arg1->getType() << ConstCharPtrTy
- << 1 /* different class */
- << 0 /* qualifier difference */
- << 3 /* parameter mismatch */
- << 2 << Arg1->getType() << ConstCharPtrTy;
-
- const QualType SizeTy = Context.getSizeType();
- if (Arg2Ty->getCanonicalTypeInternal().withoutLocalFastQualifiers() != SizeTy)
- Diag(Arg2->getLocStart(), diag::err_typecheck_convert_incompatible)
- << Arg2->getType() << SizeTy
- << 1 /* different class */
- << 0 /* qualifier difference */
- << 3 /* parameter mismatch */
- << 3 << Arg2->getType() << SizeTy;
-
- return false;
-}
-
-/// SemaBuiltinUnorderedCompare - Handle functions like __builtin_isgreater and
-/// friends. This is declared to take (...), so we have to check everything.
-bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) {
- if (TheCall->getNumArgs() < 2)
- return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args)
- << 0 << 2 << TheCall->getNumArgs()/*function call*/;
- if (TheCall->getNumArgs() > 2)
- return Diag(TheCall->getArg(2)->getLocStart(),
- diag::err_typecheck_call_too_many_args)
- << 0 /*function call*/ << 2 << TheCall->getNumArgs()
- << SourceRange(TheCall->getArg(2)->getLocStart(),
- (*(TheCall->arg_end()-1))->getLocEnd());
-
- ExprResult OrigArg0 = TheCall->getArg(0);
- ExprResult OrigArg1 = TheCall->getArg(1);
-
- // Do standard promotions between the two arguments, returning their common
- // type.
- QualType Res = UsualArithmeticConversions(OrigArg0, OrigArg1, false);
- if (OrigArg0.isInvalid() || OrigArg1.isInvalid())
- return true;
-
- // Make sure any conversions are pushed back into the call; this is
- // type safe since unordered compare builtins are declared as "_Bool
- // foo(...)".
- TheCall->setArg(0, OrigArg0.get());
- TheCall->setArg(1, OrigArg1.get());
-
- if (OrigArg0.get()->isTypeDependent() || OrigArg1.get()->isTypeDependent())
- return false;
-
- // If the common type isn't a real floating type, then the arguments were
- // invalid for this operation.
- if (Res.isNull() || !Res->isRealFloatingType())
- return Diag(OrigArg0.get()->getLocStart(),
- diag::err_typecheck_call_invalid_ordered_compare)
- << OrigArg0.get()->getType() << OrigArg1.get()->getType()
- << SourceRange(OrigArg0.get()->getLocStart(), OrigArg1.get()->getLocEnd());
-
- return false;
-}
-
-/// SemaBuiltinSemaBuiltinFPClassification - Handle functions like
-/// __builtin_isnan and friends. This is declared to take (...), so we have
-/// to check everything. We expect the last argument to be a floating point
-/// value.
-bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs) {
- if (TheCall->getNumArgs() < NumArgs)
- return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args)
- << 0 << NumArgs << TheCall->getNumArgs()/*function call*/;
- if (TheCall->getNumArgs() > NumArgs)
- return Diag(TheCall->getArg(NumArgs)->getLocStart(),
- diag::err_typecheck_call_too_many_args)
- << 0 /*function call*/ << NumArgs << TheCall->getNumArgs()
- << SourceRange(TheCall->getArg(NumArgs)->getLocStart(),
- (*(TheCall->arg_end()-1))->getLocEnd());
-
- Expr *OrigArg = TheCall->getArg(NumArgs-1);
-
- if (OrigArg->isTypeDependent())
- return false;
-
- // This operation requires a non-_Complex floating-point number.
- if (!OrigArg->getType()->isRealFloatingType())
- return Diag(OrigArg->getLocStart(),
- diag::err_typecheck_call_invalid_unary_fp)
- << OrigArg->getType() << OrigArg->getSourceRange();
-
- // If this is an implicit conversion from float -> float or double, remove it.
- if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(OrigArg)) {
- // Only remove standard FloatCasts, leaving other casts inplace
- if (Cast->getCastKind() == CK_FloatingCast) {
- Expr *CastArg = Cast->getSubExpr();
- if (CastArg->getType()->isSpecificBuiltinType(BuiltinType::Float)) {
- assert((Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) ||
- Cast->getType()->isSpecificBuiltinType(BuiltinType::Float)) &&
- "promotion from float to either float or double is the only expected cast here");
- Cast->setSubExpr(nullptr);
- TheCall->setArg(NumArgs-1, CastArg);
- }
- }
- }
-
- return false;
-}
-
-// Customized Sema Checking for VSX builtins that have the following signature:
-// vector [...] builtinName(vector [...], vector [...], const int);
-// Which takes the same type of vectors (any legal vector type) for the first
-// two arguments and takes compile time constant for the third argument.
-// Example builtins are :
-// vector double vec_xxpermdi(vector double, vector double, int);
-// vector short vec_xxsldwi(vector short, vector short, int);
-bool Sema::SemaBuiltinVSX(CallExpr *TheCall) {
- unsigned ExpectedNumArgs = 3;
- if (TheCall->getNumArgs() < ExpectedNumArgs)
- return Diag(TheCall->getLocEnd(),
- diag::err_typecheck_call_too_few_args_at_least)
- << 0 /*function call*/ << ExpectedNumArgs << TheCall->getNumArgs()
- << TheCall->getSourceRange();
-
- if (TheCall->getNumArgs() > ExpectedNumArgs)
- return Diag(TheCall->getLocEnd(),
- diag::err_typecheck_call_too_many_args_at_most)
- << 0 /*function call*/ << ExpectedNumArgs << TheCall->getNumArgs()
- << TheCall->getSourceRange();
-
- // Check the third argument is a compile time constant
- llvm::APSInt Value;
- if(!TheCall->getArg(2)->isIntegerConstantExpr(Value, Context))
- return Diag(TheCall->getLocStart(),
- diag::err_vsx_builtin_nonconstant_argument)
- << 3 /* argument index */ << TheCall->getDirectCallee()
- << SourceRange(TheCall->getArg(2)->getLocStart(),
- TheCall->getArg(2)->getLocEnd());
-
- QualType Arg1Ty = TheCall->getArg(0)->getType();
- QualType Arg2Ty = TheCall->getArg(1)->getType();
-
- // Check the type of argument 1 and argument 2 are vectors.
- SourceLocation BuiltinLoc = TheCall->getLocStart();
- if ((!Arg1Ty->isVectorType() && !Arg1Ty->isDependentType()) ||
- (!Arg2Ty->isVectorType() && !Arg2Ty->isDependentType())) {
- return Diag(BuiltinLoc, diag::err_vec_builtin_non_vector)
- << TheCall->getDirectCallee()
- << SourceRange(TheCall->getArg(0)->getLocStart(),
- TheCall->getArg(1)->getLocEnd());
- }
-
- // Check the first two arguments are the same type.
- if (!Context.hasSameUnqualifiedType(Arg1Ty, Arg2Ty)) {
- return Diag(BuiltinLoc, diag::err_vec_builtin_incompatible_vector)
- << TheCall->getDirectCallee()
- << SourceRange(TheCall->getArg(0)->getLocStart(),
- TheCall->getArg(1)->getLocEnd());
- }
-
- // When default clang type checking is turned off and the customized type
- // checking is used, the returning type of the function must be explicitly
- // set. Otherwise it is _Bool by default.
- TheCall->setType(Arg1Ty);
-
- return false;
-}
-
-/// SemaBuiltinShuffleVector - Handle __builtin_shufflevector.
-// This is declared to take (...), so we have to check everything.
-ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {
- if (TheCall->getNumArgs() < 2)
- return ExprError(Diag(TheCall->getLocEnd(),
- diag::err_typecheck_call_too_few_args_at_least)
- << 0 /*function call*/ << 2 << TheCall->getNumArgs()
- << TheCall->getSourceRange());
-
- // Determine which of the following types of shufflevector we're checking:
- // 1) unary, vector mask: (lhs, mask)
- // 2) binary, scalar mask: (lhs, rhs, index, ..., index)
- QualType resType = TheCall->getArg(0)->getType();
- unsigned numElements = 0;
-
- if (!TheCall->getArg(0)->isTypeDependent() &&
- !TheCall->getArg(1)->isTypeDependent()) {
- QualType LHSType = TheCall->getArg(0)->getType();
- QualType RHSType = TheCall->getArg(1)->getType();
-
- if (!LHSType->isVectorType() || !RHSType->isVectorType())
- return ExprError(Diag(TheCall->getLocStart(),
- diag::err_vec_builtin_non_vector)
- << TheCall->getDirectCallee()
- << SourceRange(TheCall->getArg(0)->getLocStart(),
- TheCall->getArg(1)->getLocEnd()));
-
- numElements = LHSType->getAs<VectorType>()->getNumElements();
- unsigned numResElements = TheCall->getNumArgs() - 2;
-
- // Check to see if we have a call with 2 vector arguments, the unary shuffle
- // with mask. If so, verify that RHS is an integer vector type with the
- // same number of elts as lhs.
- if (TheCall->getNumArgs() == 2) {
- if (!RHSType->hasIntegerRepresentation() ||
- RHSType->getAs<VectorType>()->getNumElements() != numElements)
- return ExprError(Diag(TheCall->getLocStart(),
- diag::err_vec_builtin_incompatible_vector)
- << TheCall->getDirectCallee()
- << SourceRange(TheCall->getArg(1)->getLocStart(),
- TheCall->getArg(1)->getLocEnd()));
- } else if (!Context.hasSameUnqualifiedType(LHSType, RHSType)) {
- return ExprError(Diag(TheCall->getLocStart(),
- diag::err_vec_builtin_incompatible_vector)
- << TheCall->getDirectCallee()
- << SourceRange(TheCall->getArg(0)->getLocStart(),
- TheCall->getArg(1)->getLocEnd()));
- } else if (numElements != numResElements) {
- QualType eltType = LHSType->getAs<VectorType>()->getElementType();
- resType = Context.getVectorType(eltType, numResElements,
- VectorType::GenericVector);
- }
- }
-
- for (unsigned i = 2; i < TheCall->getNumArgs(); i++) {
- if (TheCall->getArg(i)->isTypeDependent() ||
- TheCall->getArg(i)->isValueDependent())
- continue;
-
- llvm::APSInt Result(32);
- if (!TheCall->getArg(i)->isIntegerConstantExpr(Result, Context))
- return ExprError(Diag(TheCall->getLocStart(),
- diag::err_shufflevector_nonconstant_argument)
- << TheCall->getArg(i)->getSourceRange());
-
- // Allow -1 which will be translated to undef in the IR.
- if (Result.isSigned() && Result.isAllOnesValue())
- continue;
-
- if (Result.getActiveBits() > 64 || Result.getZExtValue() >= numElements*2)
- return ExprError(Diag(TheCall->getLocStart(),
- diag::err_shufflevector_argument_too_large)
- << TheCall->getArg(i)->getSourceRange());
- }
-
- SmallVector<Expr*, 32> exprs;
-
- for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; i++) {
- exprs.push_back(TheCall->getArg(i));
- TheCall->setArg(i, nullptr);
- }
-
- return new (Context) ShuffleVectorExpr(Context, exprs, resType,
- TheCall->getCallee()->getLocStart(),
- TheCall->getRParenLoc());
-}
-
-/// SemaConvertVectorExpr - Handle __builtin_convertvector
-ExprResult Sema::SemaConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo,
- SourceLocation BuiltinLoc,
- SourceLocation RParenLoc) {
- ExprValueKind VK = VK_RValue;
- ExprObjectKind OK = OK_Ordinary;
- QualType DstTy = TInfo->getType();
- QualType SrcTy = E->getType();
-
- if (!SrcTy->isVectorType() && !SrcTy->isDependentType())
- return ExprError(Diag(BuiltinLoc,
- diag::err_convertvector_non_vector)
- << E->getSourceRange());
- if (!DstTy->isVectorType() && !DstTy->isDependentType())
- return ExprError(Diag(BuiltinLoc,
- diag::err_convertvector_non_vector_type));
-
- if (!SrcTy->isDependentType() && !DstTy->isDependentType()) {
- unsigned SrcElts = SrcTy->getAs<VectorType>()->getNumElements();
- unsigned DstElts = DstTy->getAs<VectorType>()->getNumElements();
- if (SrcElts != DstElts)
- return ExprError(Diag(BuiltinLoc,
- diag::err_convertvector_incompatible_vector)
- << E->getSourceRange());
- }
-
- return new (Context)
- ConvertVectorExpr(E, TInfo, DstTy, VK, OK, BuiltinLoc, RParenLoc);
-}
-
-/// SemaBuiltinPrefetch - Handle __builtin_prefetch.
-// This is declared to take (const void*, ...) and can take two
-// optional constant int args.
-bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) {
- unsigned NumArgs = TheCall->getNumArgs();
-
- if (NumArgs > 3)
- return Diag(TheCall->getLocEnd(),
- diag::err_typecheck_call_too_many_args_at_most)
- << 0 /*function call*/ << 3 << NumArgs
- << TheCall->getSourceRange();
-
- // Argument 0 is checked for us and the remaining arguments must be
- // constant integers.
- for (unsigned i = 1; i != NumArgs; ++i)
+/// Check the arguments to '__builtin_va_start' or '__builtin_ms_va_start'\r
+/// for validity. Emit an error and return true on failure; return false\r
+/// on success.\r
+bool Sema::SemaBuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall) {\r
+ Expr *Fn = TheCall->getCallee();\r
+\r
+ if (checkVAStartABI(*this, BuiltinID, Fn))\r
+ return true;\r
+\r
+ if (TheCall->getNumArgs() > 2) {\r
+ Diag(TheCall->getArg(2)->getLocStart(),\r
+ diag::err_typecheck_call_too_many_args)\r
+ << 0 /*function call*/ << 2 << TheCall->getNumArgs()\r
+ << Fn->getSourceRange()\r
+ << SourceRange(TheCall->getArg(2)->getLocStart(),\r
+ (*(TheCall->arg_end()-1))->getLocEnd());\r
+ return true;\r
+ }\r
+\r
+ if (TheCall->getNumArgs() < 2) {\r
+ return Diag(TheCall->getLocEnd(),\r
+ diag::err_typecheck_call_too_few_args_at_least)\r
+ << 0 /*function call*/ << 2 << TheCall->getNumArgs();\r
+ }\r
+\r
+ // Type-check the first argument normally.\r
+ if (checkBuiltinArgument(*this, TheCall, 0))\r
+ return true;\r
+\r
+ // Check that the current function is variadic, and get its last parameter.\r
+ ParmVarDecl *LastParam;\r
+ if (checkVAStartIsInVariadicFunction(*this, Fn, &LastParam))\r
+ return true;\r
+\r
+ // Verify that the second argument to the builtin is the last argument of the\r
+ // current function or method.\r
+ bool SecondArgIsLastNamedArgument = false;\r
+ const Expr *Arg = TheCall->getArg(1)->IgnoreParenCasts();\r
+\r
+ // These are valid if SecondArgIsLastNamedArgument is false after the next\r
+ // block.\r
+ QualType Type;\r
+ SourceLocation ParamLoc;\r
+ bool IsCRegister = false;\r
+\r
+ if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {\r
+ if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {\r
+ SecondArgIsLastNamedArgument = PV == LastParam;\r
+\r
+ Type = PV->getType();\r
+ ParamLoc = PV->getLocation();\r
+ IsCRegister =\r
+ PV->getStorageClass() == SC_Register && !getLangOpts().CPlusPlus;\r
+ }\r
+ }\r
+\r
+ if (!SecondArgIsLastNamedArgument)\r
+ Diag(TheCall->getArg(1)->getLocStart(),\r
+ diag::warn_second_arg_of_va_start_not_last_named_param);\r
+ else if (IsCRegister || Type->isReferenceType() ||\r
+ Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {\r
+ // Promotable integers are UB, but enumerations need a bit of\r
+ // extra checking to see what their promotable type actually is.\r
+ if (!Type->isPromotableIntegerType())\r
+ return false;\r
+ if (!Type->isEnumeralType())\r
+ return true;\r
+ const EnumDecl *ED = Type->getAs<EnumType>()->getDecl();\r
+ return !(ED &&\r
+ Context.typesAreCompatible(ED->getPromotionType(), Type));\r
+ }()) {\r
+ unsigned Reason = 0;\r
+ if (Type->isReferenceType()) Reason = 1;\r
+ else if (IsCRegister) Reason = 2;\r
+ Diag(Arg->getLocStart(), diag::warn_va_start_type_is_undefined) << Reason;\r
+ Diag(ParamLoc, diag::note_parameter_type) << Type;\r
+ }\r
+\r
+ TheCall->setType(Context.VoidTy);\r
+ return false;\r
+}\r
+\r
+bool Sema::SemaBuiltinVAStartARMMicrosoft(CallExpr *Call) {\r
+ // void __va_start(va_list *ap, const char *named_addr, size_t slot_size,\r
+ // const char *named_addr);\r
+\r
+ Expr *Func = Call->getCallee();\r
+\r
+ if (Call->getNumArgs() < 3)\r
+ return Diag(Call->getLocEnd(),\r
+ diag::err_typecheck_call_too_few_args_at_least)\r
+ << 0 /*function call*/ << 3 << Call->getNumArgs();\r
+\r
+ // Type-check the first argument normally.\r
+ if (checkBuiltinArgument(*this, Call, 0))\r
+ return true;\r
+\r
+ // Check that the current function is variadic.\r
+ if (checkVAStartIsInVariadicFunction(*this, Func))\r
+ return true;\r
+\r
+ // __va_start on Windows does not validate the parameter qualifiers\r
+\r
+ const Expr *Arg1 = Call->getArg(1)->IgnoreParens();\r
+ const Type *Arg1Ty = Arg1->getType().getCanonicalType().getTypePtr();\r
+\r
+ const Expr *Arg2 = Call->getArg(2)->IgnoreParens();\r
+ const Type *Arg2Ty = Arg2->getType().getCanonicalType().getTypePtr();\r
+\r
+ const QualType &ConstCharPtrTy =\r
+ Context.getPointerType(Context.CharTy.withConst());\r
+ if (!Arg1Ty->isPointerType() ||\r
+ Arg1Ty->getPointeeType().withoutLocalFastQualifiers() != Context.CharTy)\r
+ Diag(Arg1->getLocStart(), diag::err_typecheck_convert_incompatible)\r
+ << Arg1->getType() << ConstCharPtrTy\r
+ << 1 /* different class */\r
+ << 0 /* qualifier difference */\r
+ << 3 /* parameter mismatch */\r
+ << 2 << Arg1->getType() << ConstCharPtrTy;\r
+\r
+ const QualType SizeTy = Context.getSizeType();\r
+ if (Arg2Ty->getCanonicalTypeInternal().withoutLocalFastQualifiers() != SizeTy)\r
+ Diag(Arg2->getLocStart(), diag::err_typecheck_convert_incompatible)\r
+ << Arg2->getType() << SizeTy\r
+ << 1 /* different class */\r
+ << 0 /* qualifier difference */\r
+ << 3 /* parameter mismatch */\r
+ << 3 << Arg2->getType() << SizeTy;\r
+\r
+ return false;\r
+}\r
+\r
+/// SemaBuiltinUnorderedCompare - Handle functions like __builtin_isgreater and\r
+/// friends. This is declared to take (...), so we have to check everything.\r
+bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) {\r
+ if (TheCall->getNumArgs() < 2)\r
+ return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args)\r
+ << 0 << 2 << TheCall->getNumArgs()/*function call*/;\r
+ if (TheCall->getNumArgs() > 2)\r
+ return Diag(TheCall->getArg(2)->getLocStart(),\r
+ diag::err_typecheck_call_too_many_args)\r
+ << 0 /*function call*/ << 2 << TheCall->getNumArgs()\r
+ << SourceRange(TheCall->getArg(2)->getLocStart(),\r
+ (*(TheCall->arg_end()-1))->getLocEnd());\r
+\r
+ ExprResult OrigArg0 = TheCall->getArg(0);\r
+ ExprResult OrigArg1 = TheCall->getArg(1);\r
+\r
+ // Do standard promotions between the two arguments, returning their common\r
+ // type.\r
+ QualType Res = UsualArithmeticConversions(OrigArg0, OrigArg1, false);\r
+ if (OrigArg0.isInvalid() || OrigArg1.isInvalid())\r
+ return true;\r
+\r
+ // Make sure any conversions are pushed back into the call; this is\r
+ // type safe since unordered compare builtins are declared as "_Bool\r
+ // foo(...)".\r
+ TheCall->setArg(0, OrigArg0.get());\r
+ TheCall->setArg(1, OrigArg1.get());\r
+\r
+ if (OrigArg0.get()->isTypeDependent() || OrigArg1.get()->isTypeDependent())\r
+ return false;\r
+\r
+ // If the common type isn't a real floating type, then the arguments were\r
+ // invalid for this operation.\r
+ if (Res.isNull() || !Res->isRealFloatingType())\r
+ return Diag(OrigArg0.get()->getLocStart(),\r
+ diag::err_typecheck_call_invalid_ordered_compare)\r
+ << OrigArg0.get()->getType() << OrigArg1.get()->getType()\r
+ << SourceRange(OrigArg0.get()->getLocStart(), OrigArg1.get()->getLocEnd());\r
+\r
+ return false;\r
+}\r
+\r
+/// SemaBuiltinSemaBuiltinFPClassification - Handle functions like\r
+/// __builtin_isnan and friends. This is declared to take (...), so we have\r
+/// to check everything. We expect the last argument to be a floating point\r
+/// value.\r
+bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs) {\r
+ if (TheCall->getNumArgs() < NumArgs)\r
+ return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args)\r
+ << 0 << NumArgs << TheCall->getNumArgs()/*function call*/;\r
+ if (TheCall->getNumArgs() > NumArgs)\r
+ return Diag(TheCall->getArg(NumArgs)->getLocStart(),\r
+ diag::err_typecheck_call_too_many_args)\r
+ << 0 /*function call*/ << NumArgs << TheCall->getNumArgs()\r
+ << SourceRange(TheCall->getArg(NumArgs)->getLocStart(),\r
+ (*(TheCall->arg_end()-1))->getLocEnd());\r
+\r
+ Expr *OrigArg = TheCall->getArg(NumArgs-1);\r
+\r
+ if (OrigArg->isTypeDependent())\r
+ return false;\r
+\r
+ // This operation requires a non-_Complex floating-point number.\r
+ if (!OrigArg->getType()->isRealFloatingType())\r
+ return Diag(OrigArg->getLocStart(),\r
+ diag::err_typecheck_call_invalid_unary_fp)\r
+ << OrigArg->getType() << OrigArg->getSourceRange();\r
+\r
+ // If this is an implicit conversion from float -> float, double, or\r
+ // long double, remove it.\r
+ if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(OrigArg)) {\r
+ // Only remove standard FloatCasts, leaving other casts inplace\r
+ if (Cast->getCastKind() == CK_FloatingCast) {\r
+ Expr *CastArg = Cast->getSubExpr();\r
+ if (CastArg->getType()->isSpecificBuiltinType(BuiltinType::Float)) {\r
+ assert(\r
+ (Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) ||\r
+ Cast->getType()->isSpecificBuiltinType(BuiltinType::Float) ||\r
+ Cast->getType()->isSpecificBuiltinType(BuiltinType::LongDouble)) &&\r
+ "promotion from float to either float, double, or long double is "\r
+ "the only expected cast here");\r
+ Cast->setSubExpr(nullptr);\r
+ TheCall->setArg(NumArgs-1, CastArg);\r
+ }\r
+ }\r
+ }\r
+ \r
+ return false;\r
+}\r
+\r
+// Customized Sema Checking for VSX builtins that have the following signature:\r
+// vector [...] builtinName(vector [...], vector [...], const int);\r
+// Which takes the same type of vectors (any legal vector type) for the first\r
+// two arguments and takes compile time constant for the third argument.\r
+// Example builtins are :\r
+// vector double vec_xxpermdi(vector double, vector double, int);\r
+// vector short vec_xxsldwi(vector short, vector short, int);\r
+bool Sema::SemaBuiltinVSX(CallExpr *TheCall) {\r
+ unsigned ExpectedNumArgs = 3;\r
+ if (TheCall->getNumArgs() < ExpectedNumArgs)\r
+ return Diag(TheCall->getLocEnd(),\r
+ diag::err_typecheck_call_too_few_args_at_least)\r
+ << 0 /*function call*/ << ExpectedNumArgs << TheCall->getNumArgs()\r
+ << TheCall->getSourceRange();\r
+\r
+ if (TheCall->getNumArgs() > ExpectedNumArgs)\r
+ return Diag(TheCall->getLocEnd(),\r
+ diag::err_typecheck_call_too_many_args_at_most)\r
+ << 0 /*function call*/ << ExpectedNumArgs << TheCall->getNumArgs()\r
+ << TheCall->getSourceRange();\r
+\r
+ // Check the third argument is a compile time constant\r
+ llvm::APSInt Value;\r
+ if(!TheCall->getArg(2)->isIntegerConstantExpr(Value, Context))\r
+ return Diag(TheCall->getLocStart(),\r
+ diag::err_vsx_builtin_nonconstant_argument)\r
+ << 3 /* argument index */ << TheCall->getDirectCallee()\r
+ << SourceRange(TheCall->getArg(2)->getLocStart(),\r
+ TheCall->getArg(2)->getLocEnd());\r
+\r
+ QualType Arg1Ty = TheCall->getArg(0)->getType();\r
+ QualType Arg2Ty = TheCall->getArg(1)->getType();\r
+\r
+ // Check the type of argument 1 and argument 2 are vectors.\r
+ SourceLocation BuiltinLoc = TheCall->getLocStart();\r
+ if ((!Arg1Ty->isVectorType() && !Arg1Ty->isDependentType()) ||\r
+ (!Arg2Ty->isVectorType() && !Arg2Ty->isDependentType())) {\r
+ return Diag(BuiltinLoc, diag::err_vec_builtin_non_vector)\r
+ << TheCall->getDirectCallee()\r
+ << SourceRange(TheCall->getArg(0)->getLocStart(),\r
+ TheCall->getArg(1)->getLocEnd());\r
+ }\r
+\r
+ // Check the first two arguments are the same type.\r
+ if (!Context.hasSameUnqualifiedType(Arg1Ty, Arg2Ty)) {\r
+ return Diag(BuiltinLoc, diag::err_vec_builtin_incompatible_vector)\r
+ << TheCall->getDirectCallee()\r
+ << SourceRange(TheCall->getArg(0)->getLocStart(),\r
+ TheCall->getArg(1)->getLocEnd());\r
+ }\r
+\r
+ // When default clang type checking is turned off and the customized type\r
+ // checking is used, the returning type of the function must be explicitly\r
+ // set. Otherwise it is _Bool by default.\r
+ TheCall->setType(Arg1Ty);\r
+\r
+ return false;\r
+}\r
+\r
+/// SemaBuiltinShuffleVector - Handle __builtin_shufflevector.\r
+// This is declared to take (...), so we have to check everything.\r
+ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {\r
+ if (TheCall->getNumArgs() < 2)\r
+ return ExprError(Diag(TheCall->getLocEnd(),\r
+ diag::err_typecheck_call_too_few_args_at_least)\r
+ << 0 /*function call*/ << 2 << TheCall->getNumArgs()\r
+ << TheCall->getSourceRange());\r
+\r
+ // Determine which of the following types of shufflevector we're checking:\r
+ // 1) unary, vector mask: (lhs, mask)\r
+ // 2) binary, scalar mask: (lhs, rhs, index, ..., index)\r
+ QualType resType = TheCall->getArg(0)->getType();\r
+ unsigned numElements = 0;\r
+\r
+ if (!TheCall->getArg(0)->isTypeDependent() &&\r
+ !TheCall->getArg(1)->isTypeDependent()) {\r
+ QualType LHSType = TheCall->getArg(0)->getType();\r
+ QualType RHSType = TheCall->getArg(1)->getType();\r
+\r
+ if (!LHSType->isVectorType() || !RHSType->isVectorType())\r
+ return ExprError(Diag(TheCall->getLocStart(),\r
+ diag::err_vec_builtin_non_vector)\r
+ << TheCall->getDirectCallee()\r
+ << SourceRange(TheCall->getArg(0)->getLocStart(),\r
+ TheCall->getArg(1)->getLocEnd()));\r
+\r
+ numElements = LHSType->getAs<VectorType>()->getNumElements();\r
+ unsigned numResElements = TheCall->getNumArgs() - 2;\r
+\r
+ // Check to see if we have a call with 2 vector arguments, the unary shuffle\r
+ // with mask. If so, verify that RHS is an integer vector type with the\r
+ // same number of elts as lhs.\r
+ if (TheCall->getNumArgs() == 2) {\r
+ if (!RHSType->hasIntegerRepresentation() ||\r
+ RHSType->getAs<VectorType>()->getNumElements() != numElements)\r
+ return ExprError(Diag(TheCall->getLocStart(),\r
+ diag::err_vec_builtin_incompatible_vector)\r
+ << TheCall->getDirectCallee()\r
+ << SourceRange(TheCall->getArg(1)->getLocStart(),\r
+ TheCall->getArg(1)->getLocEnd()));\r
+ } else if (!Context.hasSameUnqualifiedType(LHSType, RHSType)) {\r
+ return ExprError(Diag(TheCall->getLocStart(),\r
+ diag::err_vec_builtin_incompatible_vector)\r
+ << TheCall->getDirectCallee()\r
+ << SourceRange(TheCall->getArg(0)->getLocStart(),\r
+ TheCall->getArg(1)->getLocEnd()));\r
+ } else if (numElements != numResElements) {\r
+ QualType eltType = LHSType->getAs<VectorType>()->getElementType();\r
+ resType = Context.getVectorType(eltType, numResElements,\r
+ VectorType::GenericVector);\r
+ }\r
+ }\r
+\r
+ for (unsigned i = 2; i < TheCall->getNumArgs(); i++) {\r
+ if (TheCall->getArg(i)->isTypeDependent() ||\r
+ TheCall->getArg(i)->isValueDependent())\r
+ continue;\r
+\r
+ llvm::APSInt Result(32);\r
+ if (!TheCall->getArg(i)->isIntegerConstantExpr(Result, Context))\r
+ return ExprError(Diag(TheCall->getLocStart(),\r
+ diag::err_shufflevector_nonconstant_argument)\r
+ << TheCall->getArg(i)->getSourceRange());\r
+\r
+ // Allow -1 which will be translated to undef in the IR.\r
+ if (Result.isSigned() && Result.isAllOnesValue())\r
+ continue;\r
+\r
+ if (Result.getActiveBits() > 64 || Result.getZExtValue() >= numElements*2)\r
+ return ExprError(Diag(TheCall->getLocStart(),\r
+ diag::err_shufflevector_argument_too_large)\r
+ << TheCall->getArg(i)->getSourceRange());\r
+ }\r
+\r
+ SmallVector<Expr*, 32> exprs;\r
+\r
+ for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; i++) {\r
+ exprs.push_back(TheCall->getArg(i));\r
+ TheCall->setArg(i, nullptr);\r
+ }\r
+\r
+ return new (Context) ShuffleVectorExpr(Context, exprs, resType,\r
+ TheCall->getCallee()->getLocStart(),\r
+ TheCall->getRParenLoc());\r
+}\r
+\r
+/// SemaConvertVectorExpr - Handle __builtin_convertvector\r
+ExprResult Sema::SemaConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo,\r
+ SourceLocation BuiltinLoc,\r
+ SourceLocation RParenLoc) {\r
+ ExprValueKind VK = VK_RValue;\r
+ ExprObjectKind OK = OK_Ordinary;\r
+ QualType DstTy = TInfo->getType();\r
+ QualType SrcTy = E->getType();\r
+\r
+ if (!SrcTy->isVectorType() && !SrcTy->isDependentType())\r
+ return ExprError(Diag(BuiltinLoc,\r
+ diag::err_convertvector_non_vector)\r
+ << E->getSourceRange());\r
+ if (!DstTy->isVectorType() && !DstTy->isDependentType())\r
+ return ExprError(Diag(BuiltinLoc,\r
+ diag::err_convertvector_non_vector_type));\r
+\r
+ if (!SrcTy->isDependentType() && !DstTy->isDependentType()) {\r
+ unsigned SrcElts = SrcTy->getAs<VectorType>()->getNumElements();\r
+ unsigned DstElts = DstTy->getAs<VectorType>()->getNumElements();\r
+ if (SrcElts != DstElts)\r
+ return ExprError(Diag(BuiltinLoc,\r
+ diag::err_convertvector_incompatible_vector)\r
+ << E->getSourceRange());\r
+ }\r
+\r
+ return new (Context)\r
+ ConvertVectorExpr(E, TInfo, DstTy, VK, OK, BuiltinLoc, RParenLoc);\r
+}\r
+\r
+/// SemaBuiltinPrefetch - Handle __builtin_prefetch.\r
+// This is declared to take (const void*, ...) and can take two\r
+// optional constant int args.\r
+bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) {\r
+ unsigned NumArgs = TheCall->getNumArgs();\r
+\r
+ if (NumArgs > 3)\r
+ return Diag(TheCall->getLocEnd(),\r
+ diag::err_typecheck_call_too_many_args_at_most)\r
+ << 0 /*function call*/ << 3 << NumArgs\r
+ << TheCall->getSourceRange();\r
+\r
+ // Argument 0 is checked for us and the remaining arguments must be\r
+ // constant integers.\r
+ for (unsigned i = 1; i != NumArgs; ++i)\r
if (SemaBuiltinConstantArgRange(TheCall, i, 0, i == 1 ? 1 : 3))
return true;
// overloaded atomics should be declared only once.
void test9_1(volatile int* ptr, int val) {
- __sync_fetch_and_add_4(ptr, val);
-}
-void test9_2(volatile int* ptr, int val) {
- __sync_fetch_and_add(ptr, val);
-}
-void test9_3(volatile int* ptr, int val) {
- __sync_fetch_and_add_4(ptr, val);
- __sync_fetch_and_add(ptr, val);
- __sync_fetch_and_add(ptr, val);
- __sync_fetch_and_add_4(ptr, val);
- __sync_fetch_and_add_4(ptr, val);
-}
-
-void test9_4(volatile int* ptr, int val) {
- // expected-warning@+1 {{the semantics of this intrinsic changed with GCC version 4.4 - the newer semantics are provided here}}
- __sync_fetch_and_nand(ptr, val);
-}
-
-// rdar://7236819
-void test10(void) __attribute__((noreturn));
-
-void test10(void) {
- __asm__("int3");
- __builtin_unreachable();
-
- // No warning about falling off the end of a noreturn function.
-}
-
-void test11(int X) {
- switch (X) {
- case __builtin_eh_return_data_regno(0): // constant foldable.
- break;
- }
-
- __builtin_eh_return_data_regno(X); // expected-error {{argument to '__builtin_eh_return_data_regno' must be a constant integer}}
-}
-
-// PR5062
-void test12(void) __attribute__((__noreturn__));
-void test12(void) {
- __builtin_trap(); // no warning because trap is noreturn.
-}
-
-void test_unknown_builtin(int a, int b) {
- __builtin_isles(a, b); // expected-error{{use of unknown builtin}} \
- // expected-note{{did you mean '__builtin_isless'?}}
-}
-
-int test13() {
- __builtin_eh_return(0, 0); // no warning, eh_return never returns.
-}
-
-// <rdar://problem/8228293>
-void test14() {
- int old;
- old = __sync_fetch_and_min((volatile int *)&old, 1);
-}
-
-// <rdar://problem/8336581>
-void test15(const char *s) {
- __builtin_printf("string is %s\n", s);
-}
-
-// PR7885
-int test16() {
- return __builtin_constant_p() + // expected-error{{too few arguments}}
- __builtin_constant_p(1, 2); // expected-error {{too many arguments}}
-}
-
-const int test17_n = 0;
-const char test17_c[] = {1, 2, 3, 0};
-const char test17_d[] = {1, 2, 3, 4};
-typedef int __attribute__((vector_size(16))) IntVector;
-struct Aggregate { int n; char c; };
-enum Enum { EnumValue1, EnumValue2 };
-
-typedef __typeof(sizeof(int)) size_t;
-size_t strlen(const char *);
-
-void test17() {
-#define ASSERT(...) { int arr[(__VA_ARGS__) ? 1 : -1]; }
-#define T(...) ASSERT(__builtin_constant_p(__VA_ARGS__))
-#define F(...) ASSERT(!__builtin_constant_p(__VA_ARGS__))
-
- // __builtin_constant_p returns 1 if the argument folds to:
- // - an arithmetic constant with value which is known at compile time
- T(test17_n);
- T(&test17_c[3] - test17_c);
- T(3i + 5); // expected-warning {{imaginary constant}}
- T(4.2 * 7.6);
- T(EnumValue1);
- T((enum Enum)(int)EnumValue2);
-
- // - the address of the first character of a string literal, losslessly cast
- // to any type
- T("string literal");
- T((double*)"string literal");
- T("string literal" + 0);
- T((long)"string literal");
-
- // ... and otherwise returns 0.
- F("string literal" + 1);
- F(&test17_n);
- F(test17_c);
- F(&test17_c);
- F(&test17_d);
- F((struct Aggregate){0, 1});
- F((IntVector){0, 1, 2, 3});
-
- // Ensure that a technique used in glibc is handled correctly.
-#define OPT(...) (__builtin_constant_p(__VA_ARGS__) && strlen(__VA_ARGS__) < 4)
- // FIXME: These are incorrectly treated as ICEs because strlen is treated as
- // a builtin.
- ASSERT(OPT("abc"));
- ASSERT(!OPT("abcd"));
- // In these cases, the strlen is non-constant, but the __builtin_constant_p
- // is 0: the array size is not an ICE but is foldable.
- ASSERT(!OPT(test17_c)); // expected-warning {{folded}}
- ASSERT(!OPT(&test17_c[0])); // expected-warning {{folded}}
- ASSERT(!OPT((char*)test17_c)); // expected-warning {{folded}}
- ASSERT(!OPT(test17_d)); // expected-warning {{folded}}
- ASSERT(!OPT(&test17_d[0])); // expected-warning {{folded}}
- ASSERT(!OPT((char*)test17_d)); // expected-warning {{folded}}
-
-#undef OPT
-#undef T
-#undef F
-}
-
-void test18() {
- char src[1024];
- char dst[2048];
- size_t result;
- void *ptr;
-
- ptr = __builtin___memccpy_chk(dst, src, '\037', sizeof(src), sizeof(dst));
- result = __builtin___strlcpy_chk(dst, src, sizeof(dst), sizeof(dst));
- result = __builtin___strlcat_chk(dst, src, sizeof(dst), sizeof(dst));
-
- ptr = __builtin___memccpy_chk(dst, src, '\037', sizeof(src)); // expected-error {{too few arguments to function call}}
- ptr = __builtin___strlcpy_chk(dst, src, sizeof(dst), sizeof(dst)); // expected-warning {{incompatible integer to pointer conversion}}
- ptr = __builtin___strlcat_chk(dst, src, sizeof(dst), sizeof(dst)); // expected-warning {{incompatible integer to pointer conversion}}
-}
-
-void no_ms_builtins() {
- __assume(1); // expected-warning {{implicit declaration}}
- __noop(1); // expected-warning {{implicit declaration}}
- __debugbreak(); // expected-warning {{implicit declaration}}
-}
-
-void unavailable() {
- __builtin_operator_new(0); // expected-error {{'__builtin_operator_new' is only available in C++}}
- __builtin_operator_delete(0); // expected-error {{'__builtin_operator_delete' is only available in C++}}
-}
-
-// rdar://18259539
-size_t strlcpy(char * restrict dst, const char * restrict src, size_t size);
-size_t strlcat(char * restrict dst, const char * restrict src, size_t size);
-
-void Test19(void)
-{
- static char b[40];
- static char buf[20];
-
- strlcpy(buf, b, sizeof(b)); // expected-warning {{size argument in 'strlcpy' call appears to be size of the source; expected the size of the destination}} \\
- // expected-note {{change size argument to be the size of the destination}}
- __builtin___strlcpy_chk(buf, b, sizeof(b), __builtin_object_size(buf, 0)); // expected-warning {{size argument in '__builtin___strlcpy_chk' call appears to be size of the source; expected the size of the destination}} \
- // expected-note {{change size argument to be the size of the destination}} \
- // expected-warning {{'__builtin___strlcpy_chk' will always overflow destination buffer}}
-
- strlcat(buf, b, sizeof(b)); // expected-warning {{size argument in 'strlcat' call appears to be size of the source; expected the size of the destination}} \
- // expected-note {{change size argument to be the size of the destination}}
-
- __builtin___strlcat_chk(buf, b, sizeof(b), __builtin_object_size(buf, 0)); // expected-warning {{size argument in '__builtin___strlcat_chk' call appears to be size of the source; expected the size of the destination}} \
- // expected-note {{change size argument to be the size of the destination}} \
- // expected-warning {{'__builtin___strlcat_chk' will always overflow destination buffer}}
-}
-
-// rdar://11076881
-char * Test20(char *p, const char *in, unsigned n)
-{
- static char buf[10];
-
- __builtin___memcpy_chk (&buf[6], in, 5, __builtin_object_size (&buf[6], 0)); // expected-warning {{'__builtin___memcpy_chk' will always overflow destination buffer}}
-
- __builtin___memcpy_chk (p, "abcde", n, __builtin_object_size (p, 0));
-
- __builtin___memcpy_chk (&buf[5], "abcde", 5, __builtin_object_size (&buf[5], 0));
-
- __builtin___memcpy_chk (&buf[5], "abcde", n, __builtin_object_size (&buf[5], 0));
-
- __builtin___memcpy_chk (&buf[6], "abcde", 5, __builtin_object_size (&buf[6], 0)); // expected-warning {{'__builtin___memcpy_chk' will always overflow destination buffer}}
-
- return buf;
-}
-
-void test21(const int *ptr) {
- __sync_fetch_and_add(ptr, 1); // expected-error{{address argument to atomic builtin cannot be const-qualified ('const int *' invalid)}}
- __atomic_fetch_add(ptr, 1, 0); // expected-error {{address argument to atomic operation must be a pointer to non-const type ('const int *' invalid)}}
-}
+ __sync_fetch_and_add_4(ptr, val);\r
+}\r
+void test9_2(volatile int* ptr, int val) {\r
+ __sync_fetch_and_add(ptr, val);\r
+}\r
+void test9_3(volatile int* ptr, int val) {\r
+ __sync_fetch_and_add_4(ptr, val);\r
+ __sync_fetch_and_add(ptr, val);\r
+ __sync_fetch_and_add(ptr, val);\r
+ __sync_fetch_and_add_4(ptr, val);\r
+ __sync_fetch_and_add_4(ptr, val);\r
+}\r
+\r
+void test9_4(volatile int* ptr, int val) {\r
+ // expected-warning@+1 {{the semantics of this intrinsic changed with GCC version 4.4 - the newer semantics are provided here}}\r
+ __sync_fetch_and_nand(ptr, val);\r
+}\r
+\r
+// rdar://7236819\r
+void test10(void) __attribute__((noreturn));\r
+\r
+void test10(void) {\r
+ __asm__("int3");\r
+ __builtin_unreachable();\r
+\r
+ // No warning about falling off the end of a noreturn function.\r
+}\r
+\r
+void test11(int X) {\r
+ switch (X) {\r
+ case __builtin_eh_return_data_regno(0): // constant foldable.\r
+ break;\r
+ }\r
+\r
+ __builtin_eh_return_data_regno(X); // expected-error {{argument to '__builtin_eh_return_data_regno' must be a constant integer}}\r
+}\r
+\r
+// PR5062\r
+void test12(void) __attribute__((__noreturn__));\r
+void test12(void) {\r
+ __builtin_trap(); // no warning because trap is noreturn.\r
+}\r
+\r
+void test_unknown_builtin(int a, int b) {\r
+ __builtin_isles(a, b); // expected-error{{use of unknown builtin}} \\r
+ // expected-note{{did you mean '__builtin_isless'?}}\r
+}\r
+\r
+int test13() {\r
+ __builtin_eh_return(0, 0); // no warning, eh_return never returns.\r
+}\r
+\r
+// <rdar://problem/8228293>\r
+void test14() {\r
+ int old;\r
+ old = __sync_fetch_and_min((volatile int *)&old, 1);\r
+}\r
+\r
+// <rdar://problem/8336581>\r
+void test15(const char *s) {\r
+ __builtin_printf("string is %s\n", s);\r
+}\r
+\r
+// PR7885\r
+int test16() {\r
+ return __builtin_constant_p() + // expected-error{{too few arguments}}\r
+ __builtin_constant_p(1, 2); // expected-error {{too many arguments}}\r
+}\r
+\r
+const int test17_n = 0;\r
+const char test17_c[] = {1, 2, 3, 0};\r
+const char test17_d[] = {1, 2, 3, 4};\r
+typedef int __attribute__((vector_size(16))) IntVector;\r
+struct Aggregate { int n; char c; };\r
+enum Enum { EnumValue1, EnumValue2 };\r
+\r
+typedef __typeof(sizeof(int)) size_t;\r
+size_t strlen(const char *);\r
+\r
+void test17() {\r
+#define ASSERT(...) { int arr[(__VA_ARGS__) ? 1 : -1]; }\r
+#define T(...) ASSERT(__builtin_constant_p(__VA_ARGS__))\r
+#define F(...) ASSERT(!__builtin_constant_p(__VA_ARGS__))\r
+\r
+ // __builtin_constant_p returns 1 if the argument folds to:\r
+ // - an arithmetic constant with value which is known at compile time\r
+ T(test17_n);\r
+ T(&test17_c[3] - test17_c);\r
+ T(3i + 5); // expected-warning {{imaginary constant}}\r
+ T(4.2 * 7.6);\r
+ T(EnumValue1);\r
+ T((enum Enum)(int)EnumValue2);\r
+\r
+ // - the address of the first character of a string literal, losslessly cast\r
+ // to any type\r
+ T("string literal");\r
+ T((double*)"string literal");\r
+ T("string literal" + 0);\r
+ T((long)"string literal");\r
+\r
+ // ... and otherwise returns 0.\r
+ F("string literal" + 1);\r
+ F(&test17_n);\r
+ F(test17_c);\r
+ F(&test17_c);\r
+ F(&test17_d);\r
+ F((struct Aggregate){0, 1});\r
+ F((IntVector){0, 1, 2, 3});\r
+\r
+ // Ensure that a technique used in glibc is handled correctly.\r
+#define OPT(...) (__builtin_constant_p(__VA_ARGS__) && strlen(__VA_ARGS__) < 4)\r
+ // FIXME: These are incorrectly treated as ICEs because strlen is treated as\r
+ // a builtin.\r
+ ASSERT(OPT("abc"));\r
+ ASSERT(!OPT("abcd"));\r
+ // In these cases, the strlen is non-constant, but the __builtin_constant_p\r
+ // is 0: the array size is not an ICE but is foldable.\r
+ ASSERT(!OPT(test17_c)); // expected-warning {{folded}}\r
+ ASSERT(!OPT(&test17_c[0])); // expected-warning {{folded}}\r
+ ASSERT(!OPT((char*)test17_c)); // expected-warning {{folded}}\r
+ ASSERT(!OPT(test17_d)); // expected-warning {{folded}}\r
+ ASSERT(!OPT(&test17_d[0])); // expected-warning {{folded}}\r
+ ASSERT(!OPT((char*)test17_d)); // expected-warning {{folded}}\r
+\r
+#undef OPT\r
+#undef T\r
+#undef F\r
+}\r
+\r
+void test18() {\r
+ char src[1024];\r
+ char dst[2048];\r
+ size_t result;\r
+ void *ptr;\r
+\r
+ ptr = __builtin___memccpy_chk(dst, src, '\037', sizeof(src), sizeof(dst));\r
+ result = __builtin___strlcpy_chk(dst, src, sizeof(dst), sizeof(dst));\r
+ result = __builtin___strlcat_chk(dst, src, sizeof(dst), sizeof(dst));\r
+\r
+ ptr = __builtin___memccpy_chk(dst, src, '\037', sizeof(src)); // expected-error {{too few arguments to function call}}\r
+ ptr = __builtin___strlcpy_chk(dst, src, sizeof(dst), sizeof(dst)); // expected-warning {{incompatible integer to pointer conversion}}\r
+ ptr = __builtin___strlcat_chk(dst, src, sizeof(dst), sizeof(dst)); // expected-warning {{incompatible integer to pointer conversion}}\r
+}\r
+\r
+void no_ms_builtins() {\r
+ __assume(1); // expected-warning {{implicit declaration}}\r
+ __noop(1); // expected-warning {{implicit declaration}}\r
+ __debugbreak(); // expected-warning {{implicit declaration}}\r
+}\r
+\r
+void unavailable() {\r
+ __builtin_operator_new(0); // expected-error {{'__builtin_operator_new' is only available in C++}}\r
+ __builtin_operator_delete(0); // expected-error {{'__builtin_operator_delete' is only available in C++}}\r
+}\r
+\r
+// rdar://18259539\r
+size_t strlcpy(char * restrict dst, const char * restrict src, size_t size);\r
+size_t strlcat(char * restrict dst, const char * restrict src, size_t size);\r
+\r
+void Test19(void)\r
+{\r
+ static char b[40];\r
+ static char buf[20];\r
+\r
+ strlcpy(buf, b, sizeof(b)); // expected-warning {{size argument in 'strlcpy' call appears to be size of the source; expected the size of the destination}} \\\r
+ // expected-note {{change size argument to be the size of the destination}}\r
+ __builtin___strlcpy_chk(buf, b, sizeof(b), __builtin_object_size(buf, 0)); // expected-warning {{size argument in '__builtin___strlcpy_chk' call appears to be size of the source; expected the size of the destination}} \\r
+ // expected-note {{change size argument to be the size of the destination}} \\r
+ // expected-warning {{'__builtin___strlcpy_chk' will always overflow destination buffer}}\r
+\r
+ strlcat(buf, b, sizeof(b)); // expected-warning {{size argument in 'strlcat' call appears to be size of the source; expected the size of the destination}} \\r
+ // expected-note {{change size argument to be the size of the destination}}\r
+ \r
+ __builtin___strlcat_chk(buf, b, sizeof(b), __builtin_object_size(buf, 0)); // expected-warning {{size argument in '__builtin___strlcat_chk' call appears to be size of the source; expected the size of the destination}} \\r
+ // expected-note {{change size argument to be the size of the destination}} \\r
+ // expected-warning {{'__builtin___strlcat_chk' will always overflow destination buffer}}\r
+}\r
+\r
+// rdar://11076881\r
+char * Test20(char *p, const char *in, unsigned n)\r
+{\r
+ static char buf[10];\r
+\r
+ __builtin___memcpy_chk (&buf[6], in, 5, __builtin_object_size (&buf[6], 0)); // expected-warning {{'__builtin___memcpy_chk' will always overflow destination buffer}}\r
+\r
+ __builtin___memcpy_chk (p, "abcde", n, __builtin_object_size (p, 0));\r
+\r
+ __builtin___memcpy_chk (&buf[5], "abcde", 5, __builtin_object_size (&buf[5], 0));\r
+\r
+ __builtin___memcpy_chk (&buf[5], "abcde", n, __builtin_object_size (&buf[5], 0));\r
+\r
+ __builtin___memcpy_chk (&buf[6], "abcde", 5, __builtin_object_size (&buf[6], 0)); // expected-warning {{'__builtin___memcpy_chk' will always overflow destination buffer}}\r
+\r
+ return buf;\r
+}\r
+\r
+void test21(const int *ptr) {\r
+ __sync_fetch_and_add(ptr, 1); // expected-error{{address argument to atomic builtin cannot be const-qualified ('const int *' invalid)}}\r
+ __atomic_fetch_add(ptr, 1, 0); // expected-error {{address argument to atomic operation must be a pointer to non-const type ('const int *' invalid)}}\r
+}\r
+\r
+void test22(void) {\r
+ (void)__builtin_signbit(); // expected-error{{too few arguments to function call, expected 1, have 0}}\r
+ (void)__builtin_signbit(1.0, 2.0, 3.0); // expected-error{{too many arguments to function call, expected 1, have 3}}\r
+ (void)__builtin_signbit(1); // expected-error {{floating point classification requires argument of floating point type (passed in 'int')}}\r
+ (void)__builtin_signbit(1.0);\r
+ (void)__builtin_signbit(1.0f);\r
+ (void)__builtin_signbit(1.0L);\r
+\r
+ (void)__builtin_signbitf(); // expected-error{{too few arguments to function call, expected 1, have 0}}\r
+ (void)__builtin_signbitf(1.0, 2.0, 3.0); // expected-error{{too many arguments to function call, expected 1, have 3}}\r
+ (void)__builtin_signbitf(1);\r
+ (void)__builtin_signbitf(1.0);\r
+ (void)__builtin_signbitf(1.0f);\r
+ (void)__builtin_signbitf(1.0L);\r
+\r
+ (void)__builtin_signbitl(); // expected-error{{too few arguments to function call, expected 1, have 0}}\r
+ (void)__builtin_signbitl(1.0, 2.0, 3.0); // expected-error{{too many arguments to function call, expected 1, have 3}}\r
+ (void)__builtin_signbitl(1);\r
+ (void)__builtin_signbitl(1.0);\r
+ (void)__builtin_signbitl(1.0f);\r
+ (void)__builtin_signbitl(1.0L);\r
+}\r