Closed
Description
Valgrind reports use of uninitialized memory in the following program, which was reduced from tokio-rs/tokio-timer#36 and alexcrichton/futures-await#47.
// main.rs
#![feature(conservative_impl_trait, generators, generator_trait)]
pub type Poll<T, E> = Result<Async<T>, E>;
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Async<T> {
Ready(T),
NotReady,
}
pub trait Future {
type Item;
type Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error>;
}
impl<F, T, E> Future for Option<F> where F: Future<Item=T, Error=E> {
type Item = Option<T>;
type Error = E;
fn poll(&mut self) -> Poll<Option<T>, E> {
match *self {
None => Ok(Async::Ready(None)),
Some(ref mut x) => match x.poll() {
Ok(Async::Ready(t)) => Ok(Async::Ready(Some(t))),
Ok(Async::NotReady) => Ok(Async::NotReady),
Err(e) => Err(e),
}
}
}
}
pub mod __rt {
pub use std::ops::Generator;
use super::Poll;
use super::{Future, Async};
use std::ops::GeneratorState;
pub trait MyFuture<T: IsResult>: Future<Item=T::Ok, Error = T::Err> {}
impl<F, T> MyFuture<T> for F
where F: Future<Item = T::Ok, Error = T::Err > + ?Sized,
T: IsResult
{}
pub trait IsResult {
type Ok;
type Err;
fn into_result(self) -> Result<Self::Ok, Self::Err>;
}
impl<T, E> IsResult for Result<T, E> {
type Ok = T;
type Err = E;
fn into_result(self) -> Result<Self::Ok, Self::Err> { self }
}
pub struct GenFuture<T>(pub T);
pub enum Mu {}
impl<T> Future for GenFuture<T>
where T: Generator<Yield = Async<Mu>>,
T::Return: IsResult,
{
type Item = <T::Return as IsResult>::Ok;
type Error = <T::Return as IsResult>::Err;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
match self.0.resume() {
GeneratorState::Yielded(Async::NotReady)
=> Ok(Async::NotReady),
GeneratorState::Yielded(Async::Ready(mu))
=> match mu {},
GeneratorState::Complete(e)
=> e.into_result().map(Async::Ready),
}
}
}
}
pub struct Foo {
_a: Option<usize>,
_b: Option<String>,
}
fn ola() -> impl __rt::MyFuture<Result<(), String>> + 'static {
__rt::GenFuture(move || -> Result<(), String> {
let _f = Foo { _a: None, _b: None };
yield Async::NotReady;
return Ok(());
})
}
fn main() {
let ft = ola();
let _ = Some(ft).poll();
}
$ rustc -v -V
rustc 1.25.0-nightly (6828cf901 2018-01-06)
binary: rustc
commit-hash: 6828cf90146c7fefc4ba4f16dffe75f763f2d910
commit-date: 2018-01-06
host: x86_64-unknown-linux-gnu
release: 1.25.0-nightly
LLVM version: 4.0
$ rustc main.rs
$ valgrind ./main
==2217== Memcheck, a memory error detector
==2217== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2217== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==2217== Command: ./main
==2217==
==2217== Conditional jump or move depends on uninitialised value(s)
==2217== at 0x10FAF4: <core::option::Option<F> as main::Future>::poll (in /home/dwrensha/Desktop/main)
==2217== by 0x10F59A: main::main (in /home/dwrensha/Desktop/main)
==2217== by 0x10F7E2: std::rt::lang_start::{{closure}} (in /home/dwrensha/Desktop/main)
==2217== by 0x119E17: {{closure}} (rt.rs:59)
==2217== by 0x119E17: _ZN3std9panicking3try7do_call17hffb5315d0c0f678dE.llvm.3A805FA6 (panicking.rs:480)
==2217== by 0x123D9E: __rust_maybe_catch_panic (lib.rs:102)
==2217== by 0x11034F: try<i32,closure> (panicking.rs:459)
==2217== by 0x11034F: catch_unwind<closure,i32> (panic.rs:365)
==2217== by 0x11034F: std::rt::lang_start_internal (rt.rs:58)
==2217== by 0x10F7C6: std::rt::lang_start (in /home/dwrensha/Desktop/main)
==2217== by 0x10F62D: main (in /home/dwrensha/Desktop/main)
==2217==
==2217== Conditional jump or move depends on uninitialised value(s)
==2217== at 0x10FB06: <core::option::Option<F> as main::Future>::poll (in /home/dwrensha/Desktop/main)
==2217== by 0x10F59A: main::main (in /home/dwrensha/Desktop/main)
==2217== by 0x10F7E2: std::rt::lang_start::{{closure}} (in /home/dwrensha/Desktop/main)
==2217== by 0x119E17: {{closure}} (rt.rs:59)
==2217== by 0x119E17: _ZN3std9panicking3try7do_call17hffb5315d0c0f678dE.llvm.3A805FA6 (panicking.rs:480)
==2217== by 0x123D9E: __rust_maybe_catch_panic (lib.rs:102)
==2217== by 0x11034F: try<i32,closure> (panicking.rs:459)
==2217== by 0x11034F: catch_unwind<closure,i32> (panic.rs:365)
==2217== by 0x11034F: std::rt::lang_start_internal (rt.rs:58)
==2217== by 0x10F7C6: std::rt::lang_start (in /home/dwrensha/Desktop/main)
==2217== by 0x10F62D: main (in /home/dwrensha/Desktop/main)
==2217==
==2217==
==2217== HEAP SUMMARY:
==2217== in use at exit: 0 bytes in 0 blocks
==2217== total heap usage: 6 allocs, 6 frees, 2,000 bytes allocated
==2217==
==2217== All heap blocks were freed -- no leaks are possible
==2217==
==2217== For counts of detected and suppressed errors, rerun with: -v
==2217== Use --track-origins=yes to see where uninitialised values come from
==2217== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Metadata
Metadata
Assignees
Labels
No labels