From 296aa96deb7e7676455db22dcdbaab83d21736ce Mon Sep 17 00:00:00 2001 From: Robin Kruppe Date: Mon, 20 Nov 2017 17:47:29 +0100 Subject: [PATCH] [rustllvm] Use report_fatal_error over llvm_unreachable This makes it more robust when assertions are disabled, crashing instead of causing UB. Also introduces a tidy check to enforce this rule, which in turn necessitated making tidy run on src/rustllvm. Fixes #44020 --- src/rustllvm/ArchiveWrapper.cpp | 2 +- src/rustllvm/PassWrapper.cpp | 32 ++++++++++++++++---------------- src/rustllvm/RustWrapper.cpp | 22 +++++++++++----------- src/tools/tidy/src/lib.rs | 1 - src/tools/tidy/src/style.rs | 10 +++++++++- 5 files changed, 37 insertions(+), 30 deletions(-) diff --git a/src/rustllvm/ArchiveWrapper.cpp b/src/rustllvm/ArchiveWrapper.cpp index 7f76861c0777d..591ebdc9ddb25 100644 --- a/src/rustllvm/ArchiveWrapper.cpp +++ b/src/rustllvm/ArchiveWrapper.cpp @@ -66,7 +66,7 @@ static Archive::Kind fromRust(LLVMRustArchiveKind Kind) { case LLVMRustArchiveKind::COFF: return Archive::K_COFF; default: - llvm_unreachable("Bad ArchiveKind."); + report_fatal_error("Bad ArchiveKind."); } } diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index d0c042e6451c7..4a359fb3ad306 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -235,7 +235,7 @@ static CodeModel::Model fromRust(LLVMRustCodeModel Model) { case LLVMRustCodeModel::Large: return CodeModel::Large; default: - llvm_unreachable("Bad CodeModel."); + report_fatal_error("Bad CodeModel."); } } @@ -258,7 +258,7 @@ static CodeGenOpt::Level fromRust(LLVMRustCodeGenOptLevel Level) { case LLVMRustCodeGenOptLevel::Aggressive: return CodeGenOpt::Aggressive; default: - llvm_unreachable("Bad CodeGenOptLevel."); + report_fatal_error("Bad CodeGenOptLevel."); } } @@ -302,7 +302,7 @@ static Optional fromRust(LLVMRustRelocMode RustReloc) { break; #endif } - llvm_unreachable("Bad RelocModel."); + report_fatal_error("Bad RelocModel."); } #if LLVM_RUSTLLVM @@ -511,7 +511,7 @@ static TargetMachine::CodeGenFileType fromRust(LLVMRustFileType Type) { case LLVMRustFileType::ObjectFile: return TargetMachine::CGFT_ObjectFile; default: - llvm_unreachable("Bad FileType."); + report_fatal_error("Bad FileType."); } } @@ -1197,7 +1197,7 @@ extern "C" bool LLVMRustWriteThinBitcodeToFile(LLVMPassManagerRef PMR, LLVMModuleRef M, const char *BcFile) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } struct LLVMRustThinLTOData { @@ -1211,32 +1211,32 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, int num_modules, const char **preserved_symbols, int num_symbols) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } extern "C" bool LLVMRustPrepareThinLTORename(const LLVMRustThinLTOData *Data, LLVMModuleRef M) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } extern "C" bool LLVMRustPrepareThinLTOResolveWeak(const LLVMRustThinLTOData *Data, LLVMModuleRef M) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } extern "C" bool LLVMRustPrepareThinLTOInternalize(const LLVMRustThinLTOData *Data, LLVMModuleRef M) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } extern "C" bool LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } extern "C" void LLVMRustFreeThinLTOData(LLVMRustThinLTOData *Data) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } struct LLVMRustThinLTOBuffer { @@ -1244,22 +1244,22 @@ struct LLVMRustThinLTOBuffer { extern "C" LLVMRustThinLTOBuffer* LLVMRustThinLTOBufferCreate(LLVMModuleRef M) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } extern "C" void LLVMRustThinLTOBufferFree(LLVMRustThinLTOBuffer *Buffer) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } extern "C" const void* LLVMRustThinLTOBufferPtr(const LLVMRustThinLTOBuffer *Buffer) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } extern "C" size_t LLVMRustThinLTOBufferLen(const LLVMRustThinLTOBuffer *Buffer) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } extern "C" LLVMModuleRef @@ -1267,6 +1267,6 @@ LLVMRustParseBitcodeForThinLTO(LLVMContextRef Context, const char *data, size_t len, const char *identifier) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } #endif // LLVM_VERSION_GE(4, 0) diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 9aa172591b86f..424b226bcf778 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -54,7 +54,7 @@ static AtomicOrdering fromRust(LLVMAtomicOrdering Ordering) { return AtomicOrdering::SequentiallyConsistent; } - llvm_unreachable("Invalid LLVMAtomicOrdering value!"); + report_fatal_error("Invalid LLVMAtomicOrdering value!"); } static LLVM_THREAD_LOCAL char *LastError; @@ -161,7 +161,7 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) { case SanitizeMemory: return Attribute::SanitizeMemory; } - llvm_unreachable("bad AttributeKind"); + report_fatal_error("bad AttributeKind"); } extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned Index, @@ -356,7 +356,7 @@ static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) { case LLVMRustSynchronizationScope::CrossThread: return SyncScope::System; default: - llvm_unreachable("bad SynchronizationScope."); + report_fatal_error("bad SynchronizationScope."); } } #else @@ -367,7 +367,7 @@ static SynchronizationScope fromRust(LLVMRustSynchronizationScope Scope) { case LLVMRustSynchronizationScope::CrossThread: return CrossThread; default: - llvm_unreachable("bad SynchronizationScope."); + report_fatal_error("bad SynchronizationScope."); } } #endif @@ -397,7 +397,7 @@ static InlineAsm::AsmDialect fromRust(LLVMRustAsmDialect Dialect) { case LLVMRustAsmDialect::Intel: return InlineAsm::AD_Intel; default: - llvm_unreachable("bad AsmDialect."); + report_fatal_error("bad AsmDialect."); } } @@ -748,7 +748,7 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable( unwrapDI(Ty), AlwaysPreserve, fromRust(Flags) #if LLVM_VERSION_GE(4, 0) , - AlignInBits + AlignInBits #endif )); } else { @@ -1149,7 +1149,7 @@ extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) { return LLVMTokenTypeKind; #endif } - llvm_unreachable("Unhandled TypeID."); + report_fatal_error("Unhandled TypeID."); } extern "C" void LLVMRustWriteDebugLocToString(LLVMContextRef C, @@ -1370,7 +1370,7 @@ static LLVMRustLinkage toRust(LLVMLinkage Linkage) { case LLVMCommonLinkage: return LLVMRustLinkage::CommonLinkage; default: - llvm_unreachable("Invalid LLVMRustLinkage value!"); + report_fatal_error("Invalid LLVMRustLinkage value!"); } } @@ -1399,7 +1399,7 @@ static LLVMLinkage fromRust(LLVMRustLinkage Linkage) { case LLVMRustLinkage::CommonLinkage: return LLVMCommonLinkage; } - llvm_unreachable("Invalid LLVMRustLinkage value!"); + report_fatal_error("Invalid LLVMRustLinkage value!"); } extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) { @@ -1447,7 +1447,7 @@ static LLVMRustVisibility toRust(LLVMVisibility Vis) { case LLVMProtectedVisibility: return LLVMRustVisibility::Protected; } - llvm_unreachable("Invalid LLVMRustVisibility value!"); + report_fatal_error("Invalid LLVMRustVisibility value!"); } static LLVMVisibility fromRust(LLVMRustVisibility Vis) { @@ -1459,7 +1459,7 @@ static LLVMVisibility fromRust(LLVMRustVisibility Vis) { case LLVMRustVisibility::Protected: return LLVMProtectedVisibility; } - llvm_unreachable("Invalid LLVMRustVisibility value!"); + report_fatal_error("Invalid LLVMRustVisibility value!"); } extern "C" LLVMRustVisibility LLVMRustGetVisibility(LLVMValueRef V) { diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 598620fa29392..bd49f288eb2eb 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -57,7 +57,6 @@ fn filter_dirs(path: &Path) -> bool { "src/libbacktrace", "src/libcompiler_builtins", "src/compiler-rt", - "src/rustllvm", "src/liblibc", "src/vendor", "src/rt/hoedown", diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index a689d8a8be411..40d84b98d3a7d 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -50,6 +50,11 @@ const UNEXPLAINED_IGNORE_DOCTEST_INFO: &str = r#"unexplained "```ignore" doctest "#; +const LLVM_UNREACHABLE_INFO: &str = r"\ +C++ code used llvm_unreachable, which triggers undefined behavior +when executed when assertions are disabled. +Use llvm::report_fatal_error for increased robustness."; + /// Parser states for line_is_url. #[derive(PartialEq)] #[allow(non_camel_case_types)] @@ -108,7 +113,7 @@ pub fn check(path: &Path, bad: &mut bool) { let mut contents = String::new(); super::walk(path, &mut super::filter_dirs, &mut |file| { let filename = file.file_name().unwrap().to_string_lossy(); - let extensions = [".rs", ".py", ".js", ".sh", ".c", ".h"]; + let extensions = [".rs", ".py", ".js", ".sh", ".c", ".cpp", ".h"]; if extensions.iter().all(|e| !filename.ends_with(e)) || filename.starts_with(".#") { return @@ -153,6 +158,9 @@ pub fn check(path: &Path, bad: &mut bool) { if line.ends_with("```ignore") || line.ends_with("```rust,ignore") { err(UNEXPLAINED_IGNORE_DOCTEST_INFO); } + if filename.ends_with(".cpp") && line.contains("llvm_unreachable") { + err(LLVM_UNREACHABLE_INFO); + } } if !licenseck(file, &contents) { tidy_error!(bad, "{}: incorrect license", file.display());