@@ -35,6 +35,7 @@ declare_lint_pass! {
35
35
DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK ,
36
36
DEPRECATED ,
37
37
DEPRECATED_IN_FUTURE ,
38
+ DEPRECATED_LLVM_INTRINSIC ,
38
39
DEPRECATED_SAFE_2024 ,
39
40
DEPRECATED_WHERE_CLAUSE_LOCATION ,
40
41
DUPLICATE_MACRO_ATTRIBUTES ,
@@ -117,6 +118,7 @@ declare_lint_pass! {
117
118
UNKNOWN_CRATE_TYPES ,
118
119
UNKNOWN_DIAGNOSTIC_ATTRIBUTES ,
119
120
UNKNOWN_LINTS ,
121
+ UNKNOWN_LLVM_INTRINSIC ,
120
122
UNNAMEABLE_TEST_ITEMS ,
121
123
UNNAMEABLE_TYPES ,
122
124
UNREACHABLE_CODE ,
@@ -5138,3 +5140,83 @@ declare_lint! {
5138
5140
"detects tail calls of functions marked with `#[track_caller]`" ,
5139
5141
@feature_gate = explicit_tail_calls;
5140
5142
}
5143
+
5144
+ declare_lint ! {
5145
+ /// The `unknown_llvm_intrinsic` lint detects usage of unknown LLVM intrinsics.
5146
+ ///
5147
+ /// ### Example
5148
+ ///
5149
+ /// ```rust,compile_fail
5150
+ /// #![feature(link_llvm_intrinsics, abi_unadjusted)]
5151
+ ///
5152
+ /// unsafe extern "unadjusted" {
5153
+ /// #[link_name = "llvm.abcde"]
5154
+ /// fn foo();
5155
+ /// }
5156
+ ///
5157
+ /// # #[inline(never)]
5158
+ /// pub fn bar() {
5159
+ /// unsafe { foo() }
5160
+ /// }
5161
+ /// #
5162
+ /// # fn main() {
5163
+ /// # bar();
5164
+ /// # }
5165
+ /// ```
5166
+ ///
5167
+ /// {{produces}}
5168
+ ///
5169
+ /// ### Explanation
5170
+ ///
5171
+ /// Linking to an unknown LLVM intrinsic may cause linker errors (in general it's UB),
5172
+ /// so this lint captures those undesirable scenarios.
5173
+ pub UNKNOWN_LLVM_INTRINSIC ,
5174
+ Deny ,
5175
+ "detects uses of unknown LLVM intrinsics" ,
5176
+ @feature_gate = link_llvm_intrinsics;
5177
+ }
5178
+
5179
+ declare_lint ! {
5180
+ /// The `deprecated_llvm_intrinsic` lint detects usage of deprecated LLVM intrinsics.
5181
+ ///
5182
+ /// ### Example
5183
+ ///
5184
+ /// ```rust,ignore (fails on non-x86)
5185
+ /// #![cfg(any(target_arch = "x86", target_arch = "x86_64"))]
5186
+ /// #![feature(link_llvm_intrinsics, abi_unadjusted)]
5187
+ /// #![deny(deprecated_llvm_intrinsic)]
5188
+ ///
5189
+ /// unsafe extern "unadjusted" {
5190
+ /// #[link_name = "llvm.x86.addcarryx.u32"]
5191
+ /// fn foo(a: u8, b: u32, c: u32, d: &mut u32) -> u8;
5192
+ /// }
5193
+ ///
5194
+ /// #[inline(never)]
5195
+ /// #[target_feature(enable = "adx")]
5196
+ /// pub fn bar(a: u8, b: u32, c: u32, d: &mut u32) -> u8 {
5197
+ /// unsafe { foo(a, b, c, d) }
5198
+ /// }
5199
+ /// ```
5200
+ ///
5201
+ /// This will produce:
5202
+ ///
5203
+ /// ```text
5204
+ /// error: Using deprecated intrinsic `llvm.x86.addcarryx.u32`
5205
+ /// --> example.rs:7:5
5206
+ /// |
5207
+ /// 7 | fn foo(a: u8, b: u32, c: u32, d: &mut u32) -> u8;
5208
+ /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5209
+ /// |
5210
+ /// ```
5211
+ ///
5212
+ /// ### Explanation
5213
+ ///
5214
+ /// LLVM periodically updates its list of intrinsics. Removed intrinsics are unlikely
5215
+ /// to be removed, but they may optimize less well than their new versions, so it's
5216
+ /// best to use the new version. Also, some deprecated intrinsics might have buggy
5217
+ /// behavior
5218
+ pub DEPRECATED_LLVM_INTRINSIC ,
5219
+ Allow ,
5220
+ "detects uses of deprecated LLVM intrinsics" ,
5221
+ @feature_gate = link_llvm_intrinsics;
5222
+ }
0 commit comments