Index: lib/Sema/SemaChecking.cpp =================================================================== --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -85,6 +85,10 @@ #include "llvm/Support/Locale.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" + +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/Module.h" + #include #include #include @@ -965,15 +969,178 @@ 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; + static bool Once = false; - llvm::APSInt Result; - if (SemaBuiltinConstantArg(TheCall, ArgNo, Result)) - return true; - ICEArguments &= ~(1 << ArgNo); + if (!Once) { + Once = true; + unsigned Start = -1; + unsigned End = -1; + switch (Context.getTargetInfo().getTriple().getArch()) { + case llvm::Triple::x86: { + Start = X86::LastTIBuiltin + 1; + End = X86::LastX86CommonBuiltin; + break; + } + case llvm::Triple::x86_64: { + Start = X86::LastTIBuiltin + 1; + //Start = X86::FirstX86_64Builtin; + End = X86::LastTSBuiltin; + break; + } + case llvm::Triple::mips: + case llvm::Triple::mipsel: + case llvm::Triple::mips64: + case llvm::Triple::mips64el: { + Start = Mips::LastTIBuiltin + 1; + End = Mips::LastTSBuiltin; + break; + } + case llvm::Triple::hexagon: { + Start = Hexagon::LastTIBuiltin + 1; + End = Hexagon::LastTSBuiltin; + break; + } + case llvm::Triple::systemz: { + Start = SystemZ::LastTIBuiltin + 1; + End = SystemZ::LastTSBuiltin; + break; + } + case llvm::Triple::ppc: + case llvm::Triple::ppc64: + case llvm::Triple::ppc64le: { + Start = PPC::LastTIBuiltin + 1; + End = PPC::LastTSBuiltin; + break; + } + case llvm::Triple::aarch64: + case llvm::Triple::aarch64_be: { + Start = AArch64::LastTIBuiltin + 1; + End = AArch64::LastTSBuiltin; + break; + } + case llvm::Triple::arm: + case llvm::Triple::armeb: + case llvm::Triple::thumb: + case llvm::Triple::thumbeb: { + Start = ARM::LastTIBuiltin + 1; + End = ARM::LastTSBuiltin; + break; + } + case llvm::Triple::amdgcn: + case llvm::Triple::r600: { + Start = AMDGPU::LastTIBuiltin + 1; + End = AMDGPU::LastTSBuiltin; + break; + } + case llvm::Triple::nvptx: + case llvm::Triple::nvptx64: { + Start = NVPTX::LastTIBuiltin + 1; + End = NVPTX::LastTSBuiltin; + break; + } + case llvm::Triple::wasm32: + case llvm::Triple::wasm64: { + Start = WebAssembly::LastTIBuiltin + 1; + End = WebAssembly::LastTSBuiltin; + break; + } + case llvm::Triple::riscv32: + case llvm::Triple::riscv64: { +#if 0 + Start = RISCV::LastTIBuiltin + 1; + End = RISCV::LastTSBuiltin; +#endif + Start = 0; + End = 0; + break; + } + case llvm::Triple::xcore: { + Start = XCore::LastTIBuiltin + 1; + End = XCore::LastTSBuiltin; + break; + } + case llvm::Triple::msp430: + case llvm::Triple::sparc: + case llvm::Triple::sparcv9: + case llvm::Triple::sparcel: + case llvm::Triple::spir: + case llvm::Triple::spir64: + Start = 0; + End = 0; + break; + default: + llvm_unreachable("todo"); + } + + unsigned MissingCount = 0; + unsigned ExtraImmArg = 0; + + for (unsigned BuiltinID = Start; BuiltinID != End; ++BuiltinID) { + unsigned ICEArguments = 0; + ASTContext::GetBuiltinTypeError Error; + Context.GetBuiltinType(BuiltinID, Error, &ICEArguments); + + + const char *Name = getASTContext().BuiltinInfo.getName(BuiltinID); + llvm::Intrinsic::ID IntrinsicID = llvm::Intrinsic::not_intrinsic; + StringRef Prefix = + llvm::Triple::getArchTypePrefix(Context.getTargetInfo().getTriple().getArch()); + if (!Prefix.empty()) { + IntrinsicID = llvm::Intrinsic::getIntrinsicForGCCBuiltin(Prefix.data(), Name); + // NOTE we don't need to perform a compatibility flag check here since the + // intrinsics are declared in Builtins*.def via LANGBUILTIN which filter the + // MS builtins via ALL_MS_LANGUAGES and are filtered earlier. + if (IntrinsicID == llvm::Intrinsic::not_intrinsic) + IntrinsicID = llvm::Intrinsic::getIntrinsicForMSBuiltin(Prefix.data(), Name); + } + + + llvm::LLVMContext Ctx; + llvm::Module M("arst", Ctx); + + llvm::Function *Decl = nullptr; + + + if (IntrinsicID != llvm::Intrinsic::not_intrinsic) { + + if (!llvm::Intrinsic::isOverloaded(IntrinsicID)) { + Decl = llvm::Intrinsic::getDeclaration( + &M, (llvm::Intrinsic::ID)IntrinsicID, {}); + if (!Decl) { + llvm_unreachable("no decl"); + //report_fatal_error("no decl: " + Twine(Name)); + } + } else { + llvm::dbgs() << "Skipping overloadable intrinsic: " << Twine(Name) << '\n'; + } + } + + // 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) { + if (Decl && Decl->hasParamAttribute(ArgNo, llvm::Attribute::ImmArg)) { + llvm::dbgs() << "EXTRA immarg: " << Twine(ArgNo) << " to " << Twine(Name) << '\n'; + ++ExtraImmArg; + } + continue; + } + + + if (Decl && !Decl->hasParamAttribute(ArgNo, llvm::Attribute::ImmArg)) { + llvm::dbgs() << "Missing immarg: " + Twine(ArgNo) + " to " + Twine(Name) << '\n'; + //report_fatal_error("Missing immarg: " + Twine(ArgNo) + " to " + Twine(Name)); + ++MissingCount; + //llvm_unreachable("Missing immarg"); + } + + ICEArguments &= ~(1 << ArgNo); + } + + } + + assert(MissingCount == 0); + assert(ExtraImmArg == 0); } switch (BuiltinID) {