auto merge of #14234 : alexcrichton/rust/rollup, r=alexcrichton
Let's try this again!
This commit is contained in:
commit
0481d628b8
@ -68,7 +68,7 @@
|
||||
#
|
||||
# * `TESTNAME=...` - Specify the name of tests to run
|
||||
# * `CHECK_IGNORED=1` - Run normally-ignored tests
|
||||
# * `NO_BENCH=1` - Don't run crate benchmarks (disable `--bench` flag)
|
||||
# * `PLEASE_BENCH=1` - Run crate benchmarks (enable `--bench` flag)
|
||||
#
|
||||
# * `CFG_ENABLE_VALGRIND=1` - Run tests under valgrind
|
||||
# * `VALGRIND_COMPILE=1` - Run the compiler itself under valgrind
|
||||
|
@ -51,19 +51,21 @@
|
||||
|
||||
TARGET_CRATES := libc std green rustuv native flate arena glob term semver \
|
||||
uuid serialize sync getopts collections num test time rand \
|
||||
workcache url log regex graphviz core
|
||||
workcache url log regex graphviz core rlibc
|
||||
HOST_CRATES := syntax rustc rustdoc fourcc hexfloat regex_macros fmt_macros
|
||||
CRATES := $(TARGET_CRATES) $(HOST_CRATES)
|
||||
TOOLS := compiletest rustdoc rustc
|
||||
|
||||
DEPS_core :=
|
||||
DEPS_rlibc :=
|
||||
DEPS_std := core libc native:rustrt native:compiler-rt native:backtrace native:jemalloc
|
||||
DEPS_graphviz := std
|
||||
DEPS_green := std rand native:context_switch
|
||||
DEPS_rustuv := std native:uv native:uv_support
|
||||
DEPS_native := std
|
||||
DEPS_syntax := std term serialize collections log fmt_macros
|
||||
DEPS_rustc := syntax native:rustllvm flate arena serialize sync getopts \
|
||||
collections time log
|
||||
collections time log graphviz
|
||||
DEPS_rustdoc := rustc native:hoedown serialize sync getopts collections \
|
||||
test time
|
||||
DEPS_flate := std native:miniz
|
||||
@ -98,6 +100,7 @@ TOOL_SOURCE_rustdoc := $(S)src/driver/driver.rs
|
||||
TOOL_SOURCE_rustc := $(S)src/driver/driver.rs
|
||||
|
||||
ONLY_RLIB_core := 1
|
||||
ONLY_RLIB_rlibc := 1
|
||||
|
||||
################################################################################
|
||||
# You should not need to edit below this line
|
||||
|
12
mk/docs.mk
12
mk/docs.mk
@ -30,7 +30,7 @@ DOCS := index intro tutorial guide-ffi guide-macros guide-lifetimes \
|
||||
guide-tasks guide-container guide-pointers guide-testing \
|
||||
guide-runtime complement-bugreport complement-cheatsheet \
|
||||
complement-lang-faq complement-project-faq rust rustdoc \
|
||||
guide-unsafe not_found
|
||||
guide-unsafe
|
||||
|
||||
PDF_DOCS := tutorial rust
|
||||
|
||||
@ -42,10 +42,11 @@ L10N_LANGS := ja
|
||||
# Generally no need to edit below here.
|
||||
|
||||
# The options are passed to the documentation generators.
|
||||
RUSTDOC_HTML_OPTS = --markdown-css rust.css \
|
||||
--markdown-before-content=doc/version_info.html \
|
||||
RUSTDOC_HTML_OPTS_NO_CSS = --markdown-before-content=doc/version_info.html \
|
||||
--markdown-in-header=doc/favicon.inc --markdown-after-content=doc/footer.inc
|
||||
|
||||
RUSTDOC_HTML_OPTS = $(RUSTDOC_HTML_OPTS_NO_CSS) --markdown-css rust.css
|
||||
|
||||
PANDOC_BASE_OPTS := --standalone --toc --number-sections
|
||||
PANDOC_TEX_OPTS = $(PANDOC_BASE_OPTS) --include-before-body=doc/version.tex \
|
||||
--from=markdown --include-before-body=doc/footer.tex --to=latex
|
||||
@ -152,6 +153,11 @@ doc/footer.tex: $(D)/footer.inc | doc/
|
||||
@$(call E, pandoc: $@)
|
||||
$(CFG_PANDOC) --from=html --to=latex $< --output=$@
|
||||
|
||||
# HTML (rustdoc)
|
||||
DOC_TARGETS += doc/not_found.html
|
||||
doc/not_found.html: $(D)/not_found.md $(HTML_DEPS) | doc/
|
||||
$(RUSTDOC) $(RUSTDOC_HTML_OPTS_NO_CSS) --markdown-css http://static.rust-lang.org/doc/master/rust.css $<
|
||||
|
||||
define DEF_DOC
|
||||
|
||||
# HTML (rustdoc)
|
||||
|
@ -32,7 +32,7 @@ ifdef CHECK_IGNORED
|
||||
TESTARGS += --ignored
|
||||
endif
|
||||
|
||||
TEST_BENCH = --bench
|
||||
TEST_BENCH =
|
||||
|
||||
# Arguments to the cfail/rfail/rpass/bench tests
|
||||
ifdef CFG_VALGRIND
|
||||
@ -40,8 +40,8 @@ ifdef CFG_VALGRIND
|
||||
TEST_BENCH =
|
||||
endif
|
||||
|
||||
ifdef NO_BENCH
|
||||
TEST_BENCH =
|
||||
ifdef PLEASE_BENCH
|
||||
TEST_BENCH = --bench
|
||||
endif
|
||||
|
||||
# Arguments to the perf tests
|
||||
|
@ -1799,6 +1799,8 @@ type int8_t = i8;
|
||||
- `no_start` - disable linking to the `native` crate, which specifies the
|
||||
"start" language item.
|
||||
- `no_std` - disable linking to the `std` crate.
|
||||
- `no_builtins` - disable optimizing certain code patterns to invocations of
|
||||
library functions that are assumed to exist
|
||||
|
||||
### Module-only attributes
|
||||
|
||||
|
@ -186,6 +186,25 @@ impl<'b, T> Deref<T> for Ref<'b, T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy a `Ref`.
|
||||
///
|
||||
/// The `RefCell` is already immutably borrowed, so this cannot fail.
|
||||
///
|
||||
/// A `Clone` implementation would interfere with the widespread
|
||||
/// use of `r.borrow().clone()` to clone the contents of a `RefCell`.
|
||||
#[experimental]
|
||||
pub fn clone_ref<'b, T>(orig: &Ref<'b, T>) -> Ref<'b, T> {
|
||||
// Since this Ref exists, we know the borrow flag
|
||||
// is not set to WRITING.
|
||||
let borrow = orig.parent.borrow.get();
|
||||
debug_assert!(borrow != WRITING && borrow != UNUSED);
|
||||
orig.parent.borrow.set(borrow + 1);
|
||||
|
||||
Ref {
|
||||
parent: orig.parent,
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps a mutable borrowed reference to a value in a `RefCell` box.
|
||||
pub struct RefMut<'b, T> {
|
||||
parent: &'b RefCell<T>
|
||||
@ -307,4 +326,19 @@ mod test {
|
||||
let _ = _b;
|
||||
let _b = x.borrow_mut();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clone_ref_updates_flag() {
|
||||
let x = RefCell::new(0);
|
||||
{
|
||||
let b1 = x.borrow();
|
||||
assert!(x.try_borrow_mut().is_none());
|
||||
{
|
||||
let _b2 = clone_ref(&b1);
|
||||
assert!(x.try_borrow_mut().is_none());
|
||||
}
|
||||
assert!(x.try_borrow_mut().is_none());
|
||||
}
|
||||
assert!(x.try_borrow_mut().is_some());
|
||||
}
|
||||
}
|
||||
|
@ -192,7 +192,23 @@ pub fn max<T: TotalOrd>(v1: T, v2: T) -> T {
|
||||
// Implementation of Eq/TotalEq for some primitive types
|
||||
#[cfg(not(test))]
|
||||
mod impls {
|
||||
use cmp::{Ord, TotalOrd, Eq, TotalEq, Ordering};
|
||||
use cmp::{Ord, TotalOrd, Eq, TotalEq, Ordering, Equal};
|
||||
|
||||
impl Eq for () {
|
||||
#[inline]
|
||||
fn eq(&self, _other: &()) -> bool { true }
|
||||
#[inline]
|
||||
fn ne(&self, _other: &()) -> bool { false }
|
||||
}
|
||||
impl TotalEq for () {}
|
||||
impl Ord for () {
|
||||
#[inline]
|
||||
fn lt(&self, _other: &()) -> bool { false }
|
||||
}
|
||||
impl TotalOrd for () {
|
||||
#[inline]
|
||||
fn cmp(&self, _other: &()) -> Ordering { Equal }
|
||||
}
|
||||
|
||||
// & pointers
|
||||
impl<'a, T: Eq> Eq for &'a T {
|
||||
|
@ -16,6 +16,11 @@ pub trait Default {
|
||||
fn default() -> Self;
|
||||
}
|
||||
|
||||
impl Default for () {
|
||||
#[inline]
|
||||
fn default() -> () { () }
|
||||
}
|
||||
|
||||
impl<T: Default + 'static> Default for @T {
|
||||
fn default() -> @T { @Default::default() }
|
||||
}
|
||||
|
@ -18,6 +18,9 @@
|
||||
//! * `memcpy`, `memcmp`, `memset` - These are core memory routines which are
|
||||
//! often generated by LLVM. Additionally, this library can make explicit
|
||||
//! calls to these funcitons. Their signatures are the same as found in C.
|
||||
//! These functions are often provided by the system libc, but can also be
|
||||
//! provided by `librlibc` which is distributed with the standard rust
|
||||
//! distribution.
|
||||
//!
|
||||
//! * `rust_begin_unwind` - This function takes three arguments, a
|
||||
//! `&fmt::Arguments`, a `&str`, and a `uint. These three arguments dictate
|
||||
@ -100,7 +103,6 @@ pub mod container;
|
||||
/* Core types and methods on primitives */
|
||||
|
||||
mod unicode;
|
||||
mod unit;
|
||||
pub mod any;
|
||||
pub mod atomics;
|
||||
pub mod bool;
|
||||
@ -116,9 +118,6 @@ pub mod slice;
|
||||
pub mod str;
|
||||
pub mod tuple;
|
||||
|
||||
#[cfg(stage0, not(test))]
|
||||
pub mod owned;
|
||||
|
||||
// FIXME: this module should not exist. Once owned allocations are no longer a
|
||||
// language type, this module can move outside to the owned allocation
|
||||
// crate.
|
||||
|
@ -1,101 +0,0 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Operations on unique pointer types
|
||||
|
||||
use any::{Any, AnyRefExt};
|
||||
use clone::Clone;
|
||||
use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering};
|
||||
use default::Default;
|
||||
use intrinsics;
|
||||
use mem;
|
||||
use raw::TraitObject;
|
||||
use result::{Ok, Err, Result};
|
||||
|
||||
/// A value that represents the global exchange heap. This is the default
|
||||
/// place that the `box` keyword allocates into when no place is supplied.
|
||||
///
|
||||
/// The following two examples are equivalent:
|
||||
///
|
||||
/// let foo = box(HEAP) Bar::new(...);
|
||||
/// let foo = box Bar::new(...);
|
||||
#[lang="exchange_heap"]
|
||||
pub static HEAP: () = ();
|
||||
|
||||
/// A type that represents a uniquely-owned value.
|
||||
#[lang="owned_box"]
|
||||
pub struct Box<T>(*T);
|
||||
|
||||
impl<T: Default> Default for Box<T> {
|
||||
fn default() -> Box<T> { box Default::default() }
|
||||
}
|
||||
|
||||
impl<T: Clone> Clone for Box<T> {
|
||||
/// Return a copy of the owned box.
|
||||
#[inline]
|
||||
fn clone(&self) -> Box<T> { box {(**self).clone()} }
|
||||
|
||||
/// Perform copy-assignment from `source` by reusing the existing allocation.
|
||||
#[inline]
|
||||
fn clone_from(&mut self, source: &Box<T>) {
|
||||
(**self).clone_from(&(**source));
|
||||
}
|
||||
}
|
||||
|
||||
// box pointers
|
||||
impl<T:Eq> Eq for Box<T> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Box<T>) -> bool { *(*self) == *(*other) }
|
||||
#[inline]
|
||||
fn ne(&self, other: &Box<T>) -> bool { *(*self) != *(*other) }
|
||||
}
|
||||
impl<T:Ord> Ord for Box<T> {
|
||||
#[inline]
|
||||
fn lt(&self, other: &Box<T>) -> bool { *(*self) < *(*other) }
|
||||
#[inline]
|
||||
fn le(&self, other: &Box<T>) -> bool { *(*self) <= *(*other) }
|
||||
#[inline]
|
||||
fn ge(&self, other: &Box<T>) -> bool { *(*self) >= *(*other) }
|
||||
#[inline]
|
||||
fn gt(&self, other: &Box<T>) -> bool { *(*self) > *(*other) }
|
||||
}
|
||||
impl<T: TotalOrd> TotalOrd for Box<T> {
|
||||
#[inline]
|
||||
fn cmp(&self, other: &Box<T>) -> Ordering { (**self).cmp(*other) }
|
||||
}
|
||||
impl<T: TotalEq> TotalEq for Box<T> {}
|
||||
|
||||
/// Extension methods for an owning `Any` trait object
|
||||
pub trait AnyOwnExt {
|
||||
/// Returns the boxed value if it is of type `T`, or
|
||||
/// `Err(Self)` if it isn't.
|
||||
fn move<T: 'static>(self) -> Result<Box<T>, Self>;
|
||||
}
|
||||
|
||||
impl AnyOwnExt for Box<Any> {
|
||||
#[inline]
|
||||
fn move<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
|
||||
if self.is::<T>() {
|
||||
unsafe {
|
||||
// Get the raw representation of the trait object
|
||||
let to: TraitObject =
|
||||
*mem::transmute::<&Box<Any>, &TraitObject>(&self);
|
||||
|
||||
// Prevent destructor on self being run
|
||||
intrinsics::forget(self);
|
||||
|
||||
// Extract the data pointer
|
||||
Ok(mem::transmute(to.data))
|
||||
}
|
||||
} else {
|
||||
Err(self)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Functions for the unit type.
|
||||
|
||||
#[cfg(not(test))]
|
||||
use default::Default;
|
||||
#[cfg(not(test))]
|
||||
use cmp::{Eq, Equal, Ord, Ordering, TotalEq, TotalOrd};
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl Eq for () {
|
||||
#[inline]
|
||||
fn eq(&self, _other: &()) -> bool { true }
|
||||
#[inline]
|
||||
fn ne(&self, _other: &()) -> bool { false }
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl Ord for () {
|
||||
#[inline]
|
||||
fn lt(&self, _other: &()) -> bool { false }
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl TotalOrd for () {
|
||||
#[inline]
|
||||
fn cmp(&self, _other: &()) -> Ordering { Equal }
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl TotalEq for () {}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl Default for () {
|
||||
#[inline]
|
||||
fn default() -> () { () }
|
||||
}
|
@ -1137,11 +1137,10 @@ mod test {
|
||||
fn test_schedule_home_states() {
|
||||
use sleeper_list::SleeperList;
|
||||
use super::{Shutdown, Scheduler, SchedHandle};
|
||||
use std::unstable::run_in_bare_thread;
|
||||
use std::rt::thread::Thread;
|
||||
use std::sync::deque::BufferPool;
|
||||
|
||||
run_in_bare_thread(proc() {
|
||||
Thread::start(proc() {
|
||||
let sleepers = SleeperList::new();
|
||||
let mut pool = BufferPool::new();
|
||||
let (normal_worker, normal_stealer) = pool.deque();
|
||||
@ -1260,7 +1259,7 @@ mod test {
|
||||
|
||||
normal_thread.join();
|
||||
special_thread.join();
|
||||
});
|
||||
}).join();
|
||||
}
|
||||
|
||||
//#[test]
|
||||
|
@ -493,9 +493,7 @@ fn mkstat(stat: &libc::stat) -> io::FileStat {
|
||||
io::FileStat {
|
||||
size: stat.st_size as u64,
|
||||
kind: kind,
|
||||
perm: unsafe {
|
||||
io::FilePermission::from_bits(stat.st_mode as u32) & io::AllPermissions
|
||||
},
|
||||
perm: io::FilePermission::from_bits_truncate(stat.st_mode as u32),
|
||||
created: mktime(stat.st_ctime as u64, stat.st_ctime_nsec as u64),
|
||||
modified: mktime(stat.st_mtime as u64, stat.st_mtime_nsec as u64),
|
||||
accessed: mktime(stat.st_atime as u64, stat.st_atime_nsec as u64),
|
||||
|
@ -492,9 +492,7 @@ fn mkstat(stat: &libc::stat) -> io::FileStat {
|
||||
io::FileStat {
|
||||
size: stat.st_size as u64,
|
||||
kind: kind,
|
||||
perm: unsafe {
|
||||
io::FilePermission::from_bits(stat.st_mode as u32) & io::AllPermissions
|
||||
},
|
||||
perm: io::FilePermission::from_bits_truncate(stat.st_mode as u32),
|
||||
created: stat.st_ctime as u64,
|
||||
modified: stat.st_mtime as u64,
|
||||
accessed: stat.st_atime as u64,
|
||||
|
99
src/librlibc/lib.rs
Normal file
99
src/librlibc/lib.rs
Normal file
@ -0,0 +1,99 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! A bare-metal library supplying functions rustc may lower code to
|
||||
//!
|
||||
//! This library is not intended for general use, and is superseded by a system
|
||||
//! libc if one is available. In a freestanding context, however, common
|
||||
//! functions such as memset, memcpy, etc are not implemented. This library
|
||||
//! provides an implementation of these functions which are either required by
|
||||
//! libcore or called by rustc implicitly.
|
||||
//!
|
||||
//! This library is never included by default, and must be manually included if
|
||||
//! necessary. It is an error to include this library when also linking with
|
||||
//! the system libc library.
|
||||
|
||||
#![crate_id = "rlibc#0.11.0-pre"]
|
||||
#![license = "MIT/ASL2"]
|
||||
#![crate_type = "rlib"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://static.rust-lang.org/doc/master")]
|
||||
|
||||
#![no_std]
|
||||
#![experimental]
|
||||
|
||||
// This library is definining the builtin functions, so it would be a shame for
|
||||
// LLVM to optimize these function calls to themselves!
|
||||
#![no_builtins]
|
||||
|
||||
#[cfg(test)] extern crate std;
|
||||
#[cfg(test)] extern crate native;
|
||||
|
||||
// Require the offset intrinsics for LLVM to properly optimize the
|
||||
// implementations below. If pointer arithmetic is done through integers the
|
||||
// optimizations start to break down.
|
||||
extern "rust-intrinsic" {
|
||||
fn offset<T>(dst: *T, offset: int) -> *T;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *u8, n: uint) -> *mut u8 {
|
||||
let mut i = 0;
|
||||
while i < n {
|
||||
*(offset(dest as *u8, i as int) as *mut u8) = *offset(src, i as int);
|
||||
i += 1;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn memmove(dest: *mut u8, src: *u8, n: uint) -> *mut u8 {
|
||||
if src < dest as *u8 { // copy from end
|
||||
let mut i = n;
|
||||
while i != 0 {
|
||||
i -= 1;
|
||||
*(offset(dest as *u8, i as int) as *mut u8) = *offset(src, i as int);
|
||||
}
|
||||
} else { // copy from beginning
|
||||
let mut i = 0;
|
||||
while i < n {
|
||||
*(offset(dest as *u8, i as int) as *mut u8) = *offset(src, i as int);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn memset(s: *mut u8, c: i32, n: uint) -> *mut u8 {
|
||||
let mut i = 0;
|
||||
while i < n {
|
||||
*(offset(s as *u8, i as int) as *mut u8) = c as u8;
|
||||
i += 1;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn memcmp(s1: *u8, s2: *u8, n: uint) -> i32 {
|
||||
let mut i = 0;
|
||||
while i < n {
|
||||
let a = *offset(s1, i as int);
|
||||
let b = *offset(s2, i as int);
|
||||
if a != b {
|
||||
return (a - b) as i32
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#[test] fn work_on_windows() { } // FIXME #10872 needed for a happy windows
|
@ -212,7 +212,8 @@ pub mod write {
|
||||
if !sess.opts.cg.no_prepopulate_passes {
|
||||
llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod);
|
||||
llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod);
|
||||
populate_llvm_passes(fpm, mpm, llmod, opt_level);
|
||||
populate_llvm_passes(fpm, mpm, llmod, opt_level,
|
||||
trans.no_builtins);
|
||||
}
|
||||
|
||||
for pass in sess.opts.cg.passes.iter() {
|
||||
@ -264,11 +265,11 @@ pub mod write {
|
||||
// escape the closure itself, and the manager should only be
|
||||
// used once.
|
||||
fn with_codegen(tm: TargetMachineRef, llmod: ModuleRef,
|
||||
f: |PassManagerRef|) {
|
||||
no_builtins: bool, f: |PassManagerRef|) {
|
||||
unsafe {
|
||||
let cpm = llvm::LLVMCreatePassManager();
|
||||
llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod);
|
||||
llvm::LLVMRustAddLibraryInfo(cpm, llmod);
|
||||
llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
|
||||
f(cpm);
|
||||
llvm::LLVMDisposePassManager(cpm);
|
||||
}
|
||||
@ -286,7 +287,7 @@ pub mod write {
|
||||
}
|
||||
OutputTypeLlvmAssembly => {
|
||||
path.with_c_str(|output| {
|
||||
with_codegen(tm, llmod, |cpm| {
|
||||
with_codegen(tm, llmod, trans.no_builtins, |cpm| {
|
||||
llvm::LLVMRustPrintModule(cpm, llmod, output);
|
||||
})
|
||||
})
|
||||
@ -303,7 +304,7 @@ pub mod write {
|
||||
needs_metadata = true;
|
||||
output.temp_path(OutputTypeAssembly)
|
||||
};
|
||||
with_codegen(tm, llmod, |cpm| {
|
||||
with_codegen(tm, llmod, trans.no_builtins, |cpm| {
|
||||
WriteOutputFile(sess, tm, cpm, llmod, &path,
|
||||
lib::llvm::AssemblyFile);
|
||||
});
|
||||
@ -321,7 +322,7 @@ pub mod write {
|
||||
time(sess.time_passes(), "codegen passes", (), |()| {
|
||||
match object_file {
|
||||
Some(ref path) => {
|
||||
with_codegen(tm, llmod, |cpm| {
|
||||
with_codegen(tm, llmod, trans.no_builtins, |cpm| {
|
||||
WriteOutputFile(sess, tm, cpm, llmod, path,
|
||||
lib::llvm::ObjectFile);
|
||||
});
|
||||
@ -329,7 +330,8 @@ pub mod write {
|
||||
None => {}
|
||||
}
|
||||
if needs_metadata {
|
||||
with_codegen(tm, trans.metadata_module, |cpm| {
|
||||
with_codegen(tm, trans.metadata_module,
|
||||
trans.no_builtins, |cpm| {
|
||||
let out = output.temp_path(OutputTypeObject)
|
||||
.with_extension("metadata.o");
|
||||
WriteOutputFile(sess, tm, cpm,
|
||||
@ -437,7 +439,8 @@ pub mod write {
|
||||
unsafe fn populate_llvm_passes(fpm: lib::llvm::PassManagerRef,
|
||||
mpm: lib::llvm::PassManagerRef,
|
||||
llmod: ModuleRef,
|
||||
opt: lib::llvm::CodeGenOptLevel) {
|
||||
opt: lib::llvm::CodeGenOptLevel,
|
||||
no_builtins: bool) {
|
||||
// Create the PassManagerBuilder for LLVM. We configure it with
|
||||
// reasonable defaults and prepare it to actually populate the pass
|
||||
// manager.
|
||||
@ -461,7 +464,7 @@ pub mod write {
|
||||
}
|
||||
}
|
||||
llvm::LLVMPassManagerBuilderSetOptLevel(builder, opt as c_uint);
|
||||
llvm::LLVMRustAddBuilderLibraryInfo(builder, llmod);
|
||||
llvm::LLVMRustAddBuilderLibraryInfo(builder, llmod, no_builtins);
|
||||
|
||||
// Use the builder to populate the function/module pass managers.
|
||||
llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(builder, fpm);
|
||||
|
@ -519,12 +519,13 @@ pub fn optgroups() -> Vec<getopts::OptGroup> {
|
||||
optopt( "", "out-dir", "Write output to compiler-chosen filename in <dir>", "DIR"),
|
||||
optflag("", "parse-only", "Parse only; do not compile, assemble, or link"),
|
||||
optflagopt("", "pretty",
|
||||
"Pretty-print the input instead of compiling;
|
||||
valid types are: normal (un-annotated source),
|
||||
expanded (crates expanded),
|
||||
typed (crates expanded, with type annotations),
|
||||
or identified (fully parenthesized,
|
||||
AST nodes and blocks with IDs)", "TYPE"),
|
||||
"Pretty-print the input instead of compiling;
|
||||
valid types are: `normal` (un-annotated source),
|
||||
`expanded` (crates expanded),
|
||||
`typed` (crates expanded, with type annotations),
|
||||
`expanded,identified` (fully parenthesized, AST nodes with IDs), or
|
||||
`flowgraph=<nodeid>` (graphviz formatted flowgraph for node)",
|
||||
"TYPE"),
|
||||
optflagopt("", "dep-info",
|
||||
"Output dependency info to <filename> after compiling, \
|
||||
in a format suitable for use by Makefiles", "FILENAME"),
|
||||
|
@ -11,12 +11,15 @@
|
||||
|
||||
use back::link;
|
||||
use driver::session::Session;
|
||||
use driver::config;
|
||||
use driver::{config, PpMode};
|
||||
use driver::PpmFlowGraph; // FIXME (#14221).
|
||||
use front;
|
||||
use lib::llvm::{ContextRef, ModuleRef};
|
||||
use metadata::common::LinkMeta;
|
||||
use metadata::creader;
|
||||
use metadata::creader::Loader;
|
||||
use middle::cfg;
|
||||
use middle::cfg::graphviz::LabelledCFG;
|
||||
use middle::{trans, freevars, kind, ty, typeck, lint, reachable};
|
||||
use middle::dependency_format;
|
||||
use middle;
|
||||
@ -24,6 +27,8 @@ use util::common::time;
|
||||
use util::ppaux;
|
||||
use util::nodemap::{NodeSet};
|
||||
|
||||
use dot = graphviz;
|
||||
|
||||
use serialize::{json, Encodable};
|
||||
|
||||
use std::io;
|
||||
@ -356,6 +361,7 @@ pub struct CrateTranslation {
|
||||
pub metadata: Vec<u8>,
|
||||
pub reachable: Vec<StrBuf>,
|
||||
pub crate_formats: dependency_format::Dependencies,
|
||||
pub no_builtins: bool,
|
||||
}
|
||||
|
||||
/// Run the translation phase to LLVM, after which the AST and analysis can
|
||||
@ -581,14 +587,14 @@ impl pprust::PpAnn for TypedAnnotation {
|
||||
pub fn pretty_print_input(sess: Session,
|
||||
cfg: ast::CrateConfig,
|
||||
input: &Input,
|
||||
ppm: ::driver::PpMode,
|
||||
ppm: PpMode,
|
||||
ofile: Option<Path>) {
|
||||
let krate = phase_1_parse_input(&sess, cfg, input);
|
||||
let id = link::find_crate_id(krate.attrs.as_slice(),
|
||||
input.filestem().as_slice());
|
||||
|
||||
let (krate, ast_map, is_expanded) = match ppm {
|
||||
PpmExpanded | PpmExpandedIdentified | PpmTyped => {
|
||||
PpmExpanded | PpmExpandedIdentified | PpmTyped | PpmFlowGraph(_) => {
|
||||
let loader = &mut Loader::new(&sess);
|
||||
let (krate, ast_map) = phase_2_configure_and_expand(&sess,
|
||||
loader,
|
||||
@ -643,6 +649,18 @@ pub fn pretty_print_input(sess: Session,
|
||||
&annotation,
|
||||
is_expanded)
|
||||
}
|
||||
PpmFlowGraph(nodeid) => {
|
||||
let ast_map = ast_map.expect("--pretty flowgraph missing ast_map");
|
||||
let node = ast_map.find(nodeid).unwrap_or_else(|| {
|
||||
fail!("--pretty flowgraph=id couldn't find id: {}", id)
|
||||
});
|
||||
let block = match node {
|
||||
syntax::ast_map::NodeBlock(block) => block,
|
||||
_ => fail!("--pretty=flowgraph needs block, got {:?}", node)
|
||||
};
|
||||
let analysis = phase_3_run_analysis_passes(sess, &krate, ast_map);
|
||||
print_flowgraph(analysis, block, out)
|
||||
}
|
||||
_ => {
|
||||
pprust::print_crate(sess.codemap(),
|
||||
sess.diagnostic(),
|
||||
@ -657,6 +675,32 @@ pub fn pretty_print_input(sess: Session,
|
||||
|
||||
}
|
||||
|
||||
fn print_flowgraph<W:io::Writer>(analysis: CrateAnalysis,
|
||||
block: ast::P<ast::Block>,
|
||||
mut out: W) -> io::IoResult<()> {
|
||||
let ty_cx = &analysis.ty_cx;
|
||||
let cfg = cfg::CFG::new(ty_cx, block);
|
||||
let lcfg = LabelledCFG { ast_map: &ty_cx.map,
|
||||
cfg: &cfg,
|
||||
name: format!("block{}", block.id).to_strbuf(), };
|
||||
debug!("cfg: {:?}", cfg);
|
||||
let r = dot::render(&lcfg, &mut out);
|
||||
return expand_err_details(r);
|
||||
|
||||
fn expand_err_details(r: io::IoResult<()>) -> io::IoResult<()> {
|
||||
r.map_err(|ioerr| {
|
||||
let orig_detail = ioerr.detail.clone();
|
||||
let m = "graphviz::render failed";
|
||||
io::IoError {
|
||||
detail: Some(match orig_detail {
|
||||
None => m.into_owned(), Some(d) => format!("{}: {}", m, d)
|
||||
}),
|
||||
..ioerr
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn collect_crate_types(session: &Session,
|
||||
attrs: &[ast::Attribute]) -> Vec<config::CrateType> {
|
||||
// If we're generating a test executable, then ignore all other output
|
||||
|
@ -285,20 +285,32 @@ pub enum PpMode {
|
||||
PpmExpanded,
|
||||
PpmTyped,
|
||||
PpmIdentified,
|
||||
PpmExpandedIdentified
|
||||
PpmExpandedIdentified,
|
||||
PpmFlowGraph(ast::NodeId),
|
||||
}
|
||||
|
||||
pub fn parse_pretty(sess: &Session, name: &str) -> PpMode {
|
||||
match name {
|
||||
"normal" => PpmNormal,
|
||||
"expanded" => PpmExpanded,
|
||||
"typed" => PpmTyped,
|
||||
"expanded,identified" => PpmExpandedIdentified,
|
||||
"identified" => PpmIdentified,
|
||||
let mut split = name.splitn('=', 1);
|
||||
let first = split.next().unwrap();
|
||||
let opt_second = split.next();
|
||||
match (opt_second, first) {
|
||||
(None, "normal") => PpmNormal,
|
||||
(None, "expanded") => PpmExpanded,
|
||||
(None, "typed") => PpmTyped,
|
||||
(None, "expanded,identified") => PpmExpandedIdentified,
|
||||
(None, "identified") => PpmIdentified,
|
||||
(Some(s), "flowgraph") => {
|
||||
match from_str(s) {
|
||||
Some(id) => PpmFlowGraph(id),
|
||||
None => sess.fatal(format!("`pretty flowgraph=<nodeid>` needs \
|
||||
an integer <nodeid>; got {}", s))
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
sess.fatal("argument to `pretty` must be one of `normal`, \
|
||||
`expanded`, `typed`, `identified`, \
|
||||
or `expanded,identified`");
|
||||
sess.fatal(format!(
|
||||
"argument to `pretty` must be one of `normal`, \
|
||||
`expanded`, `flowgraph=<nodeid>`, `typed`, `identified`, \
|
||||
or `expanded,identified`; got {}", name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ This API is completely unstable and subject to change.
|
||||
|
||||
extern crate flate;
|
||||
extern crate arena;
|
||||
extern crate graphviz;
|
||||
extern crate syntax;
|
||||
extern crate serialize;
|
||||
extern crate sync;
|
||||
@ -122,4 +123,3 @@ pub mod lib {
|
||||
pub fn main() {
|
||||
std::os::set_exit_status(driver::main_args(std::os::args().as_slice()));
|
||||
}
|
||||
|
||||
|
@ -1755,8 +1755,10 @@ pub mod llvm {
|
||||
PM: PassManagerRef,
|
||||
M: ModuleRef);
|
||||
pub fn LLVMRustAddBuilderLibraryInfo(PMB: PassManagerBuilderRef,
|
||||
M: ModuleRef);
|
||||
pub fn LLVMRustAddLibraryInfo(PM: PassManagerRef, M: ModuleRef);
|
||||
M: ModuleRef,
|
||||
DisableSimplifyLibCalls: bool);
|
||||
pub fn LLVMRustAddLibraryInfo(PM: PassManagerRef, M: ModuleRef,
|
||||
DisableSimplifyLibCalls: bool);
|
||||
pub fn LLVMRustRunFunctionPassManager(PM: PassManagerRef, M: ModuleRef);
|
||||
pub fn LLVMRustWriteOutputFile(T: TargetMachineRef,
|
||||
PM: PassManagerRef,
|
||||
|
@ -18,10 +18,10 @@ use util::nodemap::NodeMap;
|
||||
|
||||
struct CFGBuilder<'a> {
|
||||
tcx: &'a ty::ctxt,
|
||||
method_map: typeck::MethodMap,
|
||||
exit_map: NodeMap<CFGIndex>,
|
||||
graph: CFGGraph,
|
||||
loop_scopes: Vec<LoopScope> ,
|
||||
fn_exit: CFGIndex,
|
||||
loop_scopes: Vec<LoopScope>,
|
||||
}
|
||||
|
||||
struct LoopScope {
|
||||
@ -31,22 +31,35 @@ struct LoopScope {
|
||||
}
|
||||
|
||||
pub fn construct(tcx: &ty::ctxt,
|
||||
method_map: typeck::MethodMap,
|
||||
blk: &ast::Block) -> CFG {
|
||||
let mut graph = graph::Graph::new();
|
||||
let entry = add_initial_dummy_node(&mut graph);
|
||||
|
||||
// `fn_exit` is target of return exprs, which lies somewhere
|
||||
// outside input `blk`. (Distinguishing `fn_exit` and `block_exit`
|
||||
// also resolves chicken-and-egg problem that arises if you try to
|
||||
// have return exprs jump to `block_exit` during construction.)
|
||||
let fn_exit = add_initial_dummy_node(&mut graph);
|
||||
let block_exit;
|
||||
|
||||
let mut cfg_builder = CFGBuilder {
|
||||
exit_map: NodeMap::new(),
|
||||
graph: graph::Graph::new(),
|
||||
graph: graph,
|
||||
fn_exit: fn_exit,
|
||||
tcx: tcx,
|
||||
method_map: method_map,
|
||||
loop_scopes: Vec::new()
|
||||
};
|
||||
let entry = cfg_builder.add_node(0, []);
|
||||
let exit = cfg_builder.block(blk, entry);
|
||||
block_exit = cfg_builder.block(blk, entry);
|
||||
cfg_builder.add_contained_edge(block_exit, fn_exit);
|
||||
let CFGBuilder {exit_map, graph, ..} = cfg_builder;
|
||||
CFG {exit_map: exit_map,
|
||||
graph: graph,
|
||||
entry: entry,
|
||||
exit: exit}
|
||||
exit: fn_exit}
|
||||
}
|
||||
|
||||
fn add_initial_dummy_node(g: &mut CFGGraph) -> CFGIndex {
|
||||
g.add_node(CFGNodeData { id: ast::DUMMY_NODE_ID })
|
||||
}
|
||||
|
||||
impl<'a> CFGBuilder<'a> {
|
||||
@ -327,24 +340,25 @@ impl<'a> CFGBuilder<'a> {
|
||||
|
||||
ast::ExprRet(v) => {
|
||||
let v_exit = self.opt_expr(v, pred);
|
||||
let loop_scope = *self.loop_scopes.get(0);
|
||||
self.add_exiting_edge(expr, v_exit,
|
||||
loop_scope, loop_scope.break_index);
|
||||
self.add_node(expr.id, [])
|
||||
let b = self.add_node(expr.id, [v_exit]);
|
||||
self.add_returning_edge(expr, b);
|
||||
self.add_node(ast::DUMMY_NODE_ID, [])
|
||||
}
|
||||
|
||||
ast::ExprBreak(label) => {
|
||||
let loop_scope = self.find_scope(expr, label);
|
||||
self.add_exiting_edge(expr, pred,
|
||||
let b = self.add_node(expr.id, [pred]);
|
||||
self.add_exiting_edge(expr, b,
|
||||
loop_scope, loop_scope.break_index);
|
||||
self.add_node(expr.id, [])
|
||||
self.add_node(ast::DUMMY_NODE_ID, [])
|
||||
}
|
||||
|
||||
ast::ExprAgain(label) => {
|
||||
let loop_scope = self.find_scope(expr, label);
|
||||
self.add_exiting_edge(expr, pred,
|
||||
let a = self.add_node(expr.id, [pred]);
|
||||
self.add_exiting_edge(expr, a,
|
||||
loop_scope, loop_scope.continue_index);
|
||||
self.add_node(expr.id, [])
|
||||
self.add_node(ast::DUMMY_NODE_ID, [])
|
||||
}
|
||||
|
||||
ast::ExprVec(ref elems) => {
|
||||
@ -453,13 +467,16 @@ impl<'a> CFGBuilder<'a> {
|
||||
}
|
||||
|
||||
fn add_dummy_node(&mut self, preds: &[CFGIndex]) -> CFGIndex {
|
||||
self.add_node(0, preds)
|
||||
self.add_node(ast::DUMMY_NODE_ID, preds)
|
||||
}
|
||||
|
||||
fn add_node(&mut self, id: ast::NodeId, preds: &[CFGIndex]) -> CFGIndex {
|
||||
assert!(!self.exit_map.contains_key(&id));
|
||||
let node = self.graph.add_node(CFGNodeData {id: id});
|
||||
self.exit_map.insert(id, node);
|
||||
if id != ast::DUMMY_NODE_ID {
|
||||
assert!(!self.exit_map.contains_key(&id));
|
||||
self.exit_map.insert(id, node);
|
||||
}
|
||||
for &pred in preds.iter() {
|
||||
self.add_contained_edge(pred, node);
|
||||
}
|
||||
@ -488,6 +505,16 @@ impl<'a> CFGBuilder<'a> {
|
||||
self.graph.add_edge(from_index, to_index, data);
|
||||
}
|
||||
|
||||
fn add_returning_edge(&mut self,
|
||||
_from_expr: @ast::Expr,
|
||||
from_index: CFGIndex) {
|
||||
let mut data = CFGEdgeData {exiting_scopes: vec!() };
|
||||
for &LoopScope { loop_id: id, .. } in self.loop_scopes.iter().rev() {
|
||||
data.exiting_scopes.push(id);
|
||||
}
|
||||
self.graph.add_edge(from_index, self.fn_exit, data);
|
||||
}
|
||||
|
||||
fn find_scope(&self,
|
||||
expr: @ast::Expr,
|
||||
label: Option<ast::Ident>) -> LoopScope {
|
||||
@ -521,6 +548,6 @@ impl<'a> CFGBuilder<'a> {
|
||||
|
||||
fn is_method_call(&self, expr: &ast::Expr) -> bool {
|
||||
let method_call = typeck::MethodCall::expr(expr.id);
|
||||
self.method_map.borrow().contains_key(&method_call)
|
||||
self.tcx.method_map.borrow().contains_key(&method_call)
|
||||
}
|
||||
}
|
||||
|
116
src/librustc/middle/cfg/graphviz.rs
Normal file
116
src/librustc/middle/cfg/graphviz.rs
Normal file
@ -0,0 +1,116 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/// This module provides linkage between rustc::middle::graph and
|
||||
/// libgraphviz traits.
|
||||
|
||||
/// For clarity, rename the graphviz crate locally to dot.
|
||||
use dot = graphviz;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::ast_map;
|
||||
|
||||
use middle::cfg;
|
||||
|
||||
pub type Node<'a> = (cfg::CFGIndex, &'a cfg::CFGNode);
|
||||
pub type Edge<'a> = &'a cfg::CFGEdge;
|
||||
|
||||
pub struct LabelledCFG<'a>{
|
||||
pub ast_map: &'a ast_map::Map,
|
||||
pub cfg: &'a cfg::CFG,
|
||||
pub name: StrBuf,
|
||||
}
|
||||
|
||||
fn replace_newline_with_backslash_l(s: StrBuf) -> StrBuf {
|
||||
// Replacing newlines with \\l causes each line to be left-aligned,
|
||||
// improving presentation of (long) pretty-printed expressions.
|
||||
if s.as_slice().contains("\n") {
|
||||
let mut s = s.replace("\n", "\\l");
|
||||
// Apparently left-alignment applies to the line that precedes
|
||||
// \l, not the line that follows; so, add \l at end of string
|
||||
// if not already present, ensuring last line gets left-aligned
|
||||
// as well.
|
||||
let mut last_two : Vec<_> = s.chars().rev().take(2).collect();
|
||||
last_two.reverse();
|
||||
if last_two.as_slice() != ['\\', 'l'] {
|
||||
s = s.append("\\l");
|
||||
}
|
||||
s.to_strbuf()
|
||||
} else {
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> dot::Labeller<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a> {
|
||||
fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new(self.name.as_slice()) }
|
||||
|
||||
fn node_id(&'a self, &(i,_): &Node<'a>) -> dot::Id<'a> {
|
||||
dot::Id::new(format!("N{:u}", i.node_id()))
|
||||
}
|
||||
|
||||
fn node_label(&'a self, &(i, n): &Node<'a>) -> dot::LabelText<'a> {
|
||||
if i == self.cfg.entry {
|
||||
dot::LabelStr("entry".into_maybe_owned())
|
||||
} else if i == self.cfg.exit {
|
||||
dot::LabelStr("exit".into_maybe_owned())
|
||||
} else if n.data.id == ast::DUMMY_NODE_ID {
|
||||
dot::LabelStr("(dummy_node)".into_maybe_owned())
|
||||
} else {
|
||||
let s = self.ast_map.node_to_str(n.data.id);
|
||||
// left-aligns the lines
|
||||
let s = replace_newline_with_backslash_l(s);
|
||||
dot::EscStr(s.into_maybe_owned())
|
||||
}
|
||||
}
|
||||
|
||||
fn edge_label(&self, e: &Edge<'a>) -> dot::LabelText<'a> {
|
||||
let mut label = StrBuf::new();
|
||||
let mut put_one = false;
|
||||
for (i, &node_id) in e.data.exiting_scopes.iter().enumerate() {
|
||||
if put_one {
|
||||
label = label.append(",\\l");
|
||||
} else {
|
||||
put_one = true;
|
||||
}
|
||||
let s = self.ast_map.node_to_str(node_id);
|
||||
// left-aligns the lines
|
||||
let s = replace_newline_with_backslash_l(s);
|
||||
label = label.append(format!("exiting scope_{} {}", i, s.as_slice()));
|
||||
}
|
||||
dot::EscStr(label.into_maybe_owned())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for &'a cfg::CFG {
|
||||
fn nodes(&self) -> dot::Nodes<'a, Node<'a>> {
|
||||
let mut v = Vec::new();
|
||||
self.graph.each_node(|i, nd| { v.push((i, nd)); true });
|
||||
dot::maybe_owned_vec::Growable(v)
|
||||
}
|
||||
fn edges(&self) -> dot::Edges<'a, Edge<'a>> {
|
||||
self.graph.all_edges().iter().collect()
|
||||
}
|
||||
fn source(&self, edge: &Edge<'a>) -> Node<'a> {
|
||||
let i = edge.source();
|
||||
(i, self.graph.node(i))
|
||||
}
|
||||
fn target(&self, edge: &Edge<'a>) -> Node<'a> {
|
||||
let i = edge.target();
|
||||
(i, self.graph.node(i))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a>
|
||||
{
|
||||
fn nodes(&self) -> dot::Nodes<'a, Node<'a>> { self.cfg.nodes() }
|
||||
fn edges(&self) -> dot::Edges<'a, Edge<'a>> { self.cfg.edges() }
|
||||
fn source(&self, edge: &Edge<'a>) -> Node<'a> { self.cfg.source(edge) }
|
||||
fn target(&self, edge: &Edge<'a>) -> Node<'a> { self.cfg.target(edge) }
|
||||
}
|
@ -19,25 +19,25 @@ Uses `Graph` as the underlying representation.
|
||||
|
||||
use middle::graph;
|
||||
use middle::ty;
|
||||
use middle::typeck;
|
||||
use syntax::ast;
|
||||
use util::nodemap::NodeMap;
|
||||
|
||||
mod construct;
|
||||
pub mod graphviz;
|
||||
|
||||
pub struct CFG {
|
||||
exit_map: NodeMap<CFGIndex>,
|
||||
graph: CFGGraph,
|
||||
entry: CFGIndex,
|
||||
exit: CFGIndex,
|
||||
pub exit_map: NodeMap<CFGIndex>,
|
||||
pub graph: CFGGraph,
|
||||
pub entry: CFGIndex,
|
||||
pub exit: CFGIndex,
|
||||
}
|
||||
|
||||
pub struct CFGNodeData {
|
||||
id: ast::NodeId
|
||||
pub id: ast::NodeId
|
||||
}
|
||||
|
||||
pub struct CFGEdgeData {
|
||||
exiting_scopes: Vec<ast::NodeId>
|
||||
pub exiting_scopes: Vec<ast::NodeId>
|
||||
}
|
||||
|
||||
pub type CFGIndex = graph::NodeIndex;
|
||||
@ -55,8 +55,7 @@ pub struct CFGIndices {
|
||||
|
||||
impl CFG {
|
||||
pub fn new(tcx: &ty::ctxt,
|
||||
method_map: typeck::MethodMap,
|
||||
blk: &ast::Block) -> CFG {
|
||||
construct::construct(tcx, method_map, blk)
|
||||
construct::construct(tcx, blk)
|
||||
}
|
||||
}
|
||||
|
@ -70,10 +70,14 @@ pub static Incoming: Direction = Direction { repr: 1 };
|
||||
|
||||
impl NodeIndex {
|
||||
fn get(&self) -> uint { let NodeIndex(v) = *self; v }
|
||||
/// Returns unique id (unique with respect to the graph holding associated node).
|
||||
pub fn node_id(&self) -> uint { self.get() }
|
||||
}
|
||||
|
||||
impl EdgeIndex {
|
||||
fn get(&self) -> uint { let EdgeIndex(v) = *self; v }
|
||||
/// Returns unique id (unique with respect to the graph holding associated edge).
|
||||
pub fn edge_id(&self) -> uint { self.get() }
|
||||
}
|
||||
|
||||
impl<N,E> Graph<N,E> {
|
||||
@ -201,39 +205,39 @@ impl<N,E> Graph<N,E> {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Iterating over nodes, edges
|
||||
|
||||
pub fn each_node(&self, f: |NodeIndex, &Node<N>| -> bool) -> bool {
|
||||
pub fn each_node<'a>(&'a self, f: |NodeIndex, &'a Node<N>| -> bool) -> bool {
|
||||
//! Iterates over all edges defined in the graph.
|
||||
self.nodes.iter().enumerate().advance(|(i, node)| f(NodeIndex(i), node))
|
||||
}
|
||||
|
||||
pub fn each_edge(&self, f: |EdgeIndex, &Edge<E>| -> bool) -> bool {
|
||||
pub fn each_edge<'a>(&'a self, f: |EdgeIndex, &'a Edge<E>| -> bool) -> bool {
|
||||
//! Iterates over all edges defined in the graph
|
||||
self.edges.iter().enumerate().advance(|(i, edge)| f(EdgeIndex(i), edge))
|
||||
}
|
||||
|
||||
pub fn each_outgoing_edge(&self,
|
||||
source: NodeIndex,
|
||||
f: |EdgeIndex, &Edge<E>| -> bool)
|
||||
-> bool {
|
||||
pub fn each_outgoing_edge<'a>(&'a self,
|
||||
source: NodeIndex,
|
||||
f: |EdgeIndex, &'a Edge<E>| -> bool)
|
||||
-> bool {
|
||||
//! Iterates over all outgoing edges from the node `from`
|
||||
|
||||
self.each_adjacent_edge(source, Outgoing, f)
|
||||
}
|
||||
|
||||
pub fn each_incoming_edge(&self,
|
||||
target: NodeIndex,
|
||||
f: |EdgeIndex, &Edge<E>| -> bool)
|
||||
-> bool {
|
||||
pub fn each_incoming_edge<'a>(&'a self,
|
||||
target: NodeIndex,
|
||||
f: |EdgeIndex, &'a Edge<E>| -> bool)
|
||||
-> bool {
|
||||
//! Iterates over all incoming edges to the node `target`
|
||||
|
||||
self.each_adjacent_edge(target, Incoming, f)
|
||||
}
|
||||
|
||||
pub fn each_adjacent_edge(&self,
|
||||
node: NodeIndex,
|
||||
dir: Direction,
|
||||
f: |EdgeIndex, &Edge<E>| -> bool)
|
||||
-> bool {
|
||||
pub fn each_adjacent_edge<'a>(&'a self,
|
||||
node: NodeIndex,
|
||||
dir: Direction,
|
||||
f: |EdgeIndex, &'a Edge<E>| -> bool)
|
||||
-> bool {
|
||||
//! Iterates over all edges adjacent to the node `node`
|
||||
//! in the direction `dir` (either `Outgoing` or `Incoming)
|
||||
|
||||
@ -257,11 +261,11 @@ impl<N,E> Graph<N,E> {
|
||||
// variables or other bitsets. This method facilitates such a
|
||||
// computation.
|
||||
|
||||
pub fn iterate_until_fixed_point(&self,
|
||||
op: |iter_index: uint,
|
||||
edge_index: EdgeIndex,
|
||||
edge: &Edge<E>|
|
||||
-> bool) {
|
||||
pub fn iterate_until_fixed_point<'a>(&'a self,
|
||||
op: |iter_index: uint,
|
||||
edge_index: EdgeIndex,
|
||||
edge: &'a Edge<E>|
|
||||
-> bool) {
|
||||
let mut iteration = 0;
|
||||
let mut changed = true;
|
||||
while changed {
|
||||
|
@ -1050,6 +1050,7 @@ fn check_raw_ptr_deriving(cx: &mut Context, item: &ast::Item) {
|
||||
static crate_attrs: &'static [&'static str] = &[
|
||||
"crate_type", "feature", "no_start", "no_main", "no_std", "crate_id",
|
||||
"desc", "comment", "license", "copyright", // not used in rustc now
|
||||
"no_builtins",
|
||||
];
|
||||
|
||||
|
||||
|
@ -2226,6 +2226,7 @@ pub fn trans_crate(krate: ast::Crate,
|
||||
|
||||
let metadata_module = ccx.metadata_llmod;
|
||||
let formats = ccx.tcx.dependency_formats.borrow().clone();
|
||||
let no_builtins = attr::contains_name(krate.attrs.as_slice(), "no_builtins");
|
||||
|
||||
(ccx.tcx, CrateTranslation {
|
||||
context: llcx,
|
||||
@ -2235,5 +2236,6 @@ pub fn trans_crate(krate: ast::Crate,
|
||||
metadata: metadata,
|
||||
reachable: reachable,
|
||||
crate_formats: formats,
|
||||
no_builtins: no_builtins,
|
||||
})
|
||||
}
|
||||
|
@ -309,6 +309,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
|
||||
ast_map::NodeStmt(..) |
|
||||
ast_map::NodeArg(..) |
|
||||
ast_map::NodeBlock(..) |
|
||||
ast_map::NodePat(..) |
|
||||
ast_map::NodeLocal(..) => {
|
||||
ccx.sess().bug(format!("can't monomorphize a {:?}", map_node))
|
||||
}
|
||||
|
@ -1204,7 +1204,7 @@ impl Clean<Item> for ast::ForeignItem {
|
||||
ForeignFunctionItem(Function {
|
||||
decl: decl.clean(),
|
||||
generics: generics.clean(),
|
||||
fn_style: ast::NormalFn,
|
||||
fn_style: ast::UnsafeFn,
|
||||
})
|
||||
}
|
||||
ast::ForeignItemStatic(ref ty, mutbl) => {
|
||||
|
@ -285,9 +285,7 @@ impl FsRequest {
|
||||
FileStat {
|
||||
size: stat.st_size as u64,
|
||||
kind: kind,
|
||||
perm: unsafe {
|
||||
io::FilePermission::from_bits(stat.st_mode as u32) & io::AllPermissions
|
||||
},
|
||||
perm: io::FilePermission::from_bits_truncate(stat.st_mode as u32),
|
||||
created: to_msec(stat.st_birthtim),
|
||||
modified: to_msec(stat.st_mtim),
|
||||
accessed: to_msec(stat.st_atim),
|
||||
|
@ -472,7 +472,7 @@ fn local_loop() -> &'static mut uvio::UvIoFactory {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::mem::transmute;
|
||||
use std::unstable::run_in_bare_thread;
|
||||
use std::rt::thread::Thread;
|
||||
|
||||
use super::{slice_to_uv_buf, Loop};
|
||||
|
||||
@ -496,10 +496,10 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn loop_smoke_test() {
|
||||
run_in_bare_thread(proc() {
|
||||
Thread::start(proc() {
|
||||
let mut loop_ = Loop::new();
|
||||
loop_.run();
|
||||
loop_.close();
|
||||
});
|
||||
}).join();
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ use std::rt::rtio;
|
||||
use std::rt::rtio::{ProcessConfig, IoFactory, EventLoop};
|
||||
use ai = std::io::net::addrinfo;
|
||||
|
||||
#[cfg(test)] use std::unstable::run_in_bare_thread;
|
||||
#[cfg(test)] use std::rt::thread::Thread;
|
||||
|
||||
use super::{uv_error_to_io_error, Loop};
|
||||
|
||||
@ -116,7 +116,7 @@ impl EventLoop for UvEventLoop {
|
||||
|
||||
#[test]
|
||||
fn test_callback_run_once() {
|
||||
run_in_bare_thread(proc() {
|
||||
Thread::start(proc() {
|
||||
let mut event_loop = UvEventLoop::new();
|
||||
let mut count = 0;
|
||||
let count_ptr: *mut int = &mut count;
|
||||
@ -125,7 +125,7 @@ fn test_callback_run_once() {
|
||||
});
|
||||
event_loop.run();
|
||||
assert_eq!(count, 1);
|
||||
});
|
||||
}).join();
|
||||
}
|
||||
|
||||
pub struct UvIoFactory {
|
||||
|
@ -136,10 +136,20 @@ macro_rules! bitflags(
|
||||
self.bits
|
||||
}
|
||||
|
||||
/// Convert from underlying bit representation. Unsafe because the
|
||||
/// bits are not guaranteed to represent valid flags.
|
||||
pub unsafe fn from_bits(bits: $T) -> $BitFlags {
|
||||
$BitFlags { bits: bits }
|
||||
/// Convert from underlying bit representation, unless that
|
||||
/// representation contains bits that do not correspond to a flag.
|
||||
pub fn from_bits(bits: $T) -> ::std::option::Option<$BitFlags> {
|
||||
if (bits & !$BitFlags::all().bits()) != 0 {
|
||||
::std::option::None
|
||||
} else {
|
||||
::std::option::Some($BitFlags { bits: bits })
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert from underlying bit representation, dropping any bits
|
||||
/// that do not correspond to flags.
|
||||
pub fn from_bits_truncate(bits: $T) -> $BitFlags {
|
||||
$BitFlags { bits: bits } & $BitFlags::all()
|
||||
}
|
||||
|
||||
/// Returns `true` if no flags are currently stored.
|
||||
@ -209,6 +219,7 @@ macro_rules! bitflags(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use option::{Some, None};
|
||||
use ops::{BitOr, BitAnd, Sub, Not};
|
||||
|
||||
bitflags!(
|
||||
@ -231,9 +242,21 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_from_bits() {
|
||||
assert!(unsafe { Flags::from_bits(0x00000000) } == Flags::empty());
|
||||
assert!(unsafe { Flags::from_bits(0x00000001) } == FlagA);
|
||||
assert!(unsafe { Flags::from_bits(0x00000111) } == FlagABC);
|
||||
assert!(Flags::from_bits(0) == Some(Flags::empty()));
|
||||
assert!(Flags::from_bits(0x1) == Some(FlagA));
|
||||
assert!(Flags::from_bits(0x10) == Some(FlagB));
|
||||
assert!(Flags::from_bits(0x11) == Some(FlagA | FlagB));
|
||||
assert!(Flags::from_bits(0x1000) == None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_bits_truncate() {
|
||||
assert!(Flags::from_bits_truncate(0) == Flags::empty());
|
||||
assert!(Flags::from_bits_truncate(0x1) == FlagA);
|
||||
assert!(Flags::from_bits_truncate(0x10) == FlagB);
|
||||
assert!(Flags::from_bits_truncate(0x11) == (FlagA | FlagB));
|
||||
assert!(Flags::from_bits_truncate(0x1000) == Flags::empty());
|
||||
assert!(Flags::from_bits_truncate(0x1001) == FlagA);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -209,7 +209,7 @@ impl<W: Writer> Writer for BufferedWriter<W> {
|
||||
impl<W: Writer> Drop for BufferedWriter<W> {
|
||||
fn drop(&mut self) {
|
||||
if self.inner.is_some() {
|
||||
// FIXME(#12628): should this error be ignored?
|
||||
// dtors should not fail, so we ignore a failed flush
|
||||
let _ = self.flush_buf();
|
||||
}
|
||||
}
|
||||
@ -370,6 +370,7 @@ mod test {
|
||||
use io;
|
||||
use prelude::*;
|
||||
use super::*;
|
||||
use super::super::{IoResult, EndOfFile};
|
||||
use super::super::mem::{MemReader, MemWriter, BufReader};
|
||||
use self::test::Bencher;
|
||||
use str::StrSlice;
|
||||
@ -584,6 +585,24 @@ mod test {
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn dont_fail_in_drop_on_failed_flush() {
|
||||
struct FailFlushWriter;
|
||||
|
||||
impl Writer for FailFlushWriter {
|
||||
fn write(&mut self, _buf: &[u8]) -> IoResult<()> { Ok(()) }
|
||||
fn flush(&mut self) -> IoResult<()> { Err(io::standard_error(EndOfFile)) }
|
||||
}
|
||||
|
||||
let writer = FailFlushWriter;
|
||||
let _writer = BufferedWriter::new(writer);
|
||||
|
||||
// Trigger failure. If writer fails *again* due to the flush
|
||||
// error then the process will abort.
|
||||
fail!();
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_buffered_reader(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
|
@ -1,52 +0,0 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Some various other I/O types
|
||||
|
||||
// FIXME(#3660): should move to libextra
|
||||
|
||||
use prelude::*;
|
||||
use super::*;
|
||||
|
||||
/// A Writer decorator that compresses using the 'deflate' scheme
|
||||
pub struct DeflateWriter<W> {
|
||||
priv inner_writer: W
|
||||
}
|
||||
|
||||
impl<W: Writer> DeflateWriter<W> {
|
||||
pub fn new(inner_writer: W) -> DeflateWriter<W> {
|
||||
DeflateWriter {
|
||||
inner_writer: inner_writer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Writer> Writer for DeflateWriter<W> {
|
||||
fn write(&mut self, _buf: &[u8]) { fail!() }
|
||||
|
||||
fn flush(&mut self) { fail!() }
|
||||
}
|
||||
|
||||
/// A Reader decorator that decompresses using the 'deflate' scheme
|
||||
pub struct InflateReader<R> {
|
||||
priv inner_reader: R
|
||||
}
|
||||
|
||||
impl<R: Reader> InflateReader<R> {
|
||||
pub fn new(inner_reader: R) -> InflateReader<R> {
|
||||
InflateReader {
|
||||
inner_reader: inner_reader
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Reader> Reader for InflateReader<R> {
|
||||
fn read(&mut self, _buf: &mut [u8]) -> Option<uint> { fail!() }
|
||||
}
|
@ -10,7 +10,7 @@
|
||||
|
||||
//! Temporary files and directories
|
||||
|
||||
use io::fs;
|
||||
use io::{fs, IoResult};
|
||||
use io;
|
||||
use iter::{Iterator, range};
|
||||
use libc;
|
||||
@ -18,13 +18,14 @@ use ops::Drop;
|
||||
use option::{Option, None, Some};
|
||||
use os;
|
||||
use path::{Path, GenericPath};
|
||||
use result::{Ok, Err, ResultUnwrap};
|
||||
use result::{Ok, Err};
|
||||
use sync::atomics;
|
||||
|
||||
/// A wrapper for a path to temporary directory implementing automatic
|
||||
/// scope-based deletion.
|
||||
pub struct TempDir {
|
||||
path: Option<Path>
|
||||
path: Option<Path>,
|
||||
disarmed: bool
|
||||
}
|
||||
|
||||
impl TempDir {
|
||||
@ -48,7 +49,7 @@ impl TempDir {
|
||||
let p = tmpdir.join(filename);
|
||||
match fs::mkdir(&p, io::UserRWX) {
|
||||
Err(..) => {}
|
||||
Ok(()) => return Some(TempDir { path: Some(p) })
|
||||
Ok(()) => return Some(TempDir { path: Some(p), disarmed: false })
|
||||
}
|
||||
}
|
||||
None
|
||||
@ -75,15 +76,32 @@ impl TempDir {
|
||||
pub fn path<'a>(&'a self) -> &'a Path {
|
||||
self.path.get_ref()
|
||||
}
|
||||
|
||||
/// Close and remove the temporary directory
|
||||
///
|
||||
/// Although `TempDir` removes the directory on drop, in the destructor
|
||||
/// any errors are ignored. To detect errors cleaning up the temporary
|
||||
/// directory, call `close` instead.
|
||||
pub fn close(mut self) -> IoResult<()> {
|
||||
self.cleanup_dir()
|
||||
}
|
||||
|
||||
fn cleanup_dir(&mut self) -> IoResult<()> {
|
||||
assert!(!self.disarmed);
|
||||
self.disarmed = true;
|
||||
match self.path {
|
||||
Some(ref p) => {
|
||||
fs::rmdir_recursive(p)
|
||||
}
|
||||
None => Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TempDir {
|
||||
fn drop(&mut self) {
|
||||
for path in self.path.iter() {
|
||||
if path.exists() {
|
||||
// FIXME: is failing the right thing to do?
|
||||
fs::rmdir_recursive(path).unwrap();
|
||||
}
|
||||
if !self.disarmed {
|
||||
let _ = self.cleanup_dir();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -133,16 +133,13 @@ extern crate core;
|
||||
#[cfg(test)] pub use ops = realstd::ops;
|
||||
#[cfg(test)] pub use cmp = realstd::cmp;
|
||||
#[cfg(test)] pub use ty = realstd::ty;
|
||||
#[cfg(not(stage0), test)] pub use owned = realstd::owned;
|
||||
#[cfg(test)] pub use owned = realstd::owned;
|
||||
|
||||
#[cfg(not(test))] pub use cmp = core::cmp;
|
||||
#[cfg(not(test))] pub use kinds = core::kinds;
|
||||
#[cfg(not(test))] pub use ops = core::ops;
|
||||
#[cfg(not(test))] pub use ty = core::ty;
|
||||
|
||||
#[cfg(stage0, test)] pub use owned = realstd::owned;
|
||||
#[cfg(stage0, not(test))] pub use owned = core::owned;
|
||||
|
||||
pub use core::any;
|
||||
pub use core::bool;
|
||||
pub use core::cell;
|
||||
@ -209,7 +206,7 @@ pub mod ascii;
|
||||
|
||||
pub mod rc;
|
||||
pub mod gc;
|
||||
#[cfg(not(stage0), not(test))]
|
||||
#[cfg(not(test))]
|
||||
pub mod owned;
|
||||
|
||||
/* Common traits */
|
||||
|
@ -53,24 +53,24 @@ impl Local<local_ptr::Borrowed<Task>> for Task {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use option::{None, Option};
|
||||
use unstable::run_in_bare_thread;
|
||||
use rt::thread::Thread;
|
||||
use super::*;
|
||||
use owned::Box;
|
||||
use rt::task::Task;
|
||||
|
||||
#[test]
|
||||
fn thread_local_task_smoke_test() {
|
||||
run_in_bare_thread(proc() {
|
||||
Thread::start(proc() {
|
||||
let task = box Task::new();
|
||||
Local::put(task);
|
||||
let task: Box<Task> = Local::take();
|
||||
cleanup_task(task);
|
||||
});
|
||||
}).join();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn thread_local_task_two_instances() {
|
||||
run_in_bare_thread(proc() {
|
||||
Thread::start(proc() {
|
||||
let task = box Task::new();
|
||||
Local::put(task);
|
||||
let task: Box<Task> = Local::take();
|
||||
@ -79,12 +79,12 @@ mod test {
|
||||
Local::put(task);
|
||||
let task: Box<Task> = Local::take();
|
||||
cleanup_task(task);
|
||||
});
|
||||
}).join();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn borrow_smoke_test() {
|
||||
run_in_bare_thread(proc() {
|
||||
Thread::start(proc() {
|
||||
let task = box Task::new();
|
||||
Local::put(task);
|
||||
|
||||
@ -93,12 +93,12 @@ mod test {
|
||||
}
|
||||
let task: Box<Task> = Local::take();
|
||||
cleanup_task(task);
|
||||
});
|
||||
}).join();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn borrow_with_return() {
|
||||
run_in_bare_thread(proc() {
|
||||
Thread::start(proc() {
|
||||
let task = box Task::new();
|
||||
Local::put(task);
|
||||
|
||||
@ -108,12 +108,12 @@ mod test {
|
||||
|
||||
let task: Box<Task> = Local::take();
|
||||
cleanup_task(task);
|
||||
});
|
||||
}).join();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_take() {
|
||||
run_in_bare_thread(proc() {
|
||||
Thread::start(proc() {
|
||||
let task = box Task::new();
|
||||
Local::put(task);
|
||||
|
||||
@ -122,7 +122,7 @@ mod test {
|
||||
assert!(u.is_none());
|
||||
|
||||
cleanup_task(t);
|
||||
});
|
||||
}).join();
|
||||
}
|
||||
|
||||
fn cleanup_task(mut t: Box<Task>) {
|
||||
|
@ -273,13 +273,8 @@ mod imp {
|
||||
assert_eq!(pthread_detach(native), 0);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "android")]
|
||||
pub unsafe fn yield_now() { assert_eq!(sched_yield(), 0); }
|
||||
|
||||
#[cfg(not(target_os = "macos"), not(target_os = "android"))]
|
||||
pub unsafe fn yield_now() { assert_eq!(pthread_yield(), 0); }
|
||||
|
||||
// glibc >= 2.15 has a __pthread_get_minstack() function that returns
|
||||
// PTHREAD_STACK_MIN plus however many bytes are needed for thread-local
|
||||
// storage. We need that information to avoid blowing up when a small stack
|
||||
@ -326,12 +321,7 @@ mod imp {
|
||||
fn pthread_attr_setdetachstate(attr: *mut libc::pthread_attr_t,
|
||||
state: libc::c_int) -> libc::c_int;
|
||||
fn pthread_detach(thread: libc::pthread_t) -> libc::c_int;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "android")]
|
||||
fn sched_yield() -> libc::c_int;
|
||||
#[cfg(not(target_os = "macos"), not(target_os = "android"))]
|
||||
fn pthread_yield() -> libc::c_int;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -564,6 +564,11 @@ impl<'a> IntoMaybeOwned<'a> for ~str {
|
||||
fn into_maybe_owned(self) -> MaybeOwned<'a> { Owned(self) }
|
||||
}
|
||||
|
||||
impl<'a> IntoMaybeOwned<'a> for StrBuf {
|
||||
#[inline]
|
||||
fn into_maybe_owned(self) -> MaybeOwned<'a> { Owned(self.into_owned()) }
|
||||
}
|
||||
|
||||
impl<'a> IntoMaybeOwned<'a> for &'a str {
|
||||
#[inline]
|
||||
fn into_maybe_owned(self) -> MaybeOwned<'a> { Slice(self) }
|
||||
|
@ -11,7 +11,6 @@
|
||||
#![doc(hidden)]
|
||||
|
||||
use libc::uintptr_t;
|
||||
use kinds::Send;
|
||||
|
||||
pub use core::finally;
|
||||
|
||||
@ -21,36 +20,6 @@ pub mod simd;
|
||||
pub mod sync;
|
||||
pub mod mutex;
|
||||
|
||||
/**
|
||||
|
||||
Start a new thread outside of the current runtime context and wait
|
||||
for it to terminate.
|
||||
|
||||
The executing thread has no access to a task pointer and will be using
|
||||
a normal large stack.
|
||||
*/
|
||||
pub fn run_in_bare_thread(f: proc():Send) {
|
||||
use rt::thread::Thread;
|
||||
Thread::start(f).join()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_run_in_bare_thread() {
|
||||
let i = 100;
|
||||
run_in_bare_thread(proc() {
|
||||
assert_eq!(i, 100);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_run_in_bare_thread_exchange() {
|
||||
// Does the exchange heap work without the runtime?
|
||||
let i = box 100;
|
||||
run_in_bare_thread(proc() {
|
||||
assert!(i == box 100);
|
||||
});
|
||||
}
|
||||
|
||||
/// Dynamically inquire about whether we're running under V.
|
||||
/// You should usually not use this unless your test definitely
|
||||
/// can't run correctly un-altered. Valgrind is there to help
|
||||
|
@ -635,14 +635,14 @@ impl<T> Vec<T> {
|
||||
/// ```
|
||||
pub fn truncate(&mut self, len: uint) {
|
||||
unsafe {
|
||||
let mut i = len;
|
||||
// drop any extra elements
|
||||
while i < self.len {
|
||||
ptr::read(self.as_slice().unsafe_ref(i));
|
||||
i += 1;
|
||||
while len < self.len {
|
||||
// decrement len before the read(), so a failure on Drop doesn't
|
||||
// re-drop the just-failed value.
|
||||
self.len -= 1;
|
||||
ptr::read(self.as_slice().unsafe_ref(self.len));
|
||||
}
|
||||
}
|
||||
self.len = len;
|
||||
}
|
||||
|
||||
/// Work with `self` as a mutable slice.
|
||||
@ -1862,4 +1862,39 @@ mod tests {
|
||||
assert_eq!(b[0].x, 42);
|
||||
assert_eq!(b[1].x, 84);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_truncate_drop() {
|
||||
static mut drops: uint = 0;
|
||||
struct Elem(int);
|
||||
impl Drop for Elem {
|
||||
fn drop(&mut self) {
|
||||
unsafe { drops += 1; }
|
||||
}
|
||||
}
|
||||
|
||||
let mut v = vec![Elem(1), Elem(2), Elem(3), Elem(4), Elem(5)];
|
||||
assert_eq!(unsafe { drops }, 0);
|
||||
v.truncate(3);
|
||||
assert_eq!(unsafe { drops }, 2);
|
||||
v.truncate(0);
|
||||
assert_eq!(unsafe { drops }, 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_vec_truncate_fail() {
|
||||
struct BadElem(int);
|
||||
impl Drop for BadElem {
|
||||
fn drop(&mut self) {
|
||||
let BadElem(ref mut x) = *self;
|
||||
if *x == 0xbadbeef {
|
||||
fail!("BadElem failure: 0xbadbeef")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut v = vec![BadElem(1), BadElem(2), BadElem(0xbadbeef), BadElem(4)];
|
||||
v.truncate(0);
|
||||
}
|
||||
}
|
||||
|
@ -103,6 +103,7 @@ pub enum Node {
|
||||
NodeStmt(@Stmt),
|
||||
NodeArg(@Pat),
|
||||
NodeLocal(@Pat),
|
||||
NodePat(@Pat),
|
||||
NodeBlock(P<Block>),
|
||||
|
||||
/// NodeStructCtor represents a tuple struct.
|
||||
@ -127,6 +128,7 @@ enum MapEntry {
|
||||
EntryStmt(NodeId, @Stmt),
|
||||
EntryArg(NodeId, @Pat),
|
||||
EntryLocal(NodeId, @Pat),
|
||||
EntryPat(NodeId, @Pat),
|
||||
EntryBlock(NodeId, P<Block>),
|
||||
EntryStructCtor(NodeId, @StructDef),
|
||||
EntryLifetime(NodeId, @Lifetime),
|
||||
@ -154,6 +156,7 @@ impl MapEntry {
|
||||
EntryStmt(id, _) => id,
|
||||
EntryArg(id, _) => id,
|
||||
EntryLocal(id, _) => id,
|
||||
EntryPat(id, _) => id,
|
||||
EntryBlock(id, _) => id,
|
||||
EntryStructCtor(id, _) => id,
|
||||
EntryLifetime(id, _) => id,
|
||||
@ -172,6 +175,7 @@ impl MapEntry {
|
||||
EntryStmt(_, p) => NodeStmt(p),
|
||||
EntryArg(_, p) => NodeArg(p),
|
||||
EntryLocal(_, p) => NodeLocal(p),
|
||||
EntryPat(_, p) => NodePat(p),
|
||||
EntryBlock(_, p) => NodeBlock(p),
|
||||
EntryStructCtor(_, p) => NodeStructCtor(p),
|
||||
EntryLifetime(_, p) => NodeLifetime(p),
|
||||
@ -399,6 +403,7 @@ impl Map {
|
||||
Some(NodeExpr(expr)) => expr.span,
|
||||
Some(NodeStmt(stmt)) => stmt.span,
|
||||
Some(NodeArg(pat)) | Some(NodeLocal(pat)) => pat.span,
|
||||
Some(NodePat(pat)) => pat.span,
|
||||
Some(NodeBlock(block)) => block.span,
|
||||
Some(NodeStructCtor(_)) => self.expect_item(self.get_parent(id)).span,
|
||||
_ => fail!("node_span: could not find span for id {}", id),
|
||||
@ -513,7 +518,9 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
|
||||
// Note: this is at least *potentially* a pattern...
|
||||
self.insert(pat.id, EntryLocal(self.parent, pat));
|
||||
}
|
||||
_ => {}
|
||||
_ => {
|
||||
self.insert(pat.id, EntryPat(self.parent, pat));
|
||||
}
|
||||
}
|
||||
|
||||
pat
|
||||
@ -704,6 +711,9 @@ fn node_id_to_str(map: &Map, id: NodeId) -> StrBuf {
|
||||
(format!("local {} (id={})",
|
||||
pprust::pat_to_str(pat), id)).to_strbuf()
|
||||
}
|
||||
Some(NodePat(pat)) => {
|
||||
(format!("pat {} (id={})", pprust::pat_to_str(pat), id)).to_strbuf()
|
||||
}
|
||||
Some(NodeBlock(block)) => {
|
||||
(format!("block {} (id={})",
|
||||
pprust::block_to_str(block), id)).to_strbuf()
|
||||
|
@ -128,17 +128,27 @@ LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM,
|
||||
// Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`
|
||||
// field of a PassManagerBuilder, we expose our own method of doing so.
|
||||
extern "C" void
|
||||
LLVMRustAddBuilderLibraryInfo(LLVMPassManagerBuilderRef PMB, LLVMModuleRef M) {
|
||||
LLVMRustAddBuilderLibraryInfo(LLVMPassManagerBuilderRef PMB,
|
||||
LLVMModuleRef M,
|
||||
bool DisableSimplifyLibCalls) {
|
||||
Triple TargetTriple(unwrap(M)->getTargetTriple());
|
||||
unwrap(PMB)->LibraryInfo = new TargetLibraryInfo(TargetTriple);
|
||||
TargetLibraryInfo *TLI = new TargetLibraryInfo(TargetTriple);
|
||||
if (DisableSimplifyLibCalls)
|
||||
TLI->disableAllFunctions();
|
||||
unwrap(PMB)->LibraryInfo = TLI;
|
||||
}
|
||||
|
||||
// Unfortunately, the LLVM C API doesn't provide a way to create the
|
||||
// TargetLibraryInfo pass, so we use this method to do so.
|
||||
extern "C" void
|
||||
LLVMRustAddLibraryInfo(LLVMPassManagerRef PMB, LLVMModuleRef M) {
|
||||
LLVMRustAddLibraryInfo(LLVMPassManagerRef PMB,
|
||||
LLVMModuleRef M,
|
||||
bool DisableSimplifyLibCalls) {
|
||||
Triple TargetTriple(unwrap(M)->getTargetTriple());
|
||||
unwrap(PMB)->add(new TargetLibraryInfo(TargetTriple));
|
||||
TargetLibraryInfo *TLI = new TargetLibraryInfo(TargetTriple);
|
||||
if (DisableSimplifyLibCalls)
|
||||
TLI->disableAllFunctions();
|
||||
unwrap(PMB)->add(TLI);
|
||||
}
|
||||
|
||||
// Unfortunately, the LLVM C API doesn't provide an easy way of iterating over
|
||||
|
@ -1,3 +1,11 @@
|
||||
S 2014-05-15 6a2b3d1
|
||||
freebsd-x86_64 afc98b59cb819025fecdb9d145ca4463f857a477
|
||||
linux-i386 d6f7a404412ea34db3d19814ca21fe6fa662b02f
|
||||
linux-x86_64 3dfb54406a7ea75565a7ea3071daad885cb91775
|
||||
macos-i386 bebb937551d601ad908c9e4eaa196cc7a977c503
|
||||
macos-x86_64 08346ed401ad2891c7d2ba0aac0960f6e77bb78b
|
||||
winnt-i386 ad8e5b8292a00f60f1f7dc2e35bd18abeb5b858d
|
||||
|
||||
S 2014-05-11 72fc4a5
|
||||
freebsd-x86_64 82db6355b0b7c8023c8845a74e2f224da2831b50
|
||||
linux-i386 91901299d5f86f5b67377d940073908a1f0e4e82
|
||||
|
@ -7,56 +7,104 @@
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
#![feature(macro_rules)]
|
||||
#![feature(simd)]
|
||||
#![allow(experimental)]
|
||||
|
||||
// ignore-pretty very bad with line comments
|
||||
|
||||
extern crate sync;
|
||||
|
||||
use std::io;
|
||||
use std::os;
|
||||
use std::unstable::simd::f64x2;
|
||||
use sync::Future;
|
||||
use sync::Arc;
|
||||
|
||||
static ITER: int = 50;
|
||||
static LIMIT: f64 = 2.0;
|
||||
static WORKERS: uint = 16;
|
||||
|
||||
fn write_line(init_i: f64, vec_init_r: &[f64], res: &mut Vec<u8>) {
|
||||
for chunk_init_r in vec_init_r.chunks(8) {
|
||||
let mut cur_byte = 0xff;
|
||||
let mut cur_bitmask = 0x80;
|
||||
for &init_r in chunk_init_r.iter() {
|
||||
let mut cur_r = init_r;
|
||||
let mut cur_i = init_i;
|
||||
for _ in range(0, ITER) {
|
||||
let r = cur_r;
|
||||
let i = cur_i;
|
||||
cur_r = r * r - i * i + init_r;
|
||||
cur_i = 2.0 * r * i + init_i;
|
||||
|
||||
if r * r + i * i > LIMIT * LIMIT {
|
||||
cur_byte &= !cur_bitmask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cur_bitmask >>= 1;
|
||||
}
|
||||
res.push(cur_byte);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn mandelbrot<W: io::Writer>(w: uint, mut out: W) -> io::IoResult<()> {
|
||||
assert!(WORKERS % 2 == 0);
|
||||
|
||||
// Ensure w and h are multiples of 8.
|
||||
let w = (w + 7) / 8 * 8;
|
||||
let h = w;
|
||||
let chunk_size = h / 8;
|
||||
|
||||
let data: Vec<Future<Vec<u8>>> = range(0u, 8).map(|i| Future::spawn(proc () {
|
||||
let vec_init_r = Vec::from_fn(w, |x| 2.0 * (x as f64) / (w as f64) - 1.5);
|
||||
let mut res: Vec<u8> = Vec::with_capacity((chunk_size * w) / 8);
|
||||
for y in range(i * chunk_size, (i + 1) * chunk_size) {
|
||||
let init_i = 2.0 * (y as f64) / (h as f64) - 1.0;
|
||||
write_line(init_i, vec_init_r.as_slice(), &mut res);
|
||||
}
|
||||
res
|
||||
})).collect();
|
||||
let chunk_size = h / WORKERS;
|
||||
|
||||
// Account for remainders in workload division, e.g. 1000 / 16 = 62.5
|
||||
let first_chunk_size = if h % WORKERS != 0 {
|
||||
chunk_size + h % WORKERS
|
||||
} else {
|
||||
chunk_size
|
||||
};
|
||||
|
||||
// precalc values
|
||||
let inverse_w_doubled = 2.0 / w as f64;
|
||||
let inverse_h_doubled = 2.0 / h as f64;
|
||||
let v_inverses = f64x2(inverse_w_doubled, inverse_h_doubled);
|
||||
let v_consts = f64x2(1.5, 1.0);
|
||||
|
||||
// A lot of this code assumes this (so do other lang benchmarks)
|
||||
assert!(w == h);
|
||||
let mut precalc_r = Vec::with_capacity(w);
|
||||
let mut precalc_i = Vec::with_capacity(h);
|
||||
|
||||
let precalc_futures = Vec::from_fn(WORKERS, |i| {
|
||||
Future::spawn(proc () {
|
||||
let mut rs = Vec::with_capacity(w / WORKERS);
|
||||
let mut is = Vec::with_capacity(w / WORKERS);
|
||||
|
||||
let start = i * chunk_size;
|
||||
let end = if i == 0 {
|
||||
first_chunk_size
|
||||
} else {
|
||||
(i + 1) * chunk_size
|
||||
};
|
||||
|
||||
// This assumes w == h
|
||||
for x in range(start, end) {
|
||||
let xf = x as f64;
|
||||
let xy = f64x2(xf, xf);
|
||||
|
||||
let f64x2(r, i) = xy * v_inverses - v_consts;
|
||||
rs.push(r);
|
||||
is.push(i);
|
||||
}
|
||||
|
||||
(rs, is)
|
||||
})
|
||||
});
|
||||
|
||||
for res in precalc_futures.move_iter() {
|
||||
let (rs, is) = res.unwrap();
|
||||
precalc_r.push_all_move(rs);
|
||||
precalc_i.push_all_move(is);
|
||||
}
|
||||
|
||||
assert_eq!(precalc_r.len(), w);
|
||||
assert_eq!(precalc_i.len(), h);
|
||||
|
||||
let arc_init_r = Arc::new(precalc_r);
|
||||
let arc_init_i = Arc::new(precalc_i);
|
||||
|
||||
let data = Vec::from_fn(WORKERS, |i| {
|
||||
let vec_init_r = arc_init_r.clone();
|
||||
let vec_init_i = arc_init_i.clone();
|
||||
|
||||
Future::spawn(proc () {
|
||||
let mut res: Vec<u8> = Vec::with_capacity((chunk_size * w) / 8);
|
||||
let init_r_slice = vec_init_r.as_slice();
|
||||
for &init_i in vec_init_i.slice(i * chunk_size, (i + 1) * chunk_size).iter() {
|
||||
write_line(init_i, init_r_slice, &mut res);
|
||||
}
|
||||
|
||||
res
|
||||
})
|
||||
});
|
||||
|
||||
try!(writeln!(&mut out as &mut Writer, "P4\n{} {}", w, h));
|
||||
for res in data.move_iter() {
|
||||
@ -65,15 +113,63 @@ fn mandelbrot<W: io::Writer>(w: uint, mut out: W) -> io::IoResult<()> {
|
||||
out.flush()
|
||||
}
|
||||
|
||||
fn write_line(init_i: f64, vec_init_r: &[f64], res: &mut Vec<u8>) {
|
||||
let v_init_i : f64x2 = f64x2(init_i, init_i);
|
||||
let v_2 : f64x2 = f64x2(2.0, 2.0);
|
||||
static LIMIT_SQUARED: f64 = LIMIT * LIMIT;
|
||||
|
||||
for chunk_init_r in vec_init_r.chunks(8) {
|
||||
let mut cur_byte = 0xff;
|
||||
let mut i = 0;
|
||||
|
||||
while i < 8 {
|
||||
let v_init_r = f64x2(chunk_init_r[i], chunk_init_r[i + 1]);
|
||||
let mut cur_r = v_init_r;
|
||||
let mut cur_i = v_init_i;
|
||||
let mut r_sq = v_init_r * v_init_r;
|
||||
let mut i_sq = v_init_i * v_init_i;
|
||||
|
||||
let mut b = 0;
|
||||
for _ in range(0, ITER) {
|
||||
let r = cur_r;
|
||||
let i = cur_i;
|
||||
|
||||
cur_i = v_2 * r * i + v_init_i;
|
||||
cur_r = r_sq - i_sq + v_init_r;
|
||||
|
||||
let f64x2(bit1, bit2) = r_sq + i_sq;
|
||||
|
||||
if bit1 > LIMIT_SQUARED {
|
||||
b |= 2;
|
||||
if b == 3 { break; }
|
||||
}
|
||||
|
||||
if bit2 > LIMIT_SQUARED {
|
||||
b |= 1;
|
||||
if b == 3 { break; }
|
||||
}
|
||||
|
||||
r_sq = cur_r * cur_r;
|
||||
i_sq = cur_i * cur_i;
|
||||
}
|
||||
|
||||
cur_byte = (cur_byte << 2) + b;
|
||||
i += 2;
|
||||
}
|
||||
|
||||
res.push(cur_byte^-1);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = std::os::args();
|
||||
let args = os::args();
|
||||
let args = args.as_slice();
|
||||
let res = if args.len() < 2 {
|
||||
println!("Test mode: do not dump the image because it's not utf8, \
|
||||
which interferes with the test runner.");
|
||||
mandelbrot(1000, std::io::util::NullWriter)
|
||||
mandelbrot(1000, io::util::NullWriter)
|
||||
} else {
|
||||
mandelbrot(from_str(args[1]).unwrap(), std::io::stdout())
|
||||
mandelbrot(from_str(args[1]).unwrap(), io::stdout())
|
||||
};
|
||||
res.unwrap();
|
||||
}
|
||||
|
37
src/test/run-make/graphviz-flowgraph/Makefile
Normal file
37
src/test/run-make/graphviz-flowgraph/Makefile
Normal file
@ -0,0 +1,37 @@
|
||||
-include ../tools.mk
|
||||
|
||||
FILES=f00.rs f01.rs f02.rs f03.rs f04.rs f05.rs f06.rs f07.rs \
|
||||
f08.rs f09.rs f10.rs f11.rs f12.rs f13.rs f14.rs f15.rs \
|
||||
f16.rs f17.rs f18.rs f19.rs f20.rs f21.rs f22.rs
|
||||
|
||||
|
||||
# all: $(patsubst %.rs,$(TMPDIR)/%.dot,$(FILES)) $(patsubst %.rs,$(TMPDIR)/%.pp,$(FILES))
|
||||
all: $(patsubst %.rs,$(TMPDIR)/%.check,$(FILES))
|
||||
|
||||
|
||||
RUSTC_LIB=$(RUSTC) --crate-type=lib
|
||||
|
||||
define FIND_LAST_BLOCK
|
||||
LASTBLOCKNUM_$(1) := $(shell $(RUSTC_LIB) --pretty=expanded,identified $(1) \
|
||||
| grep block
|
||||
| tail -1
|
||||
| sed -e 's@.*/\* block \([0-9]*\) \*/.*@\1@')
|
||||
endef
|
||||
|
||||
ifeq ($(findstring rustc,$(RUSTC)),)
|
||||
$(error Must set RUSTC)
|
||||
endif
|
||||
|
||||
$(TMPDIR)/%.pp: %.rs
|
||||
$(RUSTC_LIB) --pretty=expanded,identified $< -o $@
|
||||
|
||||
$(TMPDIR)/%.dot: %.rs
|
||||
$(eval $(call FIND_LAST_BLOCK,$<))
|
||||
$(RUSTC_LIB) --pretty flowgraph=$(LASTBLOCKNUM_$<) $< -o $@.tmp
|
||||
cat $@.tmp | sed -e 's@ (id=[0-9]*)@@g' \
|
||||
-e 's@\[label=""\]@@' \
|
||||
-e 's@digraph [a-zA-Z0-9_]* @digraph block @' \
|
||||
> $@
|
||||
|
||||
$(TMPDIR)/%.check: %.rs $(TMPDIR)/%.dot
|
||||
diff -u $(patsubst %.rs,$(TMPDIR)/%.dot,$<) $(patsubst %.rs,%.dot-expected.dot,$<)
|
@ -0,0 +1,7 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="block { }"];
|
||||
N0 -> N2;
|
||||
N2 -> N1;
|
||||
}
|
13
src/test/run-make/graphviz-flowgraph/f00.rs
Normal file
13
src/test/run-make/graphviz-flowgraph/f00.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn empty_0() {
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr 1"];
|
||||
N3[label="block { 1; }"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N1;
|
||||
}
|
13
src/test/run-make/graphviz-flowgraph/f01.rs
Normal file
13
src/test/run-make/graphviz-flowgraph/f01.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn lit_1() {
|
||||
1;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="local _x"];
|
||||
N3[label="block { let _x: int; }"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N1;
|
||||
}
|
13
src/test/run-make/graphviz-flowgraph/f02.rs
Normal file
13
src/test/run-make/graphviz-flowgraph/f02.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn decl_x_2() {
|
||||
let _x : int;
|
||||
}
|
13
src/test/run-make/graphviz-flowgraph/f03.dot-expected.dot
Normal file
13
src/test/run-make/graphviz-flowgraph/f03.dot-expected.dot
Normal file
@ -0,0 +1,13 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr 3"];
|
||||
N3[label="expr 33"];
|
||||
N4[label="expr 3 + 33"];
|
||||
N5[label="block { 3 + 33; }"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N4;
|
||||
N4 -> N5;
|
||||
N5 -> N1;
|
||||
}
|
13
src/test/run-make/graphviz-flowgraph/f03.rs
Normal file
13
src/test/run-make/graphviz-flowgraph/f03.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn expr_add_3() {
|
||||
3 + 33;
|
||||
}
|
11
src/test/run-make/graphviz-flowgraph/f04.dot-expected.dot
Normal file
11
src/test/run-make/graphviz-flowgraph/f04.dot-expected.dot
Normal file
@ -0,0 +1,11 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr 4"];
|
||||
N3[label="local _x"];
|
||||
N4[label="block { let _x = 4; }"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N4;
|
||||
N4 -> N1;
|
||||
}
|
13
src/test/run-make/graphviz-flowgraph/f04.rs
Normal file
13
src/test/run-make/graphviz-flowgraph/f04.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn pat_id_4() {
|
||||
let _x = 4;
|
||||
}
|
19
src/test/run-make/graphviz-flowgraph/f05.dot-expected.dot
Normal file
19
src/test/run-make/graphviz-flowgraph/f05.dot-expected.dot
Normal file
@ -0,0 +1,19 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr 5"];
|
||||
N3[label="expr 55"];
|
||||
N4[label="expr (5, 55)"];
|
||||
N5[label="local _x"];
|
||||
N6[label="local _y"];
|
||||
N7[label="pat (_x, _y)"];
|
||||
N8[label="block { let (_x, _y) = (5, 55); }"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N4;
|
||||
N4 -> N5;
|
||||
N5 -> N6;
|
||||
N6 -> N7;
|
||||
N7 -> N8;
|
||||
N8 -> N1;
|
||||
}
|
13
src/test/run-make/graphviz-flowgraph/f05.rs
Normal file
13
src/test/run-make/graphviz-flowgraph/f05.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn pat_tup_5() {
|
||||
let (_x, _y) = (5, 55);
|
||||
}
|
15
src/test/run-make/graphviz-flowgraph/f06.dot-expected.dot
Normal file
15
src/test/run-make/graphviz-flowgraph/f06.dot-expected.dot
Normal file
@ -0,0 +1,15 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr 6"];
|
||||
N3[label="expr S6{val: 6,}"];
|
||||
N4[label="local _x"];
|
||||
N5[label="pat S6{val: _x}"];
|
||||
N6[label="block { let S6{val: _x} = S6{val: 6,}; }"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N4;
|
||||
N4 -> N5;
|
||||
N5 -> N6;
|
||||
N6 -> N1;
|
||||
}
|
14
src/test/run-make/graphviz-flowgraph/f06.rs
Normal file
14
src/test/run-make/graphviz-flowgraph/f06.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
struct S6 { val: int }
|
||||
pub fn pat_struct_6() {
|
||||
let S6 { val: _x } = S6{ val: 6 };
|
||||
}
|
33
src/test/run-make/graphviz-flowgraph/f07.dot-expected.dot
Normal file
33
src/test/run-make/graphviz-flowgraph/f07.dot-expected.dot
Normal file
@ -0,0 +1,33 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr 7"];
|
||||
N3[label="expr 77"];
|
||||
N4[label="expr 777"];
|
||||
N5[label="expr 7777"];
|
||||
N6[label="expr [7, 77, 777, 7777]"];
|
||||
N7[label="expr match [7, 77, 777, 7777] { [x, y, ..] => x + y }"];
|
||||
N8[label="local x"];
|
||||
N9[label="local y"];
|
||||
N10[label="pat .."];
|
||||
N11[label="pat [x, y, ..]"];
|
||||
N12[label="expr x"];
|
||||
N13[label="expr y"];
|
||||
N14[label="expr x + y"];
|
||||
N15[label="block { match [7, 77, 777, 7777] { [x, y, ..] => x + y }; }"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N4;
|
||||
N4 -> N5;
|
||||
N5 -> N6;
|
||||
N6 -> N8;
|
||||
N8 -> N9;
|
||||
N9 -> N10;
|
||||
N10 -> N11;
|
||||
N11 -> N12;
|
||||
N12 -> N13;
|
||||
N13 -> N14;
|
||||
N14 -> N7;
|
||||
N7 -> N15;
|
||||
N15 -> N1;
|
||||
}
|
15
src/test/run-make/graphviz-flowgraph/f07.rs
Normal file
15
src/test/run-make/graphviz-flowgraph/f07.rs
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn pat_vec_7() {
|
||||
match [7, 77, 777, 7777] {
|
||||
[x, y, ..] => x + y
|
||||
};
|
||||
}
|
30
src/test/run-make/graphviz-flowgraph/f08.dot-expected.dot
Normal file
30
src/test/run-make/graphviz-flowgraph/f08.dot-expected.dot
Normal file
@ -0,0 +1,30 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr 8"];
|
||||
N3[label="local x"];
|
||||
N4[label="local _y"];
|
||||
N5[label="expr x"];
|
||||
N6[label="expr 88"];
|
||||
N7[label="expr x > 88"];
|
||||
N8[label="expr 888"];
|
||||
N9[label="expr _y"];
|
||||
N10[label="expr _y = 888"];
|
||||
N11[label="block { _y = 888; }"];
|
||||
N12[label="expr if x > 88 { _y = 888; }"];
|
||||
N13[label="block { let x = 8; let _y; if x > 88 { _y = 888; } }"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N4;
|
||||
N4 -> N5;
|
||||
N5 -> N6;
|
||||
N6 -> N7;
|
||||
N7 -> N8;
|
||||
N8 -> N9;
|
||||
N9 -> N10;
|
||||
N10 -> N11;
|
||||
N7 -> N12;
|
||||
N11 -> N12;
|
||||
N12 -> N13;
|
||||
N13 -> N1;
|
||||
}
|
16
src/test/run-make/graphviz-flowgraph/f08.rs
Normal file
16
src/test/run-make/graphviz-flowgraph/f08.rs
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn expr_if_onearm_8() {
|
||||
let x = 8; let _y;
|
||||
if x > 88 {
|
||||
_y = 888;
|
||||
}
|
||||
}
|
44
src/test/run-make/graphviz-flowgraph/f09.dot-expected.dot
Normal file
44
src/test/run-make/graphviz-flowgraph/f09.dot-expected.dot
Normal file
@ -0,0 +1,44 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr 91"];
|
||||
N3[label="local x"];
|
||||
N4[label="local _y"];
|
||||
N5[label="expr x"];
|
||||
N6[label="expr 92"];
|
||||
N7[label="expr x > 92"];
|
||||
N8[label="expr 93"];
|
||||
N9[label="expr _y"];
|
||||
N10[label="expr _y = 93"];
|
||||
N11[label="block { _y = 93; }"];
|
||||
N12[label="expr 94"];
|
||||
N13[label="expr 95"];
|
||||
N14[label="expr 94 + 95"];
|
||||
N15[label="expr _y"];
|
||||
N16[label="expr _y = 94 + 95"];
|
||||
N17[label="block { _y = 94 + 95; }"];
|
||||
N18[label="expr { _y = 94 + 95; }"];
|
||||
N19[label="expr if x > 92 { _y = 93; } else { _y = 94 + 95; }"];
|
||||
N20[label="block { let x = 91; let _y; if x > 92 { _y = 93; } else { _y = 94 + 95; } }"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N4;
|
||||
N4 -> N5;
|
||||
N5 -> N6;
|
||||
N6 -> N7;
|
||||
N7 -> N8;
|
||||
N8 -> N9;
|
||||
N9 -> N10;
|
||||
N10 -> N11;
|
||||
N7 -> N12;
|
||||
N12 -> N13;
|
||||
N13 -> N14;
|
||||
N14 -> N15;
|
||||
N15 -> N16;
|
||||
N16 -> N17;
|
||||
N17 -> N18;
|
||||
N11 -> N19;
|
||||
N18 -> N19;
|
||||
N19 -> N20;
|
||||
N20 -> N1;
|
||||
}
|
18
src/test/run-make/graphviz-flowgraph/f09.rs
Normal file
18
src/test/run-make/graphviz-flowgraph/f09.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn expr_if_twoarm_9() {
|
||||
let x = 91; let _y;
|
||||
if x > 92 {
|
||||
_y = 93;
|
||||
} else {
|
||||
_y = 94+95;
|
||||
}
|
||||
}
|
30
src/test/run-make/graphviz-flowgraph/f10.dot-expected.dot
Normal file
30
src/test/run-make/graphviz-flowgraph/f10.dot-expected.dot
Normal file
@ -0,0 +1,30 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr 10"];
|
||||
N3[label="local mut x"];
|
||||
N4[label="(dummy_node)"];
|
||||
N5[label="expr x"];
|
||||
N6[label="expr 0"];
|
||||
N7[label="expr x > 0"];
|
||||
N8[label="expr while x > 0 { x -= 1; }"];
|
||||
N9[label="expr 1"];
|
||||
N10[label="expr x"];
|
||||
N11[label="expr x -= 1"];
|
||||
N12[label="block { x -= 1; }"];
|
||||
N13[label="block { let mut x = 10; while x > 0 { x -= 1; } }"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N4;
|
||||
N4 -> N5;
|
||||
N5 -> N6;
|
||||
N6 -> N7;
|
||||
N7 -> N8;
|
||||
N7 -> N9;
|
||||
N9 -> N10;
|
||||
N10 -> N11;
|
||||
N11 -> N12;
|
||||
N12 -> N4;
|
||||
N8 -> N13;
|
||||
N13 -> N1;
|
||||
}
|
16
src/test/run-make/graphviz-flowgraph/f10.rs
Normal file
16
src/test/run-make/graphviz-flowgraph/f10.rs
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn expr_while_10() {
|
||||
let mut x = 10;
|
||||
while x > 0 {
|
||||
x -= 1;
|
||||
}
|
||||
}
|
25
src/test/run-make/graphviz-flowgraph/f11.dot-expected.dot
Normal file
25
src/test/run-make/graphviz-flowgraph/f11.dot-expected.dot
Normal file
@ -0,0 +1,25 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr 11"];
|
||||
N3[label="local mut _x"];
|
||||
N4[label="(dummy_node)"];
|
||||
N5[label="expr loop { _x -= 1; }"];
|
||||
N6[label="expr 1"];
|
||||
N7[label="expr _x"];
|
||||
N8[label="expr _x -= 1"];
|
||||
N9[label="block { _x -= 1; }"];
|
||||
N10[label="expr \"unreachable\""];
|
||||
N11[label="block { let mut _x = 11; loop { _x -= 1; } \"unreachable\"; }"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N4;
|
||||
N4 -> N6;
|
||||
N6 -> N7;
|
||||
N7 -> N8;
|
||||
N8 -> N9;
|
||||
N9 -> N4;
|
||||
N5 -> N10;
|
||||
N10 -> N11;
|
||||
N11 -> N1;
|
||||
}
|
18
src/test/run-make/graphviz-flowgraph/f11.rs
Normal file
18
src/test/run-make/graphviz-flowgraph/f11.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
pub fn expr_loop_11() {
|
||||
let mut _x = 11;
|
||||
loop {
|
||||
_x -= 1;
|
||||
}
|
||||
"unreachable";
|
||||
}
|
40
src/test/run-make/graphviz-flowgraph/f12.dot-expected.dot
Normal file
40
src/test/run-make/graphviz-flowgraph/f12.dot-expected.dot
Normal file
@ -0,0 +1,40 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr 12"];
|
||||
N3[label="local mut x"];
|
||||
N4[label="(dummy_node)"];
|
||||
N5[label="expr loop { x -= 1; if x == 2 { break ; \"unreachable\"; } }"];
|
||||
N6[label="expr 1"];
|
||||
N7[label="expr x"];
|
||||
N8[label="expr x -= 1"];
|
||||
N9[label="expr x"];
|
||||
N10[label="expr 2"];
|
||||
N11[label="expr x == 2"];
|
||||
N12[label="expr break"];
|
||||
N13[label="(dummy_node)"];
|
||||
N14[label="expr \"unreachable\""];
|
||||
N15[label="block { break ; \"unreachable\"; }"];
|
||||
N16[label="expr if x == 2 { break ; \"unreachable\"; }"];
|
||||
N17[label="block { x -= 1; if x == 2 { break ; \"unreachable\"; } }"];
|
||||
N18[label="block { let mut x = 12; loop { x -= 1; if x == 2 { break ; \"unreachable\"; } } }"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N4;
|
||||
N4 -> N6;
|
||||
N6 -> N7;
|
||||
N7 -> N8;
|
||||
N8 -> N9;
|
||||
N9 -> N10;
|
||||
N10 -> N11;
|
||||
N11 -> N12;
|
||||
N12 -> N5[label="exiting scope_0 expr break,\lexiting scope_1 stmt break ;,\lexiting scope_2 block { break ; \"unreachable\"; },\lexiting scope_3 expr if x == 2 { break ; \"unreachable\"; },\lexiting scope_4 block { x -= 1; if x == 2 { break ; \"unreachable\"; } }"];
|
||||
N13 -> N14;
|
||||
N14 -> N15;
|
||||
N11 -> N16;
|
||||
N15 -> N16;
|
||||
N16 -> N17;
|
||||
N17 -> N4;
|
||||
N5 -> N18;
|
||||
N18 -> N1;
|
||||
}
|
18
src/test/run-make/graphviz-flowgraph/f12.rs
Normal file
18
src/test/run-make/graphviz-flowgraph/f12.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
pub fn expr_loop_12() {
|
||||
let mut x = 12;
|
||||
loop {
|
||||
x -= 1;
|
||||
if x == 2 { break; "unreachable"; }
|
||||
}
|
||||
}
|
44
src/test/run-make/graphviz-flowgraph/f13.dot-expected.dot
Normal file
44
src/test/run-make/graphviz-flowgraph/f13.dot-expected.dot
Normal file
@ -0,0 +1,44 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr E13b"];
|
||||
N3[label="expr 13"];
|
||||
N4[label="expr E13b(13)"];
|
||||
N5[label="local x"];
|
||||
N6[label="local _y"];
|
||||
N7[label="expr x"];
|
||||
N8[label="expr match x { E13a => _y = 1, E13b(v) => _y = v + 1 }"];
|
||||
N9[label="local E13a"];
|
||||
N10[label="expr 1"];
|
||||
N11[label="expr _y"];
|
||||
N12[label="expr _y = 1"];
|
||||
N13[label="local v"];
|
||||
N14[label="pat E13b(v)"];
|
||||
N15[label="expr v"];
|
||||
N16[label="expr 1"];
|
||||
N17[label="expr v + 1"];
|
||||
N18[label="expr _y"];
|
||||
N19[label="expr _y = v + 1"];
|
||||
N20[label="block {\l let x = E13b(13);\l let _y;\l match x { E13a => _y = 1, E13b(v) => _y = v + 1 }\l}\l"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N4;
|
||||
N4 -> N5;
|
||||
N5 -> N6;
|
||||
N6 -> N7;
|
||||
N7 -> N9;
|
||||
N9 -> N10;
|
||||
N10 -> N11;
|
||||
N11 -> N12;
|
||||
N12 -> N8;
|
||||
N7 -> N13;
|
||||
N13 -> N14;
|
||||
N14 -> N15;
|
||||
N15 -> N16;
|
||||
N16 -> N17;
|
||||
N17 -> N18;
|
||||
N18 -> N19;
|
||||
N19 -> N8;
|
||||
N8 -> N20;
|
||||
N20 -> N1;
|
||||
}
|
18
src/test/run-make/graphviz-flowgraph/f13.rs
Normal file
18
src/test/run-make/graphviz-flowgraph/f13.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
enum E13 { E13a, E13b(int) }
|
||||
pub fn expr_match_13() {
|
||||
let x = E13b(13); let _y;
|
||||
match x {
|
||||
E13a => _y = 1,
|
||||
E13b(v) => _y = v + 1,
|
||||
}
|
||||
}
|
28
src/test/run-make/graphviz-flowgraph/f14.dot-expected.dot
Normal file
28
src/test/run-make/graphviz-flowgraph/f14.dot-expected.dot
Normal file
@ -0,0 +1,28 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr 14"];
|
||||
N3[label="local x"];
|
||||
N4[label="expr x"];
|
||||
N5[label="expr 1"];
|
||||
N6[label="expr x > 1"];
|
||||
N7[label="expr return"];
|
||||
N8[label="(dummy_node)"];
|
||||
N9[label="expr \"unreachable\""];
|
||||
N10[label="block { return; \"unreachable\"; }"];
|
||||
N11[label="expr if x > 1 { return; \"unreachable\"; }"];
|
||||
N12[label="block { let x = 14; if x > 1 { return; \"unreachable\"; } }"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N4;
|
||||
N4 -> N5;
|
||||
N5 -> N6;
|
||||
N6 -> N7;
|
||||
N7 -> N1;
|
||||
N8 -> N9;
|
||||
N9 -> N10;
|
||||
N6 -> N11;
|
||||
N10 -> N11;
|
||||
N11 -> N12;
|
||||
N12 -> N1;
|
||||
}
|
18
src/test/run-make/graphviz-flowgraph/f14.rs
Normal file
18
src/test/run-make/graphviz-flowgraph/f14.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
pub fn expr_ret_14() {
|
||||
let x = 14;
|
||||
if x > 1 {
|
||||
return;
|
||||
"unreachable";
|
||||
}
|
||||
}
|
79
src/test/run-make/graphviz-flowgraph/f15.dot-expected.dot
Normal file
79
src/test/run-make/graphviz-flowgraph/f15.dot-expected.dot
Normal file
@ -0,0 +1,79 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr 15"];
|
||||
N3[label="local mut x"];
|
||||
N4[label="expr 151"];
|
||||
N5[label="local mut y"];
|
||||
N6[label="(dummy_node)"];
|
||||
N7[label="expr \'outer:\l loop {\l \'inner:\l loop {\l if x == 1 { break \'outer ; \"unreachable\" }\l if y >= 2 { break ; \"unreachable\" }\l y -= 3;\l }\l y -= 4;\l x -= 5;\l }\l"];
|
||||
N8[label="(dummy_node)"];
|
||||
N9[label="expr \'inner:\l loop {\l if x == 1 { break \'outer ; \"unreachable\" }\l if y >= 2 { break ; \"unreachable\" }\l y -= 3;\l }\l"];
|
||||
N10[label="expr x"];
|
||||
N11[label="expr 1"];
|
||||
N12[label="expr x == 1"];
|
||||
N13[label="expr break \'outer"];
|
||||
N14[label="(dummy_node)"];
|
||||
N15[label="expr \"unreachable\""];
|
||||
N16[label="block { break \'outer ; \"unreachable\" }"];
|
||||
N17[label="expr if x == 1 { break \'outer ; \"unreachable\" }"];
|
||||
N18[label="expr y"];
|
||||
N19[label="expr 2"];
|
||||
N20[label="expr y >= 2"];
|
||||
N21[label="expr break"];
|
||||
N22[label="(dummy_node)"];
|
||||
N23[label="expr \"unreachable\""];
|
||||
N24[label="block { break ; \"unreachable\" }"];
|
||||
N25[label="expr if y >= 2 { break ; \"unreachable\" }"];
|
||||
N26[label="expr 3"];
|
||||
N27[label="expr y"];
|
||||
N28[label="expr y -= 3"];
|
||||
N29[label="block {\l if x == 1 { break \'outer ; \"unreachable\" }\l if y >= 2 { break ; \"unreachable\" }\l y -= 3;\l}\l"];
|
||||
N30[label="expr 4"];
|
||||
N31[label="expr y"];
|
||||
N32[label="expr y -= 4"];
|
||||
N33[label="expr 5"];
|
||||
N34[label="expr x"];
|
||||
N35[label="expr x -= 5"];
|
||||
N36[label="block {\l \'inner:\l loop {\l if x == 1 { break \'outer ; \"unreachable\" }\l if y >= 2 { break ; \"unreachable\" }\l y -= 3;\l }\l y -= 4;\l x -= 5;\l}\l"];
|
||||
N37[label="block {\l let mut x = 15;\l let mut y = 151;\l \'outer:\l loop {\l \'inner:\l loop {\l if x == 1 { break \'outer ; \"unreachable\" }\l if y >= 2 { break ; \"unreachable\" }\l y -= 3;\l }\l y -= 4;\l x -= 5;\l }\l}\l"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N4;
|
||||
N4 -> N5;
|
||||
N5 -> N6;
|
||||
N6 -> N8;
|
||||
N8 -> N10;
|
||||
N10 -> N11;
|
||||
N11 -> N12;
|
||||
N12 -> N13;
|
||||
N13 -> N7[label="exiting scope_0 expr break \'outer,\lexiting scope_1 stmt break \'outer ;,\lexiting scope_2 block { break \'outer ; \"unreachable\" },\lexiting scope_3 expr if x == 1 { break \'outer ; \"unreachable\" },\lexiting scope_4 stmt if x == 1 { break \'outer ; \"unreachable\" },\lexiting scope_5 block {\l if x == 1 { break \'outer ; \"unreachable\" }\l if y >= 2 { break ; \"unreachable\" }\l y -= 3;\l}\l,\lexiting scope_6 expr \'inner:\l loop {\l if x == 1 { break \'outer ; \"unreachable\" }\l if y >= 2 { break ; \"unreachable\" }\l y -= 3;\l }\l,\lexiting scope_7 stmt \'inner:\l loop {\l if x == 1 { break \'outer ; \"unreachable\" }\l if y >= 2 { break ; \"unreachable\" }\l y -= 3;\l }\l,\lexiting scope_8 block {\l \'inner:\l loop {\l if x == 1 { break \'outer ; \"unreachable\" }\l if y >= 2 { break ; \"unreachable\" }\l y -= 3;\l }\l y -= 4;\l x -= 5;\l}\l"];
|
||||
N14 -> N15;
|
||||
N15 -> N16;
|
||||
N12 -> N17;
|
||||
N16 -> N17;
|
||||
N17 -> N18;
|
||||
N18 -> N19;
|
||||
N19 -> N20;
|
||||
N20 -> N21;
|
||||
N21 -> N9[label="exiting scope_0 expr break,\lexiting scope_1 stmt break ;,\lexiting scope_2 block { break ; \"unreachable\" },\lexiting scope_3 expr if y >= 2 { break ; \"unreachable\" },\lexiting scope_4 stmt if y >= 2 { break ; \"unreachable\" },\lexiting scope_5 block {\l if x == 1 { break \'outer ; \"unreachable\" }\l if y >= 2 { break ; \"unreachable\" }\l y -= 3;\l}\l"];
|
||||
N22 -> N23;
|
||||
N23 -> N24;
|
||||
N20 -> N25;
|
||||
N24 -> N25;
|
||||
N25 -> N26;
|
||||
N26 -> N27;
|
||||
N27 -> N28;
|
||||
N28 -> N29;
|
||||
N29 -> N8;
|
||||
N9 -> N30;
|
||||
N30 -> N31;
|
||||
N31 -> N32;
|
||||
N32 -> N33;
|
||||
N33 -> N34;
|
||||
N34 -> N35;
|
||||
N35 -> N36;
|
||||
N36 -> N6;
|
||||
N7 -> N37;
|
||||
N37 -> N1;
|
||||
}
|
30
src/test/run-make/graphviz-flowgraph/f15.rs
Normal file
30
src/test/run-make/graphviz-flowgraph/f15.rs
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
pub fn expr_break_label_15() {
|
||||
let mut x = 15;
|
||||
let mut y = 151;
|
||||
'outer: loop {
|
||||
'inner: loop {
|
||||
if x == 1 {
|
||||
break 'outer;
|
||||
"unreachable"
|
||||
}
|
||||
if y >= 2 {
|
||||
break;
|
||||
"unreachable"
|
||||
}
|
||||
y -= 3;
|
||||
}
|
||||
y -= 4;
|
||||
x -= 5;
|
||||
}
|
||||
}
|
81
src/test/run-make/graphviz-flowgraph/f16.dot-expected.dot
Normal file
81
src/test/run-make/graphviz-flowgraph/f16.dot-expected.dot
Normal file
@ -0,0 +1,81 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr 16"];
|
||||
N3[label="local mut x"];
|
||||
N4[label="expr 16"];
|
||||
N5[label="local mut y"];
|
||||
N6[label="(dummy_node)"];
|
||||
N7[label="expr \'outer:\l loop {\l \'inner:\l loop {\l if x == 1 { continue \'outer ; \"unreachable\" }\l if y >= 1 { break ; \"unreachable\" }\l y -= 1;\l }\l y -= 1;\l x -= 1;\l }\l"];
|
||||
N8[label="(dummy_node)"];
|
||||
N9[label="expr \'inner:\l loop {\l if x == 1 { continue \'outer ; \"unreachable\" }\l if y >= 1 { break ; \"unreachable\" }\l y -= 1;\l }\l"];
|
||||
N10[label="expr x"];
|
||||
N11[label="expr 1"];
|
||||
N12[label="expr x == 1"];
|
||||
N13[label="expr continue \'outer"];
|
||||
N14[label="(dummy_node)"];
|
||||
N15[label="expr \"unreachable\""];
|
||||
N16[label="block { continue \'outer ; \"unreachable\" }"];
|
||||
N17[label="expr if x == 1 { continue \'outer ; \"unreachable\" }"];
|
||||
N18[label="expr y"];
|
||||
N19[label="expr 1"];
|
||||
N20[label="expr y >= 1"];
|
||||
N21[label="expr break"];
|
||||
N22[label="(dummy_node)"];
|
||||
N23[label="expr \"unreachable\""];
|
||||
N24[label="block { break ; \"unreachable\" }"];
|
||||
N25[label="expr if y >= 1 { break ; \"unreachable\" }"];
|
||||
N26[label="expr 1"];
|
||||
N27[label="expr y"];
|
||||
N28[label="expr y -= 1"];
|
||||
N29[label="block {\l if x == 1 { continue \'outer ; \"unreachable\" }\l if y >= 1 { break ; \"unreachable\" }\l y -= 1;\l}\l"];
|
||||
N30[label="expr 1"];
|
||||
N31[label="expr y"];
|
||||
N32[label="expr y -= 1"];
|
||||
N33[label="expr 1"];
|
||||
N34[label="expr x"];
|
||||
N35[label="expr x -= 1"];
|
||||
N36[label="block {\l \'inner:\l loop {\l if x == 1 { continue \'outer ; \"unreachable\" }\l if y >= 1 { break ; \"unreachable\" }\l y -= 1;\l }\l y -= 1;\l x -= 1;\l}\l"];
|
||||
N37[label="expr \"unreachable\""];
|
||||
N38[label="block {\l let mut x = 16;\l let mut y = 16;\l \'outer:\l loop {\l \'inner:\l loop {\l if x == 1 { continue \'outer ; \"unreachable\" }\l if y >= 1 { break ; \"unreachable\" }\l y -= 1;\l }\l y -= 1;\l x -= 1;\l }\l \"unreachable\";\l}\l"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N4;
|
||||
N4 -> N5;
|
||||
N5 -> N6;
|
||||
N6 -> N8;
|
||||
N8 -> N10;
|
||||
N10 -> N11;
|
||||
N11 -> N12;
|
||||
N12 -> N13;
|
||||
N13 -> N6[label="exiting scope_0 expr continue \'outer,\lexiting scope_1 stmt continue \'outer ;,\lexiting scope_2 block { continue \'outer ; \"unreachable\" },\lexiting scope_3 expr if x == 1 { continue \'outer ; \"unreachable\" },\lexiting scope_4 stmt if x == 1 { continue \'outer ; \"unreachable\" },\lexiting scope_5 block {\l if x == 1 { continue \'outer ; \"unreachable\" }\l if y >= 1 { break ; \"unreachable\" }\l y -= 1;\l}\l,\lexiting scope_6 expr \'inner:\l loop {\l if x == 1 { continue \'outer ; \"unreachable\" }\l if y >= 1 { break ; \"unreachable\" }\l y -= 1;\l }\l,\lexiting scope_7 stmt \'inner:\l loop {\l if x == 1 { continue \'outer ; \"unreachable\" }\l if y >= 1 { break ; \"unreachable\" }\l y -= 1;\l }\l,\lexiting scope_8 block {\l \'inner:\l loop {\l if x == 1 { continue \'outer ; \"unreachable\" }\l if y >= 1 { break ; \"unreachable\" }\l y -= 1;\l }\l y -= 1;\l x -= 1;\l}\l"];
|
||||
N14 -> N15;
|
||||
N15 -> N16;
|
||||
N12 -> N17;
|
||||
N16 -> N17;
|
||||
N17 -> N18;
|
||||
N18 -> N19;
|
||||
N19 -> N20;
|
||||
N20 -> N21;
|
||||
N21 -> N9[label="exiting scope_0 expr break,\lexiting scope_1 stmt break ;,\lexiting scope_2 block { break ; \"unreachable\" },\lexiting scope_3 expr if y >= 1 { break ; \"unreachable\" },\lexiting scope_4 stmt if y >= 1 { break ; \"unreachable\" },\lexiting scope_5 block {\l if x == 1 { continue \'outer ; \"unreachable\" }\l if y >= 1 { break ; \"unreachable\" }\l y -= 1;\l}\l"];
|
||||
N22 -> N23;
|
||||
N23 -> N24;
|
||||
N20 -> N25;
|
||||
N24 -> N25;
|
||||
N25 -> N26;
|
||||
N26 -> N27;
|
||||
N27 -> N28;
|
||||
N28 -> N29;
|
||||
N29 -> N8;
|
||||
N9 -> N30;
|
||||
N30 -> N31;
|
||||
N31 -> N32;
|
||||
N32 -> N33;
|
||||
N33 -> N34;
|
||||
N34 -> N35;
|
||||
N35 -> N36;
|
||||
N36 -> N6;
|
||||
N7 -> N37;
|
||||
N37 -> N38;
|
||||
N38 -> N1;
|
||||
}
|
31
src/test/run-make/graphviz-flowgraph/f16.rs
Normal file
31
src/test/run-make/graphviz-flowgraph/f16.rs
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
pub fn expr_continue_label_16() {
|
||||
let mut x = 16;
|
||||
let mut y = 16;
|
||||
'outer: loop {
|
||||
'inner: loop {
|
||||
if x == 1 {
|
||||
continue 'outer;
|
||||
"unreachable"
|
||||
}
|
||||
if y >= 1 {
|
||||
break;
|
||||
"unreachable"
|
||||
}
|
||||
y -= 1;
|
||||
}
|
||||
y -= 1;
|
||||
x -= 1;
|
||||
}
|
||||
"unreachable";
|
||||
}
|
17
src/test/run-make/graphviz-flowgraph/f17.dot-expected.dot
Normal file
17
src/test/run-make/graphviz-flowgraph/f17.dot-expected.dot
Normal file
@ -0,0 +1,17 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr 1"];
|
||||
N3[label="expr 7"];
|
||||
N4[label="expr 17"];
|
||||
N5[label="expr [1, 7, 17]"];
|
||||
N6[label="local _v"];
|
||||
N7[label="block { let _v = [1, 7, 17]; }"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N4;
|
||||
N4 -> N5;
|
||||
N5 -> N6;
|
||||
N6 -> N7;
|
||||
N7 -> N1;
|
||||
}
|
13
src/test/run-make/graphviz-flowgraph/f17.rs
Normal file
13
src/test/run-make/graphviz-flowgraph/f17.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn expr_vec_17() {
|
||||
let _v = [1, 7, 17];
|
||||
}
|
17
src/test/run-make/graphviz-flowgraph/f18.dot-expected.dot
Normal file
17
src/test/run-make/graphviz-flowgraph/f18.dot-expected.dot
Normal file
@ -0,0 +1,17 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr inner"];
|
||||
N3[label="expr inner"];
|
||||
N4[label="expr 18"];
|
||||
N5[label="expr inner(18)"];
|
||||
N6[label="expr inner(inner(18))"];
|
||||
N7[label="block {\l fn inner(x: int) -> int { x + x }\l inner(inner(18));\l}\l"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N4;
|
||||
N4 -> N5;
|
||||
N5 -> N6;
|
||||
N6 -> N7;
|
||||
N7 -> N1;
|
||||
}
|
14
src/test/run-make/graphviz-flowgraph/f18.rs
Normal file
14
src/test/run-make/graphviz-flowgraph/f18.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn expr_call_18() {
|
||||
fn inner(x:int) -> int { x + x }
|
||||
inner(inner(18));
|
||||
}
|
19
src/test/run-make/graphviz-flowgraph/f19.dot-expected.dot
Normal file
19
src/test/run-make/graphviz-flowgraph/f19.dot-expected.dot
Normal file
@ -0,0 +1,19 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr 19"];
|
||||
N3[label="expr S19{x: 19,}"];
|
||||
N4[label="local s"];
|
||||
N5[label="expr s"];
|
||||
N6[label="expr s.inner()"];
|
||||
N7[label="expr s.inner().inner()"];
|
||||
N8[label="block {\l struct S19 {\l x: int,\l }\l impl S19 {\l fn inner(self) -> S19 { S19{x: self.x + self.x,} }\l }\l let s = S19{x: 19,};\l s.inner().inner();\l}\l"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N4;
|
||||
N4 -> N5;
|
||||
N5 -> N6;
|
||||
N6 -> N7;
|
||||
N7 -> N8;
|
||||
N8 -> N1;
|
||||
}
|
16
src/test/run-make/graphviz-flowgraph/f19.rs
Normal file
16
src/test/run-make/graphviz-flowgraph/f19.rs
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn expr_method_call_19() {
|
||||
struct S19 { x: int }
|
||||
impl S19 { fn inner(self) -> S19 { S19 { x: self.x + self.x } } }
|
||||
let s = S19 { x: 19 };
|
||||
s.inner().inner();
|
||||
}
|
23
src/test/run-make/graphviz-flowgraph/f20.dot-expected.dot
Normal file
23
src/test/run-make/graphviz-flowgraph/f20.dot-expected.dot
Normal file
@ -0,0 +1,23 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr 2"];
|
||||
N3[label="expr 0"];
|
||||
N4[label="expr 20"];
|
||||
N5[label="expr [2, 0, 20]"];
|
||||
N6[label="local v"];
|
||||
N7[label="expr v"];
|
||||
N8[label="expr 20"];
|
||||
N9[label="expr v[20]"];
|
||||
N10[label="block { let v = [2, 0, 20]; v[20]; }"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N4;
|
||||
N4 -> N5;
|
||||
N5 -> N6;
|
||||
N6 -> N7;
|
||||
N7 -> N8;
|
||||
N8 -> N9;
|
||||
N9 -> N10;
|
||||
N10 -> N1;
|
||||
}
|
14
src/test/run-make/graphviz-flowgraph/f20.rs
Normal file
14
src/test/run-make/graphviz-flowgraph/f20.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn expr_index_20() {
|
||||
let v = [2, 0, 20];
|
||||
v[20];
|
||||
}
|
75
src/test/run-make/graphviz-flowgraph/f21.dot-expected.dot
Normal file
75
src/test/run-make/graphviz-flowgraph/f21.dot-expected.dot
Normal file
@ -0,0 +1,75 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr 15"];
|
||||
N3[label="local mut x"];
|
||||
N4[label="expr 151"];
|
||||
N5[label="local mut y"];
|
||||
N6[label="(dummy_node)"];
|
||||
N7[label="expr \'outer:\l loop {\l \'inner:\l loop {\l if x == 1 { break \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l y -= 3;\l x -= 5;\l }\l \"unreachable\";\l }\l"];
|
||||
N8[label="(dummy_node)"];
|
||||
N9[label="expr \'inner:\l loop {\l if x == 1 { break \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l y -= 3;\l x -= 5;\l }\l"];
|
||||
N10[label="expr x"];
|
||||
N11[label="expr 1"];
|
||||
N12[label="expr x == 1"];
|
||||
N13[label="expr break \'outer"];
|
||||
N14[label="(dummy_node)"];
|
||||
N15[label="expr \"unreachable\""];
|
||||
N16[label="block { break \'outer ; \"unreachable\"; }"];
|
||||
N17[label="expr if x == 1 { break \'outer ; \"unreachable\"; }"];
|
||||
N18[label="expr y"];
|
||||
N19[label="expr 2"];
|
||||
N20[label="expr y >= 2"];
|
||||
N21[label="expr return"];
|
||||
N22[label="(dummy_node)"];
|
||||
N23[label="expr \"unreachable\""];
|
||||
N24[label="block { return; \"unreachable\"; }"];
|
||||
N25[label="expr if y >= 2 { return; \"unreachable\"; }"];
|
||||
N26[label="expr 3"];
|
||||
N27[label="expr y"];
|
||||
N28[label="expr y -= 3"];
|
||||
N29[label="expr 5"];
|
||||
N30[label="expr x"];
|
||||
N31[label="expr x -= 5"];
|
||||
N32[label="block {\l if x == 1 { break \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l y -= 3;\l x -= 5;\l}\l"];
|
||||
N33[label="expr \"unreachable\""];
|
||||
N34[label="block {\l \'inner:\l loop {\l if x == 1 { break \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l y -= 3;\l x -= 5;\l }\l \"unreachable\";\l}\l"];
|
||||
N35[label="block {\l let mut x = 15;\l let mut y = 151;\l \'outer:\l loop {\l \'inner:\l loop {\l if x == 1 { break \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l y -= 3;\l x -= 5;\l }\l \"unreachable\";\l }\l}\l"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N4;
|
||||
N4 -> N5;
|
||||
N5 -> N6;
|
||||
N6 -> N8;
|
||||
N8 -> N10;
|
||||
N10 -> N11;
|
||||
N11 -> N12;
|
||||
N12 -> N13;
|
||||
N13 -> N7[label="exiting scope_0 expr break \'outer,\lexiting scope_1 stmt break \'outer ;,\lexiting scope_2 block { break \'outer ; \"unreachable\"; },\lexiting scope_3 expr if x == 1 { break \'outer ; \"unreachable\"; },\lexiting scope_4 stmt if x == 1 { break \'outer ; \"unreachable\"; },\lexiting scope_5 block {\l if x == 1 { break \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l y -= 3;\l x -= 5;\l}\l,\lexiting scope_6 expr \'inner:\l loop {\l if x == 1 { break \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l y -= 3;\l x -= 5;\l }\l,\lexiting scope_7 stmt \'inner:\l loop {\l if x == 1 { break \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l y -= 3;\l x -= 5;\l }\l,\lexiting scope_8 block {\l \'inner:\l loop {\l if x == 1 { break \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l y -= 3;\l x -= 5;\l }\l \"unreachable\";\l}\l"];
|
||||
N14 -> N15;
|
||||
N15 -> N16;
|
||||
N12 -> N17;
|
||||
N16 -> N17;
|
||||
N17 -> N18;
|
||||
N18 -> N19;
|
||||
N19 -> N20;
|
||||
N20 -> N21;
|
||||
N21 -> N1[label="exiting scope_0 expr \'inner:\l loop {\l if x == 1 { break \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l y -= 3;\l x -= 5;\l }\l,\lexiting scope_1 expr \'outer:\l loop {\l \'inner:\l loop {\l if x == 1 { break \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l y -= 3;\l x -= 5;\l }\l \"unreachable\";\l }\l"];
|
||||
N22 -> N23;
|
||||
N23 -> N24;
|
||||
N20 -> N25;
|
||||
N24 -> N25;
|
||||
N25 -> N26;
|
||||
N26 -> N27;
|
||||
N27 -> N28;
|
||||
N28 -> N29;
|
||||
N29 -> N30;
|
||||
N30 -> N31;
|
||||
N31 -> N32;
|
||||
N32 -> N8;
|
||||
N9 -> N33;
|
||||
N33 -> N34;
|
||||
N34 -> N6;
|
||||
N7 -> N35;
|
||||
N35 -> N1;
|
||||
}
|
30
src/test/run-make/graphviz-flowgraph/f21.rs
Normal file
30
src/test/run-make/graphviz-flowgraph/f21.rs
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
pub fn expr_break_label_21() {
|
||||
let mut x = 15;
|
||||
let mut y = 151;
|
||||
'outer: loop {
|
||||
'inner: loop {
|
||||
if x == 1 {
|
||||
break 'outer;
|
||||
"unreachable";
|
||||
}
|
||||
if y >= 2 {
|
||||
return;
|
||||
"unreachable";
|
||||
}
|
||||
y -= 3;
|
||||
x -= 5;
|
||||
}
|
||||
"unreachable";
|
||||
}
|
||||
}
|
77
src/test/run-make/graphviz-flowgraph/f22.dot-expected.dot
Normal file
77
src/test/run-make/graphviz-flowgraph/f22.dot-expected.dot
Normal file
@ -0,0 +1,77 @@
|
||||
digraph block {
|
||||
N0[label="entry"];
|
||||
N1[label="exit"];
|
||||
N2[label="expr 15"];
|
||||
N3[label="local mut x"];
|
||||
N4[label="expr 151"];
|
||||
N5[label="local mut y"];
|
||||
N6[label="(dummy_node)"];
|
||||
N7[label="expr \'outer:\l loop {\l \'inner:\l loop {\l if x == 1 { continue \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l x -= 1;\l y -= 3;\l }\l \"unreachable\";\l }\l"];
|
||||
N8[label="(dummy_node)"];
|
||||
N9[label="expr \'inner:\l loop {\l if x == 1 { continue \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l x -= 1;\l y -= 3;\l }\l"];
|
||||
N10[label="expr x"];
|
||||
N11[label="expr 1"];
|
||||
N12[label="expr x == 1"];
|
||||
N13[label="expr continue \'outer"];
|
||||
N14[label="(dummy_node)"];
|
||||
N15[label="expr \"unreachable\""];
|
||||
N16[label="block { continue \'outer ; \"unreachable\"; }"];
|
||||
N17[label="expr if x == 1 { continue \'outer ; \"unreachable\"; }"];
|
||||
N18[label="expr y"];
|
||||
N19[label="expr 2"];
|
||||
N20[label="expr y >= 2"];
|
||||
N21[label="expr return"];
|
||||
N22[label="(dummy_node)"];
|
||||
N23[label="expr \"unreachable\""];
|
||||
N24[label="block { return; \"unreachable\"; }"];
|
||||
N25[label="expr if y >= 2 { return; \"unreachable\"; }"];
|
||||
N26[label="expr 1"];
|
||||
N27[label="expr x"];
|
||||
N28[label="expr x -= 1"];
|
||||
N29[label="expr 3"];
|
||||
N30[label="expr y"];
|
||||
N31[label="expr y -= 3"];
|
||||
N32[label="block {\l if x == 1 { continue \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l x -= 1;\l y -= 3;\l}\l"];
|
||||
N33[label="expr \"unreachable\""];
|
||||
N34[label="block {\l \'inner:\l loop {\l if x == 1 { continue \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l x -= 1;\l y -= 3;\l }\l \"unreachable\";\l}\l"];
|
||||
N35[label="expr \"unreachable\""];
|
||||
N36[label="block {\l let mut x = 15;\l let mut y = 151;\l \'outer:\l loop {\l \'inner:\l loop {\l if x == 1 { continue \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l x -= 1;\l y -= 3;\l }\l \"unreachable\";\l }\l \"unreachable\";\l}\l"];
|
||||
N0 -> N2;
|
||||
N2 -> N3;
|
||||
N3 -> N4;
|
||||
N4 -> N5;
|
||||
N5 -> N6;
|
||||
N6 -> N8;
|
||||
N8 -> N10;
|
||||
N10 -> N11;
|
||||
N11 -> N12;
|
||||
N12 -> N13;
|
||||
N13 -> N6[label="exiting scope_0 expr continue \'outer,\lexiting scope_1 stmt continue \'outer ;,\lexiting scope_2 block { continue \'outer ; \"unreachable\"; },\lexiting scope_3 expr if x == 1 { continue \'outer ; \"unreachable\"; },\lexiting scope_4 stmt if x == 1 { continue \'outer ; \"unreachable\"; },\lexiting scope_5 block {\l if x == 1 { continue \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l x -= 1;\l y -= 3;\l}\l,\lexiting scope_6 expr \'inner:\l loop {\l if x == 1 { continue \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l x -= 1;\l y -= 3;\l }\l,\lexiting scope_7 stmt \'inner:\l loop {\l if x == 1 { continue \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l x -= 1;\l y -= 3;\l }\l,\lexiting scope_8 block {\l \'inner:\l loop {\l if x == 1 { continue \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l x -= 1;\l y -= 3;\l }\l \"unreachable\";\l}\l"];
|
||||
N14 -> N15;
|
||||
N15 -> N16;
|
||||
N12 -> N17;
|
||||
N16 -> N17;
|
||||
N17 -> N18;
|
||||
N18 -> N19;
|
||||
N19 -> N20;
|
||||
N20 -> N21;
|
||||
N21 -> N1[label="exiting scope_0 expr \'inner:\l loop {\l if x == 1 { continue \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l x -= 1;\l y -= 3;\l }\l,\lexiting scope_1 expr \'outer:\l loop {\l \'inner:\l loop {\l if x == 1 { continue \'outer ; \"unreachable\"; }\l if y >= 2 { return; \"unreachable\"; }\l x -= 1;\l y -= 3;\l }\l \"unreachable\";\l }\l"];
|
||||
N22 -> N23;
|
||||
N23 -> N24;
|
||||
N20 -> N25;
|
||||
N24 -> N25;
|
||||
N25 -> N26;
|
||||
N26 -> N27;
|
||||
N27 -> N28;
|
||||
N28 -> N29;
|
||||
N29 -> N30;
|
||||
N30 -> N31;
|
||||
N31 -> N32;
|
||||
N32 -> N8;
|
||||
N9 -> N33;
|
||||
N33 -> N34;
|
||||
N34 -> N6;
|
||||
N7 -> N35;
|
||||
N35 -> N36;
|
||||
N36 -> N1;
|
||||
}
|
31
src/test/run-make/graphviz-flowgraph/f22.rs
Normal file
31
src/test/run-make/graphviz-flowgraph/f22.rs
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
pub fn expr_break_label_21() {
|
||||
let mut x = 15;
|
||||
let mut y = 151;
|
||||
'outer: loop {
|
||||
'inner: loop {
|
||||
if x == 1 {
|
||||
continue 'outer;
|
||||
"unreachable";
|
||||
}
|
||||
if y >= 2 {
|
||||
return;
|
||||
"unreachable";
|
||||
}
|
||||
x -= 1;
|
||||
y -= 3;
|
||||
}
|
||||
"unreachable";
|
||||
}
|
||||
"unreachable";
|
||||
}
|
@ -11,7 +11,7 @@
|
||||
extern crate libc;
|
||||
|
||||
use std::mem;
|
||||
use std::unstable::run_in_bare_thread;
|
||||
use std::rt::thread::Thread;
|
||||
|
||||
#[link(name = "rustrt")]
|
||||
extern {
|
||||
@ -21,10 +21,10 @@ extern {
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
run_in_bare_thread(proc() {
|
||||
Thread::start(proc() {
|
||||
let i = &100;
|
||||
rust_dbg_call(callback, mem::transmute(i));
|
||||
});
|
||||
}).join();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,50 @@ fn test_rm_tempdir() {
|
||||
assert!(!path.exists());
|
||||
}
|
||||
|
||||
fn test_rm_tempdir_close() {
|
||||
let (tx, rx) = channel();
|
||||
let f: proc():Send = proc() {
|
||||
let tmp = TempDir::new("test_rm_tempdir").unwrap();
|
||||
tx.send(tmp.path().clone());
|
||||
tmp.close();
|
||||
fail!("fail to unwind past `tmp`");
|
||||
};
|
||||
task::try(f);
|
||||
let path = rx.recv();
|
||||
assert!(!path.exists());
|
||||
|
||||
let tmp = TempDir::new("test_rm_tempdir").unwrap();
|
||||
let path = tmp.path().clone();
|
||||
let f: proc():Send = proc() {
|
||||
let tmp = tmp;
|
||||
tmp.close();
|
||||
fail!("fail to unwind past `tmp`");
|
||||
};
|
||||
task::try(f);
|
||||
assert!(!path.exists());
|
||||
|
||||
let path;
|
||||
{
|
||||
let f = proc() {
|
||||
TempDir::new("test_rm_tempdir").unwrap()
|
||||
};
|
||||
let tmp = task::try(f).ok().expect("test_rm_tmdir");
|
||||
path = tmp.path().clone();
|
||||
assert!(path.exists());
|
||||
tmp.close();
|
||||
}
|
||||
assert!(!path.exists());
|
||||
|
||||
let path;
|
||||
{
|
||||
let tmp = TempDir::new("test_rm_tempdir").unwrap();
|
||||
path = tmp.unwrap();
|
||||
}
|
||||
assert!(path.exists());
|
||||
fs::rmdir_recursive(&path);
|
||||
assert!(!path.exists());
|
||||
}
|
||||
|
||||
// Ideally these would be in std::os but then core would need
|
||||
// to depend on std
|
||||
fn recursive_mkdir_rel() {
|
||||
@ -130,6 +174,19 @@ pub fn test_rmdir_recursive_ok() {
|
||||
assert!(!root.join("bar").join("blat").exists());
|
||||
}
|
||||
|
||||
pub fn dont_double_fail() {
|
||||
let r: Result<(), _> = task::try(proc() {
|
||||
let tmpdir = TempDir::new("test").unwrap();
|
||||
// Remove the temporary directory so that TempDir sees
|
||||
// an error on drop
|
||||
fs::rmdir(tmpdir.path());
|
||||
// Trigger failure. If TempDir fails *again* due to the rmdir
|
||||
// error then the process will abort.
|
||||
fail!();
|
||||
});
|
||||
assert!(r.is_err());
|
||||
}
|
||||
|
||||
fn in_tmpdir(f: ||) {
|
||||
let tmpdir = TempDir::new("test").expect("can't make tmpdir");
|
||||
assert!(os::change_dir(tmpdir.path()));
|
||||
@ -140,8 +197,10 @@ fn in_tmpdir(f: ||) {
|
||||
pub fn main() {
|
||||
in_tmpdir(test_tempdir);
|
||||
in_tmpdir(test_rm_tempdir);
|
||||
in_tmpdir(test_rm_tempdir_close);
|
||||
in_tmpdir(recursive_mkdir_rel);
|
||||
in_tmpdir(recursive_mkdir_dot);
|
||||
in_tmpdir(recursive_mkdir_rel_2);
|
||||
in_tmpdir(test_rmdir_recursive_ok);
|
||||
in_tmpdir(dont_double_fail);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user