@@ -35,6 +35,7 @@ declare_lint_pass! {
3535 DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK ,
3636 DEPRECATED ,
3737 DEPRECATED_IN_FUTURE ,
38+ DEPRECATED_LLVM_INTRINSIC ,
3839 DEPRECATED_SAFE_2024 ,
3940 DEPRECATED_WHERE_CLAUSE_LOCATION ,
4041 DUPLICATE_MACRO_ATTRIBUTES ,
@@ -118,6 +119,7 @@ declare_lint_pass! {
118119 UNKNOWN_CRATE_TYPES ,
119120 UNKNOWN_DIAGNOSTIC_ATTRIBUTES ,
120121 UNKNOWN_LINTS ,
122+ UNKNOWN_LLVM_INTRINSIC ,
121123 UNNAMEABLE_TEST_ITEMS ,
122124 UNNAMEABLE_TYPES ,
123125 UNREACHABLE_CODE ,
@@ -5263,3 +5265,79 @@ declare_lint! {
52635265 report_in_deps: false ,
52645266 } ;
52655267}
5268+
5269+ declare_lint ! {
5270+ /// The `unknown_llvm_intrinsic` lint detects usage of unknown LLVM intrinsics.
5271+ ///
5272+ /// ### Example
5273+ ///
5274+ /// ```rust,compile_fail
5275+ /// #![feature(link_llvm_intrinsics, abi_unadjusted)]
5276+ ///
5277+ /// unsafe extern "unadjusted" {
5278+ /// #[link_name = "llvm.abcde"]
5279+ /// fn foo();
5280+ /// }
5281+ ///
5282+ /// #[inline(never)]
5283+ /// pub fn main() {
5284+ /// unsafe { foo() }
5285+ /// }
5286+ /// ```
5287+ ///
5288+ /// {{produces}}
5289+ ///
5290+ /// ### Explanation
5291+ ///
5292+ /// Linking to an unknown LLVM intrinsic may cause linker errors (in general it's UB),
5293+ /// so this lint captures those undesirable scenarios.
5294+ pub UNKNOWN_LLVM_INTRINSIC ,
5295+ Deny ,
5296+ "detects uses of unknown LLVM intrinsics" ,
5297+ @feature_gate = link_llvm_intrinsics;
5298+ }
5299+
5300+ declare_lint ! {
5301+ /// The `deprecated_llvm_intrinsic` lint detects usage of deprecated LLVM intrinsics.
5302+ ///
5303+ /// ### Example
5304+ ///
5305+ /// ```rust,ignore (requires x86)
5306+ /// #![cfg(any(target_arch = "x86", target_arch = "x86_64"))]
5307+ /// #![feature(link_llvm_intrinsics, abi_unadjusted)]
5308+ /// #![deny(deprecated_llvm_intrinsic)]
5309+ ///
5310+ /// unsafe extern "unadjusted" {
5311+ /// #[link_name = "llvm.x86.addcarryx.u32"]
5312+ /// fn foo(a: u8, b: u32, c: u32, d: &mut u32) -> u8;
5313+ /// }
5314+ ///
5315+ /// #[inline(never)]
5316+ /// #[target_feature(enable = "adx")]
5317+ /// pub fn bar(a: u8, b: u32, c: u32, d: &mut u32) -> u8 {
5318+ /// unsafe { foo(a, b, c, d) }
5319+ /// }
5320+ /// ```
5321+ ///
5322+ /// This will produce:
5323+ ///
5324+ /// ```text
5325+ /// error: Using deprecated intrinsic `llvm.x86.addcarryx.u32`
5326+ /// --> example.rs:7:5
5327+ /// |
5328+ /// 7 | fn foo(a: u8, b: u32, c: u32, d: &mut u32) -> u8;
5329+ /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5330+ /// |
5331+ /// ```
5332+ ///
5333+ /// ### Explanation
5334+ ///
5335+ /// LLVM periodically updates its list of intrinsics. Removed intrinsics are unlikely
5336+ /// to be removed, but they may optimize less well than their new versions, so it's
5337+ /// best to use the new version. Also, some deprecated intrinsics might have buggy
5338+ /// behavior
5339+ pub DEPRECATED_LLVM_INTRINSIC ,
5340+ Allow ,
5341+ "detects uses of deprecated LLVM intrinsics" ,
5342+ @feature_gate = link_llvm_intrinsics;
5343+ }
0 commit comments