Auto merge of #118178 - compiler-errors:rollup-0i11w85, r=compiler-errors
Rollup of 6 pull requests Successful merges: - #118012 (Add support for global allocation in smir) - #118013 (Enable Rust to use the EHCont security feature of Windows) - #118100 (Enable profiler in dist-powerpc64-linux) - #118142 (Tighten up link attributes for llvm-wrapper bindings) - #118147 (Fix some unnecessary casts) - #118161 (Allow defining opaques in `check_coroutine_obligations`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
06d1afe518
37 changed files with 666 additions and 243 deletions
|
@ -351,6 +351,16 @@ pub unsafe fn create_module<'ll>(
|
|||
);
|
||||
}
|
||||
|
||||
// Set module flag to enable Windows EHCont Guard (/guard:ehcont).
|
||||
if sess.opts.unstable_opts.ehcont_guard {
|
||||
llvm::LLVMRustAddModuleFlag(
|
||||
llmod,
|
||||
llvm::LLVMModFlagBehavior::Warning,
|
||||
"ehcontguard\0".as_ptr() as *const _,
|
||||
1,
|
||||
)
|
||||
}
|
||||
|
||||
// Insert `llvm.ident` metadata.
|
||||
//
|
||||
// On the wasm targets it will get hooked up to the "producer" sections
|
||||
|
|
|
@ -104,7 +104,7 @@ struct TimeTraceProfiler {
|
|||
impl TimeTraceProfiler {
|
||||
fn new(enabled: bool) -> Self {
|
||||
if enabled {
|
||||
unsafe { llvm::LLVMTimeTraceProfilerInitialize() }
|
||||
unsafe { llvm::LLVMRustTimeTraceProfilerInitialize() }
|
||||
}
|
||||
TimeTraceProfiler { enabled }
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ impl TimeTraceProfiler {
|
|||
impl Drop for TimeTraceProfiler {
|
||||
fn drop(&mut self) {
|
||||
if self.enabled {
|
||||
unsafe { llvm::LLVMTimeTraceProfilerFinishThread() }
|
||||
unsafe { llvm::LLVMRustTimeTraceProfilerFinishThread() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -823,11 +823,7 @@ pub type GetSymbolsCallback = unsafe extern "C" fn(*mut c_void, *const c_char) -
|
|||
pub type GetSymbolsErrorCallback = unsafe extern "C" fn(*const c_char) -> *mut c_void;
|
||||
|
||||
extern "C" {
|
||||
pub fn LLVMRustInstallFatalErrorHandler();
|
||||
pub fn LLVMRustDisableSystemDialogsOnCrash();
|
||||
|
||||
// Create and destroy contexts.
|
||||
pub fn LLVMRustContextCreate(shouldDiscardNames: bool) -> &'static mut Context;
|
||||
pub fn LLVMContextDispose(C: &'static mut Context);
|
||||
pub fn LLVMGetMDKindIDInContext(C: &Context, Name: *const c_char, SLen: c_uint) -> c_uint;
|
||||
|
||||
|
@ -843,9 +839,6 @@ extern "C" {
|
|||
/// See Module::setModuleInlineAsm.
|
||||
pub fn LLVMAppendModuleInlineAsm(M: &Module, Asm: *const c_char, Len: size_t);
|
||||
|
||||
/// See llvm::LLVMTypeKind::getTypeID.
|
||||
pub fn LLVMRustGetTypeKind(Ty: &Type) -> TypeKind;
|
||||
|
||||
// Operations on integer types
|
||||
pub fn LLVMInt1TypeInContext(C: &Context) -> &Type;
|
||||
pub fn LLVMInt8TypeInContext(C: &Context) -> &Type;
|
||||
|
@ -879,7 +872,6 @@ extern "C" {
|
|||
) -> &'a Type;
|
||||
|
||||
// Operations on array, pointer, and vector types (sequence types)
|
||||
pub fn LLVMRustArrayType(ElementType: &Type, ElementCount: u64) -> &Type;
|
||||
pub fn LLVMPointerTypeInContext(C: &Context, AddressSpace: c_uint) -> &Type;
|
||||
pub fn LLVMVectorType(ElementType: &Type, ElementCount: c_uint) -> &Type;
|
||||
|
||||
|
@ -898,10 +890,8 @@ extern "C" {
|
|||
pub fn LLVMReplaceAllUsesWith<'a>(OldVal: &'a Value, NewVal: &'a Value);
|
||||
pub fn LLVMSetMetadata<'a>(Val: &'a Value, KindID: c_uint, Node: &'a Value);
|
||||
pub fn LLVMGlobalSetMetadata<'a>(Val: &'a Value, KindID: c_uint, Metadata: &'a Metadata);
|
||||
pub fn LLVMRustGlobalAddMetadata<'a>(Val: &'a Value, KindID: c_uint, Metadata: &'a Metadata);
|
||||
pub fn LLVMValueAsMetadata(Node: &Value) -> &Metadata;
|
||||
pub fn LLVMIsAFunction(Val: &Value) -> Option<&Value>;
|
||||
pub fn LLVMRustIsNonGVFunctionPointerTy(Val: &Value) -> bool;
|
||||
|
||||
// Operations on constants of any type
|
||||
pub fn LLVMConstNull(Ty: &Type) -> &Value;
|
||||
|
@ -931,13 +921,6 @@ extern "C" {
|
|||
pub fn LLVMConstInt(IntTy: &Type, N: c_ulonglong, SignExtend: Bool) -> &Value;
|
||||
pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, Wn: c_uint, Ws: *const u64) -> &Value;
|
||||
pub fn LLVMConstReal(RealTy: &Type, N: f64) -> &Value;
|
||||
pub fn LLVMRustConstIntGetZExtValue(ConstantVal: &ConstantInt, Value: &mut u64) -> bool;
|
||||
pub fn LLVMRustConstInt128Get(
|
||||
ConstantVal: &ConstantInt,
|
||||
SExt: bool,
|
||||
high: &mut u64,
|
||||
low: &mut u64,
|
||||
) -> bool;
|
||||
|
||||
// Operations on composite constants
|
||||
pub fn LLVMConstStringInContext(
|
||||
|
@ -977,12 +960,7 @@ extern "C" {
|
|||
|
||||
// Operations on global variables, functions, and aliases (globals)
|
||||
pub fn LLVMIsDeclaration(Global: &Value) -> Bool;
|
||||
pub fn LLVMRustGetLinkage(Global: &Value) -> Linkage;
|
||||
pub fn LLVMRustSetLinkage(Global: &Value, RustLinkage: Linkage);
|
||||
pub fn LLVMSetSection(Global: &Value, Section: *const c_char);
|
||||
pub fn LLVMRustGetVisibility(Global: &Value) -> Visibility;
|
||||
pub fn LLVMRustSetVisibility(Global: &Value, Viz: Visibility);
|
||||
pub fn LLVMRustSetDSOLocal(Global: &Value, is_dso_local: bool);
|
||||
pub fn LLVMGetAlignment(Global: &Value) -> c_uint;
|
||||
pub fn LLVMSetAlignment(Global: &Value, Bytes: c_uint);
|
||||
pub fn LLVMSetDLLStorageClass(V: &Value, C: DLLStorageClass);
|
||||
|
@ -991,13 +969,6 @@ extern "C" {
|
|||
pub fn LLVMIsAGlobalVariable(GlobalVar: &Value) -> Option<&Value>;
|
||||
pub fn LLVMAddGlobal<'a>(M: &'a Module, Ty: &'a Type, Name: *const c_char) -> &'a Value;
|
||||
pub fn LLVMGetNamedGlobal(M: &Module, Name: *const c_char) -> Option<&Value>;
|
||||
pub fn LLVMRustGetOrInsertGlobal<'a>(
|
||||
M: &'a Module,
|
||||
Name: *const c_char,
|
||||
NameLen: size_t,
|
||||
T: &'a Type,
|
||||
) -> &'a Value;
|
||||
pub fn LLVMRustInsertPrivateGlobal<'a>(M: &'a Module, T: &'a Type) -> &'a Value;
|
||||
pub fn LLVMGetFirstGlobal(M: &Module) -> Option<&Value>;
|
||||
pub fn LLVMGetNextGlobal(GlobalVar: &Value) -> Option<&Value>;
|
||||
pub fn LLVMDeleteGlobal(GlobalVar: &Value);
|
||||
|
@ -1007,16 +978,9 @@ extern "C" {
|
|||
pub fn LLVMSetThreadLocalMode(GlobalVar: &Value, Mode: ThreadLocalMode);
|
||||
pub fn LLVMIsGlobalConstant(GlobalVar: &Value) -> Bool;
|
||||
pub fn LLVMSetGlobalConstant(GlobalVar: &Value, IsConstant: Bool);
|
||||
pub fn LLVMRustGetNamedValue(
|
||||
M: &Module,
|
||||
Name: *const c_char,
|
||||
NameLen: size_t,
|
||||
) -> Option<&Value>;
|
||||
pub fn LLVMSetTailCall(CallInst: &Value, IsTailCall: Bool);
|
||||
pub fn LLVMRustSetTailCallKind(CallInst: &Value, TKC: TailCallKind);
|
||||
|
||||
// Operations on attributes
|
||||
pub fn LLVMRustCreateAttrNoValue(C: &Context, attr: AttributeKind) -> &Attribute;
|
||||
pub fn LLVMCreateStringAttribute(
|
||||
C: &Context,
|
||||
Name: *const c_char,
|
||||
|
@ -1024,31 +988,9 @@ extern "C" {
|
|||
Value: *const c_char,
|
||||
ValueLen: c_uint,
|
||||
) -> &Attribute;
|
||||
pub fn LLVMRustCreateAlignmentAttr(C: &Context, bytes: u64) -> &Attribute;
|
||||
pub fn LLVMRustCreateDereferenceableAttr(C: &Context, bytes: u64) -> &Attribute;
|
||||
pub fn LLVMRustCreateDereferenceableOrNullAttr(C: &Context, bytes: u64) -> &Attribute;
|
||||
pub fn LLVMRustCreateByValAttr<'a>(C: &'a Context, ty: &'a Type) -> &'a Attribute;
|
||||
pub fn LLVMRustCreateStructRetAttr<'a>(C: &'a Context, ty: &'a Type) -> &'a Attribute;
|
||||
pub fn LLVMRustCreateElementTypeAttr<'a>(C: &'a Context, ty: &'a Type) -> &'a Attribute;
|
||||
pub fn LLVMRustCreateUWTableAttr(C: &Context, async_: bool) -> &Attribute;
|
||||
pub fn LLVMRustCreateAllocSizeAttr(C: &Context, size_arg: u32) -> &Attribute;
|
||||
pub fn LLVMRustCreateAllocKindAttr(C: &Context, size_arg: u64) -> &Attribute;
|
||||
pub fn LLVMRustCreateMemoryEffectsAttr(C: &Context, effects: MemoryEffects) -> &Attribute;
|
||||
|
||||
// Operations on functions
|
||||
pub fn LLVMRustGetOrInsertFunction<'a>(
|
||||
M: &'a Module,
|
||||
Name: *const c_char,
|
||||
NameLen: size_t,
|
||||
FunctionTy: &'a Type,
|
||||
) -> &'a Value;
|
||||
pub fn LLVMSetFunctionCallConv(Fn: &Value, CC: c_uint);
|
||||
pub fn LLVMRustAddFunctionAttributes<'a>(
|
||||
Fn: &'a Value,
|
||||
index: c_uint,
|
||||
Attrs: *const &'a Attribute,
|
||||
AttrsLen: size_t,
|
||||
);
|
||||
|
||||
// Operations on parameters
|
||||
pub fn LLVMIsAArgument(Val: &Value) -> Option<&Value>;
|
||||
|
@ -1069,12 +1011,6 @@ extern "C" {
|
|||
|
||||
// Operations on call sites
|
||||
pub fn LLVMSetInstructionCallConv(Instr: &Value, CC: c_uint);
|
||||
pub fn LLVMRustAddCallSiteAttributes<'a>(
|
||||
Instr: &'a Value,
|
||||
index: c_uint,
|
||||
Attrs: *const &'a Attribute,
|
||||
AttrsLen: size_t,
|
||||
);
|
||||
|
||||
// Operations on load/store instructions (only)
|
||||
pub fn LLVMSetVolatile(MemoryAccessInst: &Value, volatile: Bool);
|
||||
|
@ -1112,18 +1048,6 @@ extern "C" {
|
|||
Else: &'a BasicBlock,
|
||||
NumCases: c_uint,
|
||||
) -> &'a Value;
|
||||
pub fn LLVMRustBuildInvoke<'a>(
|
||||
B: &Builder<'a>,
|
||||
Ty: &'a Type,
|
||||
Fn: &'a Value,
|
||||
Args: *const &'a Value,
|
||||
NumArgs: c_uint,
|
||||
Then: &'a BasicBlock,
|
||||
Catch: &'a BasicBlock,
|
||||
OpBundles: *const &OperandBundleDef<'a>,
|
||||
NumOpBundles: c_uint,
|
||||
Name: *const c_char,
|
||||
) -> &'a Value;
|
||||
pub fn LLVMBuildLandingPad<'a>(
|
||||
B: &Builder<'a>,
|
||||
Ty: &'a Type,
|
||||
|
@ -1337,7 +1261,6 @@ extern "C" {
|
|||
pub fn LLVMBuildNeg<'a>(B: &Builder<'a>, V: &'a Value, Name: *const c_char) -> &'a Value;
|
||||
pub fn LLVMBuildFNeg<'a>(B: &Builder<'a>, V: &'a Value, Name: *const c_char) -> &'a Value;
|
||||
pub fn LLVMBuildNot<'a>(B: &Builder<'a>, V: &'a Value, Name: *const c_char) -> &'a Value;
|
||||
pub fn LLVMRustSetFastMath(Instr: &Value);
|
||||
|
||||
// Memory
|
||||
pub fn LLVMBuildAlloca<'a>(B: &Builder<'a>, Ty: &'a Type, Name: *const c_char) -> &'a Value;
|
||||
|
@ -1485,42 +1408,6 @@ extern "C" {
|
|||
|
||||
// Miscellaneous instructions
|
||||
pub fn LLVMBuildPhi<'a>(B: &Builder<'a>, Ty: &'a Type, Name: *const c_char) -> &'a Value;
|
||||
pub fn LLVMRustGetInstrProfIncrementIntrinsic(M: &Module) -> &Value;
|
||||
pub fn LLVMRustBuildCall<'a>(
|
||||
B: &Builder<'a>,
|
||||
Ty: &'a Type,
|
||||
Fn: &'a Value,
|
||||
Args: *const &'a Value,
|
||||
NumArgs: c_uint,
|
||||
OpBundles: *const &OperandBundleDef<'a>,
|
||||
NumOpBundles: c_uint,
|
||||
) -> &'a Value;
|
||||
pub fn LLVMRustBuildMemCpy<'a>(
|
||||
B: &Builder<'a>,
|
||||
Dst: &'a Value,
|
||||
DstAlign: c_uint,
|
||||
Src: &'a Value,
|
||||
SrcAlign: c_uint,
|
||||
Size: &'a Value,
|
||||
IsVolatile: bool,
|
||||
) -> &'a Value;
|
||||
pub fn LLVMRustBuildMemMove<'a>(
|
||||
B: &Builder<'a>,
|
||||
Dst: &'a Value,
|
||||
DstAlign: c_uint,
|
||||
Src: &'a Value,
|
||||
SrcAlign: c_uint,
|
||||
Size: &'a Value,
|
||||
IsVolatile: bool,
|
||||
) -> &'a Value;
|
||||
pub fn LLVMRustBuildMemSet<'a>(
|
||||
B: &Builder<'a>,
|
||||
Dst: &'a Value,
|
||||
DstAlign: c_uint,
|
||||
Val: &'a Value,
|
||||
Size: &'a Value,
|
||||
IsVolatile: bool,
|
||||
) -> &'a Value;
|
||||
pub fn LLVMBuildSelect<'a>(
|
||||
B: &Builder<'a>,
|
||||
If: &'a Value,
|
||||
|
@ -1568,6 +1455,202 @@ extern "C" {
|
|||
Name: *const c_char,
|
||||
) -> &'a Value;
|
||||
|
||||
// Atomic Operations
|
||||
pub fn LLVMBuildAtomicCmpXchg<'a>(
|
||||
B: &Builder<'a>,
|
||||
LHS: &'a Value,
|
||||
CMP: &'a Value,
|
||||
RHS: &'a Value,
|
||||
Order: AtomicOrdering,
|
||||
FailureOrder: AtomicOrdering,
|
||||
SingleThreaded: Bool,
|
||||
) -> &'a Value;
|
||||
|
||||
pub fn LLVMSetWeak(CmpXchgInst: &Value, IsWeak: Bool);
|
||||
|
||||
pub fn LLVMBuildAtomicRMW<'a>(
|
||||
B: &Builder<'a>,
|
||||
Op: AtomicRmwBinOp,
|
||||
LHS: &'a Value,
|
||||
RHS: &'a Value,
|
||||
Order: AtomicOrdering,
|
||||
SingleThreaded: Bool,
|
||||
) -> &'a Value;
|
||||
|
||||
pub fn LLVMBuildFence<'a>(
|
||||
B: &Builder<'a>,
|
||||
Order: AtomicOrdering,
|
||||
SingleThreaded: Bool,
|
||||
Name: *const c_char,
|
||||
) -> &'a Value;
|
||||
|
||||
/// Writes a module to the specified path. Returns 0 on success.
|
||||
pub fn LLVMWriteBitcodeToFile(M: &Module, Path: *const c_char) -> c_int;
|
||||
|
||||
/// Creates a legacy pass manager -- only used for final codegen.
|
||||
pub fn LLVMCreatePassManager<'a>() -> &'a mut PassManager<'a>;
|
||||
|
||||
pub fn LLVMAddAnalysisPasses<'a>(T: &'a TargetMachine, PM: &PassManager<'a>);
|
||||
|
||||
pub fn LLVMGetHostCPUFeatures() -> *mut c_char;
|
||||
|
||||
pub fn LLVMDisposeMessage(message: *mut c_char);
|
||||
|
||||
pub fn LLVMIsMultithreaded() -> Bool;
|
||||
|
||||
pub fn LLVMStructCreateNamed(C: &Context, Name: *const c_char) -> &Type;
|
||||
|
||||
pub fn LLVMStructSetBody<'a>(
|
||||
StructTy: &'a Type,
|
||||
ElementTypes: *const &'a Type,
|
||||
ElementCount: c_uint,
|
||||
Packed: Bool,
|
||||
);
|
||||
|
||||
pub fn LLVMMetadataAsValue<'a>(C: &'a Context, MD: &'a Metadata) -> &'a Value;
|
||||
|
||||
pub fn LLVMSetUnnamedAddress(Global: &Value, UnnamedAddr: UnnamedAddr);
|
||||
|
||||
pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&ConstantInt>;
|
||||
}
|
||||
|
||||
#[link(name = "llvm-wrapper", kind = "static")]
|
||||
extern "C" {
|
||||
pub fn LLVMRustInstallFatalErrorHandler();
|
||||
pub fn LLVMRustDisableSystemDialogsOnCrash();
|
||||
|
||||
// Create and destroy contexts.
|
||||
pub fn LLVMRustContextCreate(shouldDiscardNames: bool) -> &'static mut Context;
|
||||
|
||||
/// See llvm::LLVMTypeKind::getTypeID.
|
||||
pub fn LLVMRustGetTypeKind(Ty: &Type) -> TypeKind;
|
||||
|
||||
// Operations on array, pointer, and vector types (sequence types)
|
||||
pub fn LLVMRustArrayType(ElementType: &Type, ElementCount: u64) -> &Type;
|
||||
|
||||
// Operations on all values
|
||||
pub fn LLVMRustGlobalAddMetadata<'a>(Val: &'a Value, KindID: c_uint, Metadata: &'a Metadata);
|
||||
pub fn LLVMRustIsNonGVFunctionPointerTy(Val: &Value) -> bool;
|
||||
|
||||
// Operations on scalar constants
|
||||
pub fn LLVMRustConstIntGetZExtValue(ConstantVal: &ConstantInt, Value: &mut u64) -> bool;
|
||||
pub fn LLVMRustConstInt128Get(
|
||||
ConstantVal: &ConstantInt,
|
||||
SExt: bool,
|
||||
high: &mut u64,
|
||||
low: &mut u64,
|
||||
) -> bool;
|
||||
|
||||
// Operations on global variables, functions, and aliases (globals)
|
||||
pub fn LLVMRustGetLinkage(Global: &Value) -> Linkage;
|
||||
pub fn LLVMRustSetLinkage(Global: &Value, RustLinkage: Linkage);
|
||||
pub fn LLVMRustGetVisibility(Global: &Value) -> Visibility;
|
||||
pub fn LLVMRustSetVisibility(Global: &Value, Viz: Visibility);
|
||||
pub fn LLVMRustSetDSOLocal(Global: &Value, is_dso_local: bool);
|
||||
|
||||
// Operations on global variables
|
||||
pub fn LLVMRustGetOrInsertGlobal<'a>(
|
||||
M: &'a Module,
|
||||
Name: *const c_char,
|
||||
NameLen: size_t,
|
||||
T: &'a Type,
|
||||
) -> &'a Value;
|
||||
pub fn LLVMRustInsertPrivateGlobal<'a>(M: &'a Module, T: &'a Type) -> &'a Value;
|
||||
pub fn LLVMRustGetNamedValue(
|
||||
M: &Module,
|
||||
Name: *const c_char,
|
||||
NameLen: size_t,
|
||||
) -> Option<&Value>;
|
||||
pub fn LLVMRustSetTailCallKind(CallInst: &Value, TKC: TailCallKind);
|
||||
|
||||
// Operations on attributes
|
||||
pub fn LLVMRustCreateAttrNoValue(C: &Context, attr: AttributeKind) -> &Attribute;
|
||||
pub fn LLVMRustCreateAlignmentAttr(C: &Context, bytes: u64) -> &Attribute;
|
||||
pub fn LLVMRustCreateDereferenceableAttr(C: &Context, bytes: u64) -> &Attribute;
|
||||
pub fn LLVMRustCreateDereferenceableOrNullAttr(C: &Context, bytes: u64) -> &Attribute;
|
||||
pub fn LLVMRustCreateByValAttr<'a>(C: &'a Context, ty: &'a Type) -> &'a Attribute;
|
||||
pub fn LLVMRustCreateStructRetAttr<'a>(C: &'a Context, ty: &'a Type) -> &'a Attribute;
|
||||
pub fn LLVMRustCreateElementTypeAttr<'a>(C: &'a Context, ty: &'a Type) -> &'a Attribute;
|
||||
pub fn LLVMRustCreateUWTableAttr(C: &Context, async_: bool) -> &Attribute;
|
||||
pub fn LLVMRustCreateAllocSizeAttr(C: &Context, size_arg: u32) -> &Attribute;
|
||||
pub fn LLVMRustCreateAllocKindAttr(C: &Context, size_arg: u64) -> &Attribute;
|
||||
pub fn LLVMRustCreateMemoryEffectsAttr(C: &Context, effects: MemoryEffects) -> &Attribute;
|
||||
|
||||
// Operations on functions
|
||||
pub fn LLVMRustGetOrInsertFunction<'a>(
|
||||
M: &'a Module,
|
||||
Name: *const c_char,
|
||||
NameLen: size_t,
|
||||
FunctionTy: &'a Type,
|
||||
) -> &'a Value;
|
||||
pub fn LLVMRustAddFunctionAttributes<'a>(
|
||||
Fn: &'a Value,
|
||||
index: c_uint,
|
||||
Attrs: *const &'a Attribute,
|
||||
AttrsLen: size_t,
|
||||
);
|
||||
|
||||
// Operations on call sites
|
||||
pub fn LLVMRustAddCallSiteAttributes<'a>(
|
||||
Instr: &'a Value,
|
||||
index: c_uint,
|
||||
Attrs: *const &'a Attribute,
|
||||
AttrsLen: size_t,
|
||||
);
|
||||
|
||||
pub fn LLVMRustBuildInvoke<'a>(
|
||||
B: &Builder<'a>,
|
||||
Ty: &'a Type,
|
||||
Fn: &'a Value,
|
||||
Args: *const &'a Value,
|
||||
NumArgs: c_uint,
|
||||
Then: &'a BasicBlock,
|
||||
Catch: &'a BasicBlock,
|
||||
OpBundles: *const &OperandBundleDef<'a>,
|
||||
NumOpBundles: c_uint,
|
||||
Name: *const c_char,
|
||||
) -> &'a Value;
|
||||
|
||||
pub fn LLVMRustSetFastMath(Instr: &Value);
|
||||
|
||||
// Miscellaneous instructions
|
||||
pub fn LLVMRustGetInstrProfIncrementIntrinsic(M: &Module) -> &Value;
|
||||
pub fn LLVMRustBuildCall<'a>(
|
||||
B: &Builder<'a>,
|
||||
Ty: &'a Type,
|
||||
Fn: &'a Value,
|
||||
Args: *const &'a Value,
|
||||
NumArgs: c_uint,
|
||||
OpBundles: *const &OperandBundleDef<'a>,
|
||||
NumOpBundles: c_uint,
|
||||
) -> &'a Value;
|
||||
pub fn LLVMRustBuildMemCpy<'a>(
|
||||
B: &Builder<'a>,
|
||||
Dst: &'a Value,
|
||||
DstAlign: c_uint,
|
||||
Src: &'a Value,
|
||||
SrcAlign: c_uint,
|
||||
Size: &'a Value,
|
||||
IsVolatile: bool,
|
||||
) -> &'a Value;
|
||||
pub fn LLVMRustBuildMemMove<'a>(
|
||||
B: &Builder<'a>,
|
||||
Dst: &'a Value,
|
||||
DstAlign: c_uint,
|
||||
Src: &'a Value,
|
||||
SrcAlign: c_uint,
|
||||
Size: &'a Value,
|
||||
IsVolatile: bool,
|
||||
) -> &'a Value;
|
||||
pub fn LLVMRustBuildMemSet<'a>(
|
||||
B: &Builder<'a>,
|
||||
Dst: &'a Value,
|
||||
DstAlign: c_uint,
|
||||
Val: &'a Value,
|
||||
Size: &'a Value,
|
||||
IsVolatile: bool,
|
||||
) -> &'a Value;
|
||||
|
||||
pub fn LLVMRustBuildVectorReduceFAdd<'a>(
|
||||
B: &Builder<'a>,
|
||||
Acc: &'a Value,
|
||||
|
@ -1623,53 +1706,11 @@ extern "C" {
|
|||
Order: AtomicOrdering,
|
||||
) -> &'a Value;
|
||||
|
||||
pub fn LLVMBuildAtomicCmpXchg<'a>(
|
||||
B: &Builder<'a>,
|
||||
LHS: &'a Value,
|
||||
CMP: &'a Value,
|
||||
RHS: &'a Value,
|
||||
Order: AtomicOrdering,
|
||||
FailureOrder: AtomicOrdering,
|
||||
SingleThreaded: Bool,
|
||||
) -> &'a Value;
|
||||
pub fn LLVMRustTimeTraceProfilerInitialize();
|
||||
|
||||
pub fn LLVMSetWeak(CmpXchgInst: &Value, IsWeak: Bool);
|
||||
pub fn LLVMRustTimeTraceProfilerFinishThread();
|
||||
|
||||
pub fn LLVMBuildAtomicRMW<'a>(
|
||||
B: &Builder<'a>,
|
||||
Op: AtomicRmwBinOp,
|
||||
LHS: &'a Value,
|
||||
RHS: &'a Value,
|
||||
Order: AtomicOrdering,
|
||||
SingleThreaded: Bool,
|
||||
) -> &'a Value;
|
||||
|
||||
pub fn LLVMBuildFence<'a>(
|
||||
B: &Builder<'a>,
|
||||
Order: AtomicOrdering,
|
||||
SingleThreaded: Bool,
|
||||
Name: *const c_char,
|
||||
) -> &'a Value;
|
||||
|
||||
/// Writes a module to the specified path. Returns 0 on success.
|
||||
pub fn LLVMWriteBitcodeToFile(M: &Module, Path: *const c_char) -> c_int;
|
||||
|
||||
/// Creates a legacy pass manager -- only used for final codegen.
|
||||
pub fn LLVMCreatePassManager<'a>() -> &'a mut PassManager<'a>;
|
||||
|
||||
pub fn LLVMTimeTraceProfilerInitialize();
|
||||
|
||||
pub fn LLVMTimeTraceProfilerFinishThread();
|
||||
|
||||
pub fn LLVMTimeTraceProfilerFinish(FileName: *const c_char);
|
||||
|
||||
pub fn LLVMAddAnalysisPasses<'a>(T: &'a TargetMachine, PM: &PassManager<'a>);
|
||||
|
||||
pub fn LLVMGetHostCPUFeatures() -> *mut c_char;
|
||||
|
||||
pub fn LLVMDisposeMessage(message: *mut c_char);
|
||||
|
||||
pub fn LLVMIsMultithreaded() -> Bool;
|
||||
pub fn LLVMRustTimeTraceProfilerFinish(FileName: *const c_char);
|
||||
|
||||
/// Returns a string describing the last error caused by an LLVMRust* call.
|
||||
pub fn LLVMRustGetLastError() -> *const c_char;
|
||||
|
@ -1680,15 +1721,6 @@ extern "C" {
|
|||
/// Print the statistics since static dtors aren't picking them up.
|
||||
pub fn LLVMRustPrintStatistics(size: *const size_t) -> *const c_char;
|
||||
|
||||
pub fn LLVMStructCreateNamed(C: &Context, Name: *const c_char) -> &Type;
|
||||
|
||||
pub fn LLVMStructSetBody<'a>(
|
||||
StructTy: &'a Type,
|
||||
ElementTypes: *const &'a Type,
|
||||
ElementCount: c_uint,
|
||||
Packed: Bool,
|
||||
);
|
||||
|
||||
/// Prepares inline assembly.
|
||||
pub fn LLVMRustInlineAsm(
|
||||
Ty: &Type,
|
||||
|
@ -1761,8 +1793,6 @@ extern "C" {
|
|||
);
|
||||
pub fn LLVMRustHasModuleFlag(M: &Module, name: *const c_char, len: size_t) -> bool;
|
||||
|
||||
pub fn LLVMMetadataAsValue<'a>(C: &'a Context, MD: &'a Metadata) -> &'a Value;
|
||||
|
||||
pub fn LLVMRustDIBuilderCreate(M: &Module) -> &mut DIBuilder<'_>;
|
||||
|
||||
pub fn LLVMRustDIBuilderDispose<'a>(Builder: &'a mut DIBuilder<'a>);
|
||||
|
@ -2052,8 +2082,6 @@ extern "C" {
|
|||
UniqueIdLen: size_t,
|
||||
) -> &'a DIDerivedType;
|
||||
|
||||
pub fn LLVMSetUnnamedAddress(Global: &Value, UnnamedAddr: UnnamedAddr);
|
||||
|
||||
pub fn LLVMRustDIBuilderCreateTemplateTypeParameter<'a>(
|
||||
Builder: &DIBuilder<'a>,
|
||||
Scope: Option<&'a DIScope>,
|
||||
|
@ -2092,8 +2120,6 @@ extern "C" {
|
|||
#[allow(improper_ctypes)]
|
||||
pub fn LLVMRustWriteValueToString(value_ref: &Value, s: &RustString);
|
||||
|
||||
pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&ConstantInt>;
|
||||
|
||||
pub fn LLVMRustHasFeature(T: &TargetMachine, s: *const c_char) -> bool;
|
||||
|
||||
pub fn LLVMRustPrintTargetCPUs(
|
||||
|
|
|
@ -121,7 +121,7 @@ unsafe fn configure_llvm(sess: &Session) {
|
|||
}
|
||||
|
||||
if sess.opts.unstable_opts.llvm_time_trace {
|
||||
llvm::LLVMTimeTraceProfilerInitialize();
|
||||
llvm::LLVMRustTimeTraceProfilerInitialize();
|
||||
}
|
||||
|
||||
rustc_llvm::initialize_available_targets();
|
||||
|
@ -132,7 +132,7 @@ unsafe fn configure_llvm(sess: &Session) {
|
|||
pub fn time_trace_profiler_finish(file_name: &Path) {
|
||||
unsafe {
|
||||
let file_name = path_to_c_string(file_name);
|
||||
llvm::LLVMTimeTraceProfilerFinish(file_name.as_ptr());
|
||||
llvm::LLVMRustTimeTraceProfilerFinish(file_name.as_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2378,6 +2378,11 @@ fn add_order_independent_options(
|
|||
cmd.control_flow_guard();
|
||||
}
|
||||
|
||||
// OBJECT-FILES-NO, AUDIT-ORDER
|
||||
if sess.opts.unstable_opts.ehcont_guard {
|
||||
cmd.ehcont_guard();
|
||||
}
|
||||
|
||||
add_rpath_args(cmd, sess, codegen_results, out_filename);
|
||||
}
|
||||
|
||||
|
|
|
@ -185,6 +185,7 @@ pub trait Linker {
|
|||
fn optimize(&mut self);
|
||||
fn pgo_gen(&mut self);
|
||||
fn control_flow_guard(&mut self);
|
||||
fn ehcont_guard(&mut self);
|
||||
fn debuginfo(&mut self, strip: Strip, natvis_debugger_visualizers: &[PathBuf]);
|
||||
fn no_crt_objects(&mut self);
|
||||
fn no_default_libraries(&mut self);
|
||||
|
@ -605,6 +606,8 @@ impl<'a> Linker for GccLinker<'a> {
|
|||
|
||||
fn control_flow_guard(&mut self) {}
|
||||
|
||||
fn ehcont_guard(&mut self) {}
|
||||
|
||||
fn debuginfo(&mut self, strip: Strip, _: &[PathBuf]) {
|
||||
// MacOS linker doesn't support stripping symbols directly anymore.
|
||||
if self.sess.target.is_like_osx {
|
||||
|
@ -914,6 +917,12 @@ impl<'a> Linker for MsvcLinker<'a> {
|
|||
self.cmd.arg("/guard:cf");
|
||||
}
|
||||
|
||||
fn ehcont_guard(&mut self) {
|
||||
if self.sess.target.pointer_width == 64 {
|
||||
self.cmd.arg("/guard:ehcont");
|
||||
}
|
||||
}
|
||||
|
||||
fn debuginfo(&mut self, strip: Strip, natvis_debugger_visualizers: &[PathBuf]) {
|
||||
match strip {
|
||||
Strip::None => {
|
||||
|
@ -1127,6 +1136,8 @@ impl<'a> Linker for EmLinker<'a> {
|
|||
|
||||
fn control_flow_guard(&mut self) {}
|
||||
|
||||
fn ehcont_guard(&mut self) {}
|
||||
|
||||
fn debuginfo(&mut self, _strip: Strip, _: &[PathBuf]) {
|
||||
// Preserve names or generate source maps depending on debug info
|
||||
// For more information see https://emscripten.org/docs/tools_reference/emcc.html#emcc-g
|
||||
|
@ -1319,6 +1330,8 @@ impl<'a> Linker for WasmLd<'a> {
|
|||
|
||||
fn control_flow_guard(&mut self) {}
|
||||
|
||||
fn ehcont_guard(&mut self) {}
|
||||
|
||||
fn no_crt_objects(&mut self) {}
|
||||
|
||||
fn no_default_libraries(&mut self) {}
|
||||
|
@ -1472,6 +1485,8 @@ impl<'a> Linker for L4Bender<'a> {
|
|||
|
||||
fn control_flow_guard(&mut self) {}
|
||||
|
||||
fn ehcont_guard(&mut self) {}
|
||||
|
||||
fn no_crt_objects(&mut self) {}
|
||||
}
|
||||
|
||||
|
@ -1613,6 +1628,8 @@ impl<'a> Linker for AixLinker<'a> {
|
|||
|
||||
fn control_flow_guard(&mut self) {}
|
||||
|
||||
fn ehcont_guard(&mut self) {}
|
||||
|
||||
fn debuginfo(&mut self, strip: Strip, _: &[PathBuf]) {
|
||||
match strip {
|
||||
Strip::None => {}
|
||||
|
@ -1835,6 +1852,8 @@ impl<'a> Linker for PtxLinker<'a> {
|
|||
|
||||
fn control_flow_guard(&mut self) {}
|
||||
|
||||
fn ehcont_guard(&mut self) {}
|
||||
|
||||
fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, _symbols: &[String]) {}
|
||||
|
||||
fn subsystem(&mut self, _subsystem: &str) {}
|
||||
|
@ -1931,6 +1950,8 @@ impl<'a> Linker for BpfLinker<'a> {
|
|||
|
||||
fn control_flow_guard(&mut self) {}
|
||||
|
||||
fn ehcont_guard(&mut self) {}
|
||||
|
||||
fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
|
||||
let path = tmpdir.join("symbols");
|
||||
let res: io::Result<()> = try {
|
||||
|
|
|
@ -474,27 +474,25 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
cg_base.project_index(bx, llindex)
|
||||
}
|
||||
mir::ProjectionElem::ConstantIndex { offset, from_end: false, min_length: _ } => {
|
||||
let lloffset = bx.cx().const_usize(offset as u64);
|
||||
let lloffset = bx.cx().const_usize(offset);
|
||||
cg_base.project_index(bx, lloffset)
|
||||
}
|
||||
mir::ProjectionElem::ConstantIndex { offset, from_end: true, min_length: _ } => {
|
||||
let lloffset = bx.cx().const_usize(offset as u64);
|
||||
let lloffset = bx.cx().const_usize(offset);
|
||||
let lllen = cg_base.len(bx.cx());
|
||||
let llindex = bx.sub(lllen, lloffset);
|
||||
cg_base.project_index(bx, llindex)
|
||||
}
|
||||
mir::ProjectionElem::Subslice { from, to, from_end } => {
|
||||
let mut subslice = cg_base.project_index(bx, bx.cx().const_usize(from as u64));
|
||||
let mut subslice = cg_base.project_index(bx, bx.cx().const_usize(from));
|
||||
let projected_ty =
|
||||
PlaceTy::from_ty(cg_base.layout.ty).projection_ty(tcx, *elem).ty;
|
||||
subslice.layout = bx.cx().layout_of(self.monomorphize(projected_ty));
|
||||
|
||||
if subslice.layout.is_unsized() {
|
||||
assert!(from_end, "slice subslices should be `from_end`");
|
||||
subslice.llextra = Some(bx.sub(
|
||||
cg_base.llextra.unwrap(),
|
||||
bx.cx().const_usize((from as u64) + (to as u64)),
|
||||
));
|
||||
subslice.llextra =
|
||||
Some(bx.sub(cg_base.llextra.unwrap(), bx.cx().const_usize(from + to)));
|
||||
}
|
||||
|
||||
subslice
|
||||
|
|
|
@ -493,7 +493,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
|||
};
|
||||
|
||||
let ptr = ecx.allocate_ptr(
|
||||
Size::from_bytes(size as u64),
|
||||
Size::from_bytes(size),
|
||||
align,
|
||||
interpret::MemoryKind::Machine(MemoryKind::Heap),
|
||||
)?;
|
||||
|
|
|
@ -1468,7 +1468,10 @@ fn opaque_type_cycle_error(
|
|||
err.emit()
|
||||
}
|
||||
|
||||
pub(super) fn check_coroutine_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
pub(super) fn check_coroutine_obligations(
|
||||
tcx: TyCtxt<'_>,
|
||||
def_id: LocalDefId,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
debug_assert!(matches!(tcx.def_kind(def_id), DefKind::Coroutine));
|
||||
|
||||
let typeck = tcx.typeck(def_id);
|
||||
|
@ -1482,8 +1485,9 @@ pub(super) fn check_coroutine_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
// typeck writeback gives us predicates with their regions erased.
|
||||
// As borrowck already has checked lifetimes, we do not need to do it again.
|
||||
.ignoring_regions()
|
||||
// Bind opaque types to `def_id` as they should have been checked by borrowck.
|
||||
.with_opaque_type_inference(DefiningAnchor::Bind(def_id))
|
||||
// Bind opaque types to type checking root, as they should have been checked by borrowck,
|
||||
// but may show up in some cases, like when (root) obligations are stalled in the new solver.
|
||||
.with_opaque_type_inference(DefiningAnchor::Bind(typeck.hir_owner.def_id))
|
||||
.build();
|
||||
|
||||
let mut fulfillment_cx = <dyn TraitEngine<'_>>::new(&infcx);
|
||||
|
@ -1513,6 +1517,16 @@ pub(super) fn check_coroutine_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
let errors = fulfillment_cx.select_all_or_error(&infcx);
|
||||
debug!(?errors);
|
||||
if !errors.is_empty() {
|
||||
infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
|
||||
}
|
||||
|
||||
// Check that any hidden types found when checking these stalled coroutine obligations
|
||||
// are valid.
|
||||
for (key, ty) in infcx.take_opaque_types() {
|
||||
let hidden_type = infcx.resolve_vars_if_possible(ty.hidden_type);
|
||||
let key = infcx.resolve_vars_if_possible(key);
|
||||
sanity_check_found_hidden_type(tcx, key, hidden_type)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1861,7 +1861,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
// method yet. So create fresh variables here for those too,
|
||||
// if there are any.
|
||||
let generics = self.tcx.generics_of(method);
|
||||
assert_eq!(args.len(), generics.parent_count as usize);
|
||||
assert_eq!(args.len(), generics.parent_count);
|
||||
|
||||
let xform_fn_sig = if generics.params.is_empty() {
|
||||
fn_sig.instantiate(self.tcx, args)
|
||||
|
|
|
@ -187,7 +187,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for InferenceFudger<'a, 'tcx> {
|
|||
if self.type_vars.0.contains(&vid) {
|
||||
// This variable was created during the fudging.
|
||||
// Recreate it with a fresh variable here.
|
||||
let idx = (vid.as_usize() - self.type_vars.0.start.as_usize()) as usize;
|
||||
let idx = vid.as_usize() - self.type_vars.0.start.as_usize();
|
||||
let origin = self.type_vars.1[idx];
|
||||
self.infcx.next_ty_var(origin)
|
||||
} else {
|
||||
|
@ -236,7 +236,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for InferenceFudger<'a, 'tcx> {
|
|||
if self.const_vars.0.contains(&vid) {
|
||||
// This variable was created during the fudging.
|
||||
// Recreate it with a fresh variable here.
|
||||
let idx = (vid.index() - self.const_vars.0.start.index()) as usize;
|
||||
let idx = vid.index() - self.const_vars.0.start.index();
|
||||
let origin = self.const_vars.1[idx];
|
||||
self.infcx.next_const_var(ct.ty(), origin)
|
||||
} else {
|
||||
|
|
|
@ -681,17 +681,13 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
|||
for constraint in self.data.constraints.keys() {
|
||||
match *constraint {
|
||||
Constraint::VarSubVar(a_id, b_id) => {
|
||||
graph.add_edge(
|
||||
NodeIndex(a_id.index() as usize),
|
||||
NodeIndex(b_id.index() as usize),
|
||||
*constraint,
|
||||
);
|
||||
graph.add_edge(NodeIndex(a_id.index()), NodeIndex(b_id.index()), *constraint);
|
||||
}
|
||||
Constraint::RegSubVar(_, b_id) => {
|
||||
graph.add_edge(dummy_source, NodeIndex(b_id.index() as usize), *constraint);
|
||||
graph.add_edge(dummy_source, NodeIndex(b_id.index()), *constraint);
|
||||
}
|
||||
Constraint::VarSubReg(a_id, _) => {
|
||||
graph.add_edge(NodeIndex(a_id.index() as usize), dummy_sink, *constraint);
|
||||
graph.add_edge(NodeIndex(a_id.index()), dummy_sink, *constraint);
|
||||
}
|
||||
Constraint::RegSubReg(..) => {
|
||||
// this would be an edge from `dummy_source` to
|
||||
|
@ -878,7 +874,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
|||
) {
|
||||
debug!("process_edges(source_vid={:?}, dir={:?})", source_vid, dir);
|
||||
|
||||
let source_node_index = NodeIndex(source_vid.index() as usize);
|
||||
let source_node_index = NodeIndex(source_vid.index());
|
||||
for (_, edge) in graph.adjacent_edges(source_node_index, dir) {
|
||||
match edge.data {
|
||||
Constraint::VarSubVar(from_vid, to_vid) => {
|
||||
|
|
|
@ -317,7 +317,7 @@ impl<'tcx> RegionConstraintStorage<'tcx> {
|
|||
match undo_entry {
|
||||
AddVar(vid) => {
|
||||
self.var_infos.pop().unwrap();
|
||||
assert_eq!(self.var_infos.len(), vid.index() as usize);
|
||||
assert_eq!(self.var_infos.len(), vid.index());
|
||||
}
|
||||
AddConstraint(ref constraint) => {
|
||||
self.data.constraints.remove(constraint);
|
||||
|
|
|
@ -60,17 +60,17 @@ typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
|
|||
DEFINE_STDCXX_CONVERSION_FUNCTIONS(Pass, LLVMPassRef)
|
||||
DEFINE_STDCXX_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
|
||||
|
||||
extern "C" void LLVMTimeTraceProfilerInitialize() {
|
||||
extern "C" void LLVMRustTimeTraceProfilerInitialize() {
|
||||
timeTraceProfilerInitialize(
|
||||
/* TimeTraceGranularity */ 0,
|
||||
/* ProcName */ "rustc");
|
||||
}
|
||||
|
||||
extern "C" void LLVMTimeTraceProfilerFinishThread() {
|
||||
extern "C" void LLVMRustTimeTraceProfilerFinishThread() {
|
||||
timeTraceProfilerFinishThread();
|
||||
}
|
||||
|
||||
extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) {
|
||||
extern "C" void LLVMRustTimeTraceProfilerFinish(const char* FileName) {
|
||||
StringRef FN(FileName);
|
||||
std::error_code EC;
|
||||
raw_fd_ostream OS(FN, EC, sys::fs::CD_CreateAlways);
|
||||
|
|
|
@ -2268,11 +2268,7 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) {
|
|||
file.seek(std::io::SeekFrom::Start(pos_before_seek)).unwrap();
|
||||
|
||||
// Record metadata size for self-profiling
|
||||
tcx.prof.artifact_size(
|
||||
"crate_metadata",
|
||||
"crate_metadata",
|
||||
file.metadata().unwrap().len() as u64,
|
||||
);
|
||||
tcx.prof.artifact_size("crate_metadata", "crate_metadata", file.metadata().unwrap().len());
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
|
|
|
@ -497,7 +497,7 @@ impl<I: Idx, const N: usize, T: FixedSizeEncoding<ByteArray = [u8; N]>> TableBui
|
|||
}
|
||||
|
||||
LazyTable::from_position_and_encoded_size(
|
||||
NonZeroUsize::new(pos as usize).unwrap(),
|
||||
NonZeroUsize::new(pos).unwrap(),
|
||||
width,
|
||||
self.blocks.len(),
|
||||
)
|
||||
|
|
|
@ -95,9 +95,7 @@ impl<'tcx> PlaceTy<'tcx> {
|
|||
ProjectionElem::Subslice { from, to, from_end } => {
|
||||
PlaceTy::from_ty(match self.ty.kind() {
|
||||
ty::Slice(..) => self.ty,
|
||||
ty::Array(inner, _) if !from_end => {
|
||||
Ty::new_array(tcx, *inner, (to - from) as u64)
|
||||
}
|
||||
ty::Array(inner, _) if !from_end => Ty::new_array(tcx, *inner, to - from),
|
||||
ty::Array(inner, size) if from_end => {
|
||||
let size = size.eval_target_usize(tcx, param_env);
|
||||
let len = size - from - to;
|
||||
|
|
|
@ -567,7 +567,7 @@ rustc_queries! {
|
|||
separate_provide_extern
|
||||
}
|
||||
|
||||
query check_coroutine_obligations(key: LocalDefId) {
|
||||
query check_coroutine_obligations(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
|
||||
desc { |tcx| "verify auto trait bounds for coroutine interior type `{}`", tcx.def_path_str(key) }
|
||||
}
|
||||
|
||||
|
|
|
@ -1582,6 +1582,8 @@ options! {
|
|||
"version of DWARF debug information to emit (default: 2 or 4, depending on platform)"),
|
||||
dylib_lto: bool = (false, parse_bool, [UNTRACKED],
|
||||
"enables LTO for dylib crate type"),
|
||||
ehcont_guard: bool = (false, parse_bool, [TRACKED],
|
||||
"generate Windows EHCont Guard tables"),
|
||||
emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED],
|
||||
"emit a section containing stack size metadata (default: no)"),
|
||||
emit_thin_lto: bool = (true, parse_bool, [TRACKED],
|
||||
|
|
|
@ -7,12 +7,14 @@
|
|||
use crate::rustc_smir::Tables;
|
||||
use rustc_middle::ty::{self as rustc_ty, Ty as InternalTy};
|
||||
use rustc_span::Symbol;
|
||||
use stable_mir::mir::alloc::AllocId;
|
||||
use stable_mir::mir::mono::{Instance, MonoItem, StaticDef};
|
||||
use stable_mir::ty::{
|
||||
AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, Const, FloatTy,
|
||||
GenericArgKind, GenericArgs, IntTy, Region, RigidTy, TraitRef, Ty, UintTy,
|
||||
AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, Const,
|
||||
ExistentialTraitRef, FloatTy, GenericArgKind, GenericArgs, IntTy, Region, RigidTy, TraitRef,
|
||||
Ty, UintTy,
|
||||
};
|
||||
use stable_mir::{AllocId, CrateItem, DefId};
|
||||
use stable_mir::{CrateItem, DefId};
|
||||
|
||||
use super::RustcInternal;
|
||||
|
||||
|
@ -228,6 +230,17 @@ impl<'tcx> RustcInternal<'tcx> for BoundVariableKind {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> RustcInternal<'tcx> for ExistentialTraitRef {
|
||||
type T = rustc_ty::ExistentialTraitRef<'tcx>;
|
||||
|
||||
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
|
||||
rustc_ty::ExistentialTraitRef {
|
||||
def_id: self.def_id.0.internal(tables),
|
||||
args: self.generic_args.internal(tables),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> RustcInternal<'tcx> for TraitRef {
|
||||
type T = rustc_ty::TraitRef<'tcx>;
|
||||
|
||||
|
@ -276,3 +289,13 @@ where
|
|||
(*self).internal(tables)
|
||||
}
|
||||
}
|
||||
impl<'tcx, T> RustcInternal<'tcx> for Option<T>
|
||||
where
|
||||
T: RustcInternal<'tcx>,
|
||||
{
|
||||
type T = Option<T::T>;
|
||||
|
||||
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
|
||||
self.as_ref().map(|inner| inner.internal(tables))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ impl<'tcx> Tables<'tcx> {
|
|||
self.def_ids.create_or_fetch(did)
|
||||
}
|
||||
|
||||
fn create_alloc_id(&mut self, aid: AllocId) -> stable_mir::AllocId {
|
||||
pub(crate) fn create_alloc_id(&mut self, aid: AllocId) -> stable_mir::mir::alloc::AllocId {
|
||||
self.alloc_ids.create_or_fetch(aid)
|
||||
}
|
||||
|
||||
|
|
|
@ -17,15 +17,16 @@ use rustc_middle::mir::mono::MonoItem;
|
|||
use rustc_middle::ty::{self, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, Variance};
|
||||
use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||
use rustc_target::abi::FieldIdx;
|
||||
use stable_mir::mir::mono::InstanceDef;
|
||||
use stable_mir::mir::alloc::GlobalAlloc;
|
||||
use stable_mir::mir::mono::{InstanceDef, StaticDef};
|
||||
use stable_mir::mir::{
|
||||
Body, ConstOperand, CopyNonOverlapping, Statement, UserTypeProjection, VarDebugInfoFragment,
|
||||
VariantIdx,
|
||||
};
|
||||
use stable_mir::ty::{
|
||||
AdtDef, AdtKind, ClosureDef, ClosureKind, Const, ConstId, ConstantKind, EarlyParamRegion,
|
||||
FloatTy, FnDef, GenericArgs, GenericParamDef, IntTy, LineInfo, Movability, RigidTy, Span,
|
||||
TyKind, UintTy,
|
||||
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, ConstId, ConstantKind,
|
||||
EarlyParamRegion, FloatTy, FnDef, GenericArgs, GenericParamDef, IntTy, LineInfo, Movability,
|
||||
RigidTy, Span, TyKind, UintTy,
|
||||
};
|
||||
use stable_mir::{self, opaque, Context, CrateItem, Error, Filename, ItemKind};
|
||||
use std::cell::RefCell;
|
||||
|
@ -318,6 +319,30 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
|
|||
.ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64")))
|
||||
}
|
||||
|
||||
fn eval_static_initializer(&self, def: StaticDef) -> Result<Allocation, Error> {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let def_id = def.0.internal(&mut *tables);
|
||||
tables.tcx.eval_static_initializer(def_id).stable(&mut *tables)
|
||||
}
|
||||
|
||||
fn global_alloc(&self, alloc: stable_mir::mir::alloc::AllocId) -> GlobalAlloc {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let alloc_id = alloc.internal(&mut *tables);
|
||||
tables.tcx.global_alloc(alloc_id).stable(&mut *tables)
|
||||
}
|
||||
|
||||
fn vtable_allocation(
|
||||
&self,
|
||||
global_alloc: &GlobalAlloc,
|
||||
) -> Option<stable_mir::mir::alloc::AllocId> {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let GlobalAlloc::VTable(ty, trait_ref) = global_alloc else { return None };
|
||||
let alloc_id = tables
|
||||
.tcx
|
||||
.vtable_allocation((ty.internal(&mut *tables), trait_ref.internal(&mut *tables)));
|
||||
Some(alloc_id.stable(&mut *tables))
|
||||
}
|
||||
|
||||
fn usize_to_const(&self, val: u64) -> Result<Const, Error> {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let ty = tables.tcx.types.usize;
|
||||
|
@ -342,7 +367,7 @@ pub(crate) struct TablesWrapper<'tcx>(pub(crate) RefCell<Tables<'tcx>>);
|
|||
pub struct Tables<'tcx> {
|
||||
pub(crate) tcx: TyCtxt<'tcx>,
|
||||
pub(crate) def_ids: IndexMap<DefId, stable_mir::DefId>,
|
||||
pub(crate) alloc_ids: IndexMap<AllocId, stable_mir::AllocId>,
|
||||
pub(crate) alloc_ids: IndexMap<AllocId, stable_mir::mir::alloc::AllocId>,
|
||||
pub(crate) spans: IndexMap<rustc_span::Span, Span>,
|
||||
pub(crate) types: IndexMap<Ty<'tcx>, stable_mir::ty::Ty>,
|
||||
pub(crate) instances: IndexMap<ty::Instance<'tcx>, InstanceDef>,
|
||||
|
@ -1590,6 +1615,14 @@ impl<'tcx> Stable<'tcx> for ty::BoundTy {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::interpret::ConstAllocation<'tcx> {
|
||||
type T = Allocation;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
|
||||
self.inner().stable(tables)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
|
||||
type T = stable_mir::ty::Allocation;
|
||||
|
||||
|
@ -1602,6 +1635,32 @@ impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::interpret::AllocId {
|
||||
type T = stable_mir::mir::alloc::AllocId;
|
||||
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
|
||||
tables.create_alloc_id(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> {
|
||||
type T = GlobalAlloc;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
|
||||
match self {
|
||||
mir::interpret::GlobalAlloc::Function(instance) => {
|
||||
GlobalAlloc::Function(instance.stable(tables))
|
||||
}
|
||||
mir::interpret::GlobalAlloc::VTable(ty, trait_ref) => {
|
||||
GlobalAlloc::VTable(ty.stable(tables), trait_ref.stable(tables))
|
||||
}
|
||||
mir::interpret::GlobalAlloc::Static(def) => {
|
||||
GlobalAlloc::Static(tables.static_def(*def))
|
||||
}
|
||||
mir::interpret::GlobalAlloc::Memory(alloc) => GlobalAlloc::Memory(alloc.stable(tables)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for ty::trait_def::TraitSpecializationKind {
|
||||
type T = stable_mir::ty::TraitSpecializationKind;
|
||||
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
|
||||
|
@ -1989,6 +2048,14 @@ impl<'tcx> Stable<'tcx> for MonoItem<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::interpret::ErrorHandled {
|
||||
type T = Error;
|
||||
|
||||
fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
|
||||
Error::new(format!("{self:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T> Stable<'tcx> for &T
|
||||
where
|
||||
T: Stable<'tcx>,
|
||||
|
@ -2010,3 +2077,18 @@ where
|
|||
self.as_ref().map(|value| value.stable(tables))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T, E> Stable<'tcx> for Result<T, E>
|
||||
where
|
||||
T: Stable<'tcx>,
|
||||
E: Stable<'tcx>,
|
||||
{
|
||||
type T = Result<T::T, E::T>;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
|
||||
match self {
|
||||
Ok(val) => Ok(val.stable(tables)),
|
||||
Err(error) => Err(error.stable(tables)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -189,7 +189,7 @@ impl<'tcx> SymbolMangler<'tcx> {
|
|||
self.push("N");
|
||||
self.out.push(ns);
|
||||
print_prefix(self)?;
|
||||
self.push_disambiguator(disambiguator as u64);
|
||||
self.push_disambiguator(disambiguator);
|
||||
self.push_ident(name);
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
//! The goal is to eventually be published on
|
||||
//! [crates.io](https://crates.io).
|
||||
|
||||
use crate::mir::mono::InstanceDef;
|
||||
use crate::mir::mono::{InstanceDef, StaticDef};
|
||||
use crate::mir::Body;
|
||||
use std::fmt;
|
||||
use std::fmt::Debug;
|
||||
|
@ -37,9 +37,10 @@ pub mod mir;
|
|||
pub mod ty;
|
||||
pub mod visitor;
|
||||
|
||||
use crate::mir::alloc::{AllocId, GlobalAlloc};
|
||||
use crate::mir::pretty::function_name;
|
||||
use crate::mir::Mutability;
|
||||
use crate::ty::{AdtDef, AdtKind, ClosureDef, ClosureKind, Const, RigidTy};
|
||||
use crate::ty::{AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, RigidTy};
|
||||
pub use error::*;
|
||||
use mir::mono::Instance;
|
||||
use ty::{FnDef, GenericArgs};
|
||||
|
@ -73,19 +74,6 @@ impl IndexedVal for DefId {
|
|||
}
|
||||
}
|
||||
|
||||
/// A unique identification number for each provenance
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct AllocId(usize);
|
||||
|
||||
impl IndexedVal for AllocId {
|
||||
fn to_val(index: usize) -> Self {
|
||||
AllocId(index)
|
||||
}
|
||||
fn to_index(&self) -> usize {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// A list of crate items.
|
||||
pub type CrateItems = Vec<CrateItem>;
|
||||
|
||||
|
@ -141,6 +129,10 @@ impl CrateItem {
|
|||
with(|cx| cx.def_ty(self.0))
|
||||
}
|
||||
|
||||
pub fn is_foreign_item(&self) -> bool {
|
||||
with(|cx| cx.is_foreign_item(*self))
|
||||
}
|
||||
|
||||
pub fn dump<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
|
||||
writeln!(w, "{}", function_name(*self))?;
|
||||
self.body().dump(w)
|
||||
|
@ -190,6 +182,8 @@ pub fn trait_impl(trait_impl: &ImplDef) -> ImplTrait {
|
|||
with(|cx| cx.trait_impl(trait_impl))
|
||||
}
|
||||
|
||||
/// This trait defines the interface between stable_mir and the Rust compiler.
|
||||
/// Do not use this directly.
|
||||
pub trait Context {
|
||||
fn entry_fn(&self) -> Option<CrateItem>;
|
||||
/// Retrieve all items of the local crate that have a MIR associated with them.
|
||||
|
@ -291,6 +285,15 @@ pub trait Context {
|
|||
args: &GenericArgs,
|
||||
kind: ClosureKind,
|
||||
) -> Option<Instance>;
|
||||
|
||||
/// Evaluate a static's initializer.
|
||||
fn eval_static_initializer(&self, def: StaticDef) -> Result<Allocation, Error>;
|
||||
|
||||
/// Retrieve global allocation for the given allocation ID.
|
||||
fn global_alloc(&self, id: AllocId) -> GlobalAlloc;
|
||||
|
||||
/// Retrieve the id for the virtual table.
|
||||
fn vtable_allocation(&self, global_alloc: &GlobalAlloc) -> Option<AllocId>;
|
||||
}
|
||||
|
||||
// A thread local variable that stores a pointer to the tables mapping between TyCtxt
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
pub mod alloc;
|
||||
mod body;
|
||||
pub mod mono;
|
||||
pub mod pretty;
|
||||
|
|
51
compiler/stable_mir/src/mir/alloc.rs
Normal file
51
compiler/stable_mir/src/mir/alloc.rs
Normal file
|
@ -0,0 +1,51 @@
|
|||
//! This module provides methods to retrieve allocation information, such as static variables.
|
||||
use crate::mir::mono::{Instance, StaticDef};
|
||||
use crate::ty::{Allocation, Binder, ExistentialTraitRef, IndexedVal, Ty};
|
||||
use crate::with;
|
||||
|
||||
/// An allocation in the SMIR global memory can be either a function pointer,
|
||||
/// a static, or a "real" allocation with some data in it.
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub enum GlobalAlloc {
|
||||
/// The alloc ID is used as a function pointer.
|
||||
Function(Instance),
|
||||
/// This alloc ID points to a symbolic (not-reified) vtable.
|
||||
/// The `None` trait ref is used to represent auto traits.
|
||||
VTable(Ty, Option<Binder<ExistentialTraitRef>>),
|
||||
/// The alloc ID points to a "lazy" static variable that did not get computed (yet).
|
||||
/// This is also used to break the cycle in recursive statics.
|
||||
Static(StaticDef),
|
||||
/// The alloc ID points to memory.
|
||||
Memory(Allocation),
|
||||
}
|
||||
|
||||
impl From<AllocId> for GlobalAlloc {
|
||||
fn from(value: AllocId) -> Self {
|
||||
with(|cx| cx.global_alloc(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl GlobalAlloc {
|
||||
/// Retrieve the allocation id for a global allocation if it exists.
|
||||
///
|
||||
/// For `[GlobalAlloc::VTable]`, this will return the allocation for the VTable of the given
|
||||
/// type for the optional trait if the type implements the trait.
|
||||
///
|
||||
/// This method will always return `None` for allocations other than `[GlobalAlloc::VTable]`.
|
||||
pub fn vtable_allocation(&self) -> Option<AllocId> {
|
||||
with(|cx| cx.vtable_allocation(self))
|
||||
}
|
||||
}
|
||||
|
||||
/// A unique identification number for each provenance
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct AllocId(usize);
|
||||
|
||||
impl IndexedVal for AllocId {
|
||||
fn to_val(index: usize) -> Self {
|
||||
AllocId(index)
|
||||
}
|
||||
fn to_index(&self) -> usize {
|
||||
self.0
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
use crate::mir::Body;
|
||||
use crate::ty::{ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty};
|
||||
use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty};
|
||||
use crate::{with, CrateItem, DefId, Error, ItemKind, Opaque};
|
||||
use std::fmt::{Debug, Formatter};
|
||||
|
||||
|
@ -37,6 +37,11 @@ impl Instance {
|
|||
with(|context| context.instance_body(self.def))
|
||||
}
|
||||
|
||||
pub fn is_foreign_item(&self) -> bool {
|
||||
let item = CrateItem::try_from(*self);
|
||||
item.as_ref().map_or(false, CrateItem::is_foreign_item)
|
||||
}
|
||||
|
||||
/// Get the instance type with generic substitutions applied and lifetimes erased.
|
||||
pub fn ty(&self) -> Ty {
|
||||
with(|context| context.instance_ty(self.def))
|
||||
|
@ -128,6 +133,18 @@ impl From<Instance> for MonoItem {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<StaticDef> for MonoItem {
|
||||
fn from(value: StaticDef) -> Self {
|
||||
MonoItem::Static(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<StaticDef> for CrateItem {
|
||||
fn from(value: StaticDef) -> Self {
|
||||
CrateItem(value.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct InstanceDef(usize);
|
||||
|
||||
|
@ -147,9 +164,15 @@ impl TryFrom<CrateItem> for StaticDef {
|
|||
}
|
||||
|
||||
impl StaticDef {
|
||||
/// Return the type of this static definition.
|
||||
pub fn ty(&self) -> Ty {
|
||||
with(|cx| cx.def_ty(self.0))
|
||||
}
|
||||
|
||||
/// Evaluate a static's initializer, returning the allocation of the initializer's memory.
|
||||
pub fn eval_initializer(&self) -> Result<Allocation, Error> {
|
||||
with(|cx| cx.eval_static_initializer(*self))
|
||||
}
|
||||
}
|
||||
|
||||
impl IndexedVal for InstanceDef {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use super::{
|
||||
mir::Safety,
|
||||
mir::{Body, Mutability},
|
||||
with, AllocId, DefId, Error, Symbol,
|
||||
with, DefId, Error, Symbol,
|
||||
};
|
||||
use crate::mir::alloc::AllocId;
|
||||
use crate::{Filename, Opaque};
|
||||
use std::fmt::{self, Debug, Display, Formatter};
|
||||
|
||||
|
|
|
@ -686,6 +686,10 @@ change-id = 116881
|
|||
# This only applies from stage 1 onwards, and only for Windows targets.
|
||||
#control-flow-guard = false
|
||||
|
||||
# Enable Windows EHCont Guard checks in the standard library.
|
||||
# This only applies from stage 1 onwards, and only for Windows targets.
|
||||
#ehcont-guard = false
|
||||
|
||||
# Enable symbol-mangling-version v0. This can be helpful when profiling rustc,
|
||||
# as generics will be preserved in symbols (rather than erased into opaque T).
|
||||
# When no setting is given, the new scheme will be used when compiling the
|
||||
|
|
|
@ -1964,6 +1964,16 @@ impl<'a> Builder<'a> {
|
|||
rustflags.arg("-Ccontrol-flow-guard");
|
||||
}
|
||||
|
||||
// If EHCont Guard is enabled, pass the `-Zehcont-guard` flag to rustc when compiling the
|
||||
// standard library, since this might be linked into the final outputs produced by rustc.
|
||||
// Since this mitigation is only available on Windows, only enable it for the standard
|
||||
// library in case the compiler is run on a non-Windows platform.
|
||||
// This is not needed for stage 0 artifacts because these will only be used for building
|
||||
// the stage 1 compiler.
|
||||
if cfg!(windows) && mode == Mode::Std && self.config.ehcont_guard && compiler.stage >= 1 {
|
||||
rustflags.arg("-Zehcont-guard");
|
||||
}
|
||||
|
||||
// For `cargo doc` invocations, make rustdoc print the Rust version into the docs
|
||||
// This replaces spaces with tabs because RUSTDOCFLAGS does not
|
||||
// support arguments with regular spaces. Hopefully someday Cargo will
|
||||
|
|
|
@ -248,6 +248,7 @@ pub struct Config {
|
|||
pub local_rebuild: bool,
|
||||
pub jemalloc: bool,
|
||||
pub control_flow_guard: bool,
|
||||
pub ehcont_guard: bool,
|
||||
|
||||
// dist misc
|
||||
pub dist_sign_folder: Option<PathBuf>,
|
||||
|
@ -1019,6 +1020,7 @@ define_config! {
|
|||
test_compare_mode: Option<bool> = "test-compare-mode",
|
||||
llvm_libunwind: Option<String> = "llvm-libunwind",
|
||||
control_flow_guard: Option<bool> = "control-flow-guard",
|
||||
ehcont_guard: Option<bool> = "ehcont-guard",
|
||||
new_symbol_mangling: Option<bool> = "new-symbol-mangling",
|
||||
profile_generate: Option<String> = "profile-generate",
|
||||
profile_use: Option<String> = "profile-use",
|
||||
|
@ -1452,6 +1454,7 @@ impl Config {
|
|||
config.rust_thin_lto_import_instr_limit = rust.thin_lto_import_instr_limit;
|
||||
set(&mut config.rust_remap_debuginfo, rust.remap_debuginfo);
|
||||
set(&mut config.control_flow_guard, rust.control_flow_guard);
|
||||
set(&mut config.ehcont_guard, rust.ehcont_guard);
|
||||
config.llvm_libunwind_default = rust
|
||||
.llvm_libunwind
|
||||
.map(|v| v.parse().expect("failed to parse rust.llvm-libunwind"));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use super::*;
|
||||
use crate::core::config::{Config, DryRun, TargetSelection};
|
||||
use crate::core::build_steps::doc::DocumentationFormat;
|
||||
use crate::core::config::{Config, DryRun, TargetSelection};
|
||||
use std::thread;
|
||||
|
||||
fn configure(cmd: &str, host: &[&str], target: &[&str]) -> Config {
|
||||
|
|
|
@ -26,5 +26,5 @@ ENV \
|
|||
|
||||
ENV HOSTS=powerpc64-unknown-linux-gnu
|
||||
|
||||
ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
|
||||
ENV RUST_CONFIGURE_ARGS --enable-extended --enable-profiler --disable-docs
|
||||
ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS
|
||||
|
|
10
tests/codegen/ehcontguard_disabled.rs
Normal file
10
tests/codegen/ehcontguard_disabled.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
// compile-flags:
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// A basic test function.
|
||||
pub fn test() {
|
||||
}
|
||||
|
||||
// Ensure the module flag ehcontguard is not present
|
||||
// CHECK-NOT: !"ehcontguard"
|
10
tests/codegen/ehcontguard_enabled.rs
Normal file
10
tests/codegen/ehcontguard_enabled.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
// compile-flags: -Z ehcont-guard
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// A basic test function.
|
||||
pub fn test() {
|
||||
}
|
||||
|
||||
// Ensure the module flag ehcontguard=1 is present
|
||||
// CHECK: !"ehcontguard", i32 1
|
119
tests/ui-fulldeps/stable-mir/check_allocation.rs
Normal file
119
tests/ui-fulldeps/stable-mir/check_allocation.rs
Normal file
|
@ -0,0 +1,119 @@
|
|||
// run-pass
|
||||
//! Test that users are able to use stable mir APIs to retrieve information of global allocations
|
||||
//! such as `vtable_allocation`.
|
||||
|
||||
// ignore-stage1
|
||||
// ignore-cross-compile
|
||||
// ignore-remote
|
||||
// ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
|
||||
// edition: 2021
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(ascii_char, ascii_char_variants)]
|
||||
|
||||
extern crate rustc_hir;
|
||||
extern crate rustc_middle;
|
||||
#[macro_use]
|
||||
extern crate rustc_smir;
|
||||
extern crate rustc_driver;
|
||||
extern crate rustc_interface;
|
||||
extern crate stable_mir;
|
||||
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_smir::rustc_internal;
|
||||
use stable_mir::{CrateItem, CrateItems, ItemKind};
|
||||
use stable_mir::mir::alloc::GlobalAlloc;
|
||||
use stable_mir::mir::mono::StaticDef;
|
||||
use std::ascii::Char;
|
||||
use std::assert_matches::assert_matches;
|
||||
use std::io::Write;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
const CRATE_NAME: &str = "input";
|
||||
|
||||
/// This function uses the Stable MIR APIs to get information about the test crate.
|
||||
fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
|
||||
// Find items in the local crate.
|
||||
let items = stable_mir::all_local_items();
|
||||
check_foo(*get_item(&items, (ItemKind::Static, "FOO")).unwrap());
|
||||
check_bar(*get_item(&items, (ItemKind::Static, "BAR")).unwrap());
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
|
||||
/// Check the allocation data for static `FOO`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// static FOO: [&str; 2] = ["hi", "there"];
|
||||
/// ```
|
||||
fn check_foo(item: CrateItem) {
|
||||
let def = StaticDef::try_from(item).unwrap();
|
||||
let alloc = def.eval_initializer().unwrap();
|
||||
assert_eq!(alloc.provenance.ptrs.len(), 2);
|
||||
|
||||
let alloc_id_0 = alloc.provenance.ptrs[0].1.0;
|
||||
assert_matches!(GlobalAlloc::from(alloc_id_0), GlobalAlloc::Memory(..));
|
||||
|
||||
let alloc_id_1 = alloc.provenance.ptrs[1].1.0;
|
||||
assert_matches!(GlobalAlloc::from(alloc_id_1), GlobalAlloc::Memory(..));
|
||||
}
|
||||
|
||||
/// Check the allocation data for static `BAR`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// static BAR: &str = "Bar";
|
||||
/// ```
|
||||
fn check_bar(item: CrateItem) {
|
||||
let def = StaticDef::try_from(item).unwrap();
|
||||
let alloc = def.eval_initializer().unwrap();
|
||||
assert_eq!(alloc.provenance.ptrs.len(), 1);
|
||||
|
||||
let alloc_id_0 = alloc.provenance.ptrs[0].1.0;
|
||||
let GlobalAlloc::Memory(allocation) = GlobalAlloc::from(alloc_id_0) else { unreachable!() };
|
||||
assert_eq!(allocation.bytes.len(), 3);
|
||||
assert_eq!(allocation.bytes[0].unwrap(), Char::CapitalB.to_u8());
|
||||
assert_eq!(allocation.bytes[1].unwrap(), Char::SmallA.to_u8());
|
||||
assert_eq!(allocation.bytes[2].unwrap(), Char::SmallR.to_u8());
|
||||
}
|
||||
|
||||
// Use internal API to find a function in a crate.
|
||||
fn get_item<'a>(
|
||||
items: &'a CrateItems,
|
||||
item: (ItemKind, &str),
|
||||
) -> Option<&'a stable_mir::CrateItem> {
|
||||
items.iter().find(|crate_item| {
|
||||
(item.0 == crate_item.kind()) && crate_item.name() == item.1
|
||||
})
|
||||
}
|
||||
|
||||
/// This test will generate and analyze a dummy crate using the stable mir.
|
||||
/// For that, it will first write the dummy crate into a file.
|
||||
/// Then it will create a `StableMir` using custom arguments and then
|
||||
/// it will run the compiler.
|
||||
fn main() {
|
||||
let path = "alloc_input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
"rustc".to_string(),
|
||||
"--crate-name".to_string(),
|
||||
CRATE_NAME.to_string(),
|
||||
path.to_string(),
|
||||
];
|
||||
run!(args, tcx, test_stable_mir(tcx)).unwrap();
|
||||
}
|
||||
|
||||
fn generate_input(path: &str) -> std::io::Result<()> {
|
||||
let mut file = std::fs::File::create(path)?;
|
||||
write!(
|
||||
file,
|
||||
r#"
|
||||
static FOO: [&str; 2] = ["hi", "there"];
|
||||
static BAR: &str = "Bar";
|
||||
|
||||
pub fn main() {{
|
||||
println!("{{FOO:?}}! {{BAR}}");
|
||||
}}"#
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
17
tests/ui/coroutine/clone-rpit.rs
Normal file
17
tests/ui/coroutine/clone-rpit.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
// revisions: current next
|
||||
//[next] compile-flags: -Ztrait-solver=next
|
||||
// check-pass
|
||||
|
||||
#![feature(coroutines, coroutine_trait, coroutine_clone)]
|
||||
|
||||
// This stalls the goal `{coroutine} <: impl Clone`, since that has a nested goal
|
||||
// of `{coroutine}: Clone`. That is only known if we can compute the generator
|
||||
// witness types, which we don't know until after borrowck. When we later check
|
||||
// the goal for correctness, we want to be able to bind the `impl Clone` opaque.
|
||||
pub fn foo<'a, 'b>() -> impl Clone {
|
||||
move |_: ()| {
|
||||
let () = yield ();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Add table
Reference in a new issue