diff --git a/mk/rt.mk b/mk/rt.mk index 9dbbcbebb979d..14b8abb12b8fc 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -245,7 +245,7 @@ COMPRT_AR_$(1) := $$(AR_$(1)) # We chomp -Werror here because GCC warns about the type signature of # builtins not matching its own and the build fails. It's a bit hacky, # but what can we do, we're building libclang-rt using GCC ...... -COMPRT_CFLAGS_$(1) := $$(subst -Werror,,$$(CFG_GCCISH_CFLAGS_$(1))) -std=c99 +COMPRT_CFLAGS_$(1) := $$(filter-out -Werror -Werror=*,$$(CFG_GCCISH_CFLAGS_$(1))) -std=c99 # FreeBSD Clang's packaging is problematic; it doesn't copy unwind.h to # the standard include directory. This should really be in our changes to diff --git a/mk/tests.mk b/mk/tests.mk index 19587a28d5594..2cc1a612cc9f3 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -1048,7 +1048,8 @@ $(3)/test/run-make/%-$(1)-T-$(2)-H-$(3).ok: \ $$(S) \ $(3) \ "$$(LLVM_LIBDIR_RUSTFLAGS_$(3))" \ - "$$(LLVM_ALL_COMPONENTS_$(3))" + "$$(LLVM_ALL_COMPONENTS_$(3))" \ + "$$(LLVM_CXXFLAGS_$(3))" @touch -r $$@.start_time $$@ && rm $$@.start_time else # FIXME #11094 - The above rule doesn't work right for multiple targets diff --git a/src/etc/maketest.py b/src/etc/maketest.py index 34c2cdbef3538..275785f874605 100644 --- a/src/etc/maketest.py +++ b/src/etc/maketest.py @@ -55,6 +55,7 @@ def convert_path_spec(name, value): putenv('S', os.path.abspath(sys.argv[13])) putenv('RUSTFLAGS', sys.argv[15]) putenv('LLVM_COMPONENTS', sys.argv[16]) +putenv('LLVM_CXXFLAGS', sys.argv[17]) putenv('PYTHON', sys.executable) os.putenv('TARGET', target_triple) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index a49b7304643cc..805d9a9807a33 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1505,6 +1505,20 @@ impl<'a> From<&'a str> for Vec { // Clone-on-write //////////////////////////////////////////////////////////////////////////////// +#[stable(feature = "cow_from_vec", since = "1.7.0")] +impl<'a, T: Clone> From<&'a [T]> for Cow<'a, [T]> { + fn from(s: &'a [T]) -> Cow<'a, [T]> { + Cow::Borrowed(s) + } +} + +#[stable(feature = "cow_from_vec", since = "1.7.0")] +impl<'a, T: Clone> From> for Cow<'a, [T]> { + fn from(v: Vec) -> Cow<'a, [T]> { + Cow::Owned(v) + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> FromIterator for Cow<'a, [T]> where T: Clone { fn from_iter>(it: I) -> Cow<'a, [T]> { diff --git a/src/libcollectionstest/str.rs b/src/libcollectionstest/str.rs index 0fde70aacdca9..25457043a9df4 100644 --- a/src/libcollectionstest/str.rs +++ b/src/libcollectionstest/str.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::borrow::Cow; use std::cmp::Ordering::{Equal, Greater, Less}; use std::str::from_utf8; @@ -1267,6 +1268,16 @@ fn test_box_slice_clone() { assert_eq!(data, data2); } +#[test] +fn test_cow_from() { + let borrowed = "borrowed"; + let owned = String::from("owned"); + match (Cow::from(owned.clone()), Cow::from(borrowed)) { + (Cow::Owned(o), Cow::Borrowed(b)) => assert!(o == owned && b == borrowed), + _ => panic!("invalid `Cow::from`"), + } +} + mod pattern { use std::str::pattern::Pattern; use std::str::pattern::{Searcher, ReverseSearcher}; diff --git a/src/libcollectionstest/vec.rs b/src/libcollectionstest/vec.rs index b799be218e624..6a47f16c5ca77 100644 --- a/src/libcollectionstest/vec.rs +++ b/src/libcollectionstest/vec.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::borrow::Cow; use std::iter::{FromIterator, repeat}; use std::mem::size_of; @@ -466,6 +467,16 @@ fn test_into_iter_count() { assert_eq!(vec![1, 2, 3].into_iter().count(), 3); } +#[test] +fn test_cow_from() { + let borrowed: &[_] = &["borrowed", "(slice)"]; + let owned = vec!["owned", "(vec)"]; + match (Cow::from(owned.clone()), Cow::from(borrowed)) { + (Cow::Owned(o), Cow::Borrowed(b)) => assert!(o == owned && b == borrowed), + _ => panic!("invalid `Cow::from`"), + } +} + #[bench] fn bench_new(b: &mut Bencher) { b.iter(|| { diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs index dee9fb3447b45..7c98868dfe7c6 100644 --- a/src/librustc_trans/trans/cleanup.rs +++ b/src/librustc_trans/trans/cleanup.rs @@ -200,6 +200,7 @@ pub enum UnwindKind { pub struct CachedEarlyExit { label: EarlyExitLabel, cleanup_block: BasicBlockRef, + last_cleanup: usize, } pub trait Cleanup<'tcx> { @@ -560,7 +561,7 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> { for scope in self.scopes.borrow_mut().iter_mut().rev() { if scope.kind.is_ast_with_id(cleanup_scope) { scope.cleanups.push(cleanup); - scope.clear_cached_exits(); + scope.cached_landing_pad = None; return; } else { // will be adding a cleanup to some enclosing scope @@ -585,7 +586,7 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> { let mut scopes = self.scopes.borrow_mut(); let scope = &mut (*scopes)[custom_scope.index]; scope.cleanups.push(cleanup); - scope.clear_cached_exits(); + scope.cached_landing_pad = None; } /// Returns true if there are pending cleanups that should execute on panic. @@ -723,6 +724,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx let orig_scopes_len = self.scopes_len(); let mut prev_llbb; let mut popped_scopes = vec!(); + let mut skip = 0; // First we pop off all the cleanup stacks that are // traversed until the exit is reached, pushing them @@ -769,20 +771,25 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx } } + // Pop off the scope, since we may be generating + // unwinding code for it. + let top_scope = self.pop_scope(); + let cached_exit = top_scope.cached_early_exit(label); + popped_scopes.push(top_scope); + // Check if we have already cached the unwinding of this // scope for this label. If so, we can stop popping scopes // and branch to the cached label, since it contains the // cleanups for any subsequent scopes. - if let Some(exit) = self.top_scope(|s| s.cached_early_exit(label)) { + if let Some((exit, last_cleanup)) = cached_exit { prev_llbb = exit; + skip = last_cleanup; break; } - // Pop off the scope, since we will be generating - // unwinding code for it. If we are searching for a loop exit, + // If we are searching for a loop exit, // and this scope is that loop, then stop popping and set // `prev_llbb` to the appropriate exit block from the loop. - popped_scopes.push(self.pop_scope()); let scope = popped_scopes.last().unwrap(); match label { UnwindExit(..) | ReturnExit => { } @@ -826,13 +833,15 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx let bcx_in = self.new_block(&name[..], None); let exit_label = label.start(bcx_in); let mut bcx_out = bcx_in; - for cleanup in scope.cleanups.iter().rev() { + let len = scope.cleanups.len(); + for cleanup in scope.cleanups.iter().rev().take(len - skip) { bcx_out = cleanup.trans(bcx_out, scope.debug_loc); } + skip = 0; exit_label.branch(bcx_out, prev_llbb); prev_llbb = bcx_in.llbb; - scope.add_cached_early_exit(exit_label, prev_llbb); + scope.add_cached_early_exit(exit_label, prev_llbb, len); } self.push_scope(scope); } @@ -938,18 +947,20 @@ impl<'blk, 'tcx> CleanupScope<'blk, 'tcx> { fn cached_early_exit(&self, label: EarlyExitLabel) - -> Option { - self.cached_early_exits.iter(). + -> Option<(BasicBlockRef, usize)> { + self.cached_early_exits.iter().rev(). find(|e| e.label == label). - map(|e| e.cleanup_block) + map(|e| (e.cleanup_block, e.last_cleanup)) } fn add_cached_early_exit(&mut self, label: EarlyExitLabel, - blk: BasicBlockRef) { + blk: BasicBlockRef, + last_cleanup: usize) { self.cached_early_exits.push( CachedEarlyExit { label: label, - cleanup_block: blk }); + cleanup_block: blk, + last_cleanup: last_cleanup}); } /// True if this scope has cleanups that need unwinding diff --git a/src/libsyntax/errors/emitter.rs b/src/libsyntax/errors/emitter.rs index 94bbd1bd12816..4272f281edb44 100644 --- a/src/libsyntax/errors/emitter.rs +++ b/src/libsyntax/errors/emitter.rs @@ -410,7 +410,7 @@ impl EmitterWriter { chars.next(); } } - if (col - col_ptr) > 1 { + if (col - col_ptr) > 0 { // One extra squiggly is replaced by a "^" s.pop(); } @@ -962,7 +962,7 @@ mod test { _____\n\ ddd__eee_\n\ elided\n\ - _ff_gg"; + __f_gg"; let file = cm.new_filemap_and_lines("dummy.txt", inp); let span = |lo, hi, (off_lo, off_hi)| { @@ -976,7 +976,7 @@ mod test { let sp1 = span(0, 6, (0, 5)); let sp2 = span(8, 8, (0, 3)); let sp3 = span(8, 8, (5, 8)); - let sp4 = span(10, 10, (1, 3)); + let sp4 = span(10, 10, (2, 3)); let sp5 = span(10, 10, (4, 6)); let expect0 = "dummy.txt: 5 ccccc\n\ @@ -986,8 +986,8 @@ mod test { dummy.txt: 9 ddd__eee_\n\ \x20 ^~~ ^~~\n\ \x20 ...\n\ - dummy.txt:11 _ff_gg\n\ - \x20 ^~ ^~\n"; + dummy.txt:11 __f_gg\n\ + \x20 ^ ^~\n"; let expect = "dummy.txt: 1 aaaaa\n\ dummy.txt: 2 aaaaa\n\ @@ -1008,8 +1008,8 @@ mod test { let expect2 = "dummy.txt: 9 ddd__eee_\n\ \x20 ^~~ ^~~\n\ \x20 ...\n\ - dummy.txt:11 _ff_gg\n\ - \x20 ^~ ^~\n"; + dummy.txt:11 __f_gg\n\ + \x20 ^ ^~\n"; let expect_end = "dummy.txt: 1 aaaaa\n\ @@ -1020,7 +1020,7 @@ mod test { dummy.txt: 9 ddd__eee_\n\ \x20 ^ ^\n\ \x20 ...\n\ - dummy.txt:11 _ff_gg\n\ + dummy.txt:11 __f_gg\n\ \x20 ^ ^\n"; let expect0_end = "dummy.txt: 5 ccccc\n\ @@ -1031,7 +1031,7 @@ mod test { dummy.txt: 9 ddd__eee_\n\ \x20 ^ ^\n\ \x20 ...\n\ - dummy.txt:11 _ff_gg\n\ + dummy.txt:11 __f_gg\n\ \x20 ^ ^\n"; let expect_end_g1 = "dummy.txt:1 aaaaa\n\ @@ -1042,7 +1042,7 @@ mod test { let expect2_end = "dummy.txt: 9 ddd__eee_\n\ \x20 ^ ^\n\ \x20 ...\n\ - dummy.txt:11 _ff_gg\n\ + dummy.txt:11 __f_gg\n\ \x20 ^ ^\n"; let expect_groups = [expect2, expect_g1]; diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index 919540724ca6d..dcaa96446036b 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -63,7 +63,6 @@ pub mod decodable; pub mod hash; pub mod debug; pub mod default; -pub mod primitive; #[path="cmp/partial_eq.rs"] pub mod partial_eq; @@ -178,8 +177,6 @@ derive_traits! { "Default" => default::expand_deriving_default, - "FromPrimitive" => primitive::expand_deriving_from_primitive, - "Send" => bounds::expand_deriving_unsafe_bound, "Sync" => bounds::expand_deriving_unsafe_bound, "Copy" => bounds::expand_deriving_copy, diff --git a/src/libsyntax_ext/deriving/primitive.rs b/src/libsyntax_ext/deriving/primitive.rs deleted file mode 100644 index 121fe01976ef7..0000000000000 --- a/src/libsyntax_ext/deriving/primitive.rs +++ /dev/null @@ -1,142 +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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use deriving::generic::*; -use deriving::generic::ty::*; - -use syntax::ast::{MetaItem, Expr}; -use syntax::ast; -use syntax::codemap::Span; -use syntax::ext::base::{ExtCtxt, Annotatable}; -use syntax::ext::build::AstBuilder; -use syntax::parse::token::InternedString; -use syntax::ptr::P; - -pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Annotatable, - push: &mut FnMut(Annotatable)) -{ - let inline = cx.meta_word(span, InternedString::new("inline")); - let attrs = vec!(cx.attribute(span, inline)); - let trait_def = TraitDef { - span: span, - attributes: Vec::new(), - path: path_std!(cx, core::num::FromPrimitive), - additional_bounds: Vec::new(), - generics: LifetimeBounds::empty(), - is_unsafe: false, - methods: vec!( - MethodDef { - name: "from_i64", - generics: LifetimeBounds::empty(), - explicit_self: None, - args: vec!(Literal(path_local!(i64))), - ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option), - None, - vec!(Box::new(Self_)), - true)), - // #[inline] liable to cause code-bloat - attributes: attrs.clone(), - is_unsafe: false, - combine_substructure: combine_substructure(Box::new(|c, s, sub| { - cs_from("i64", c, s, sub) - })), - }, - MethodDef { - name: "from_u64", - generics: LifetimeBounds::empty(), - explicit_self: None, - args: vec!(Literal(path_local!(u64))), - ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option), - None, - vec!(Box::new(Self_)), - true)), - // #[inline] liable to cause code-bloat - attributes: attrs, - is_unsafe: false, - combine_substructure: combine_substructure(Box::new(|c, s, sub| { - cs_from("u64", c, s, sub) - })), - } - ), - associated_types: Vec::new(), - }; - - trait_def.expand(cx, mitem, item, push) -} - -fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P { - let n = match (substr.nonself_args.len(), substr.nonself_args.get(0)) { - (1, Some(o_f)) => o_f, - _ => cx.span_bug(trait_span, "incorrect number of arguments in `derive(FromPrimitive)`") - }; - - match *substr.fields { - StaticStruct(..) => { - cx.span_err(trait_span, "`FromPrimitive` cannot be derived for structs"); - return cx.expr_fail(trait_span, InternedString::new("")); - } - StaticEnum(enum_def, _) => { - if enum_def.variants.is_empty() { - cx.span_err(trait_span, - "`FromPrimitive` cannot be derived for enums with no variants"); - return cx.expr_fail(trait_span, InternedString::new("")); - } - - let mut arms = Vec::new(); - - for variant in &enum_def.variants { - let def = &variant.node.data; - if !def.is_unit() { - cx.span_err(trait_span, "`FromPrimitive` cannot be derived \ - for enums with non-unit variants"); - return cx.expr_fail(trait_span, - InternedString::new("")); - } - - let span = variant.span; - - // expr for `$n == $variant as $name` - let path = cx.path(span, vec![substr.type_ident, variant.node.name]); - let variant = cx.expr_path(path); - let ty = cx.ty_ident(span, cx.ident_of(name)); - let cast = cx.expr_cast(span, variant.clone(), ty); - let guard = cx.expr_binary(span, ast::BiEq, n.clone(), cast); - - // expr for `Some($variant)` - let body = cx.expr_some(span, variant); - - // arm for `_ if $guard => $body` - let arm = ast::Arm { - attrs: vec!(), - pats: vec!(cx.pat_wild(span)), - guard: Some(guard), - body: body, - }; - - arms.push(arm); - } - - // arm for `_ => None` - let arm = ast::Arm { - attrs: vec!(), - pats: vec!(cx.pat_wild(trait_span)), - guard: None, - body: cx.expr_none(trait_span), - }; - arms.push(arm); - - cx.expr_match(trait_span, n.clone(), arms) - } - _ => cx.span_bug(trait_span, "expected StaticEnum in derive(FromPrimitive)") - } -} diff --git a/src/test/codegen/drop.rs b/src/test/codegen/drop.rs new file mode 100644 index 0000000000000..2ac8de6d80294 --- /dev/null +++ b/src/test/codegen/drop.rs @@ -0,0 +1,47 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] + +struct SomeUniqueName; + +impl Drop for SomeUniqueName { + fn drop(&mut self) { + } +} + +pub fn possibly_unwinding() { +} + +// CHECK-LABEL: @droppy +#[no_mangle] +pub fn droppy() { +// Check that there are exactly 6 drop calls. The cleanups for the unwinding should be reused, so +// that's one new drop call per call to possibly_unwinding(), and finally 3 drop calls for the +// regular function exit. We used to have problems with quadratic growths of drop calls in such +// functions. +// CHECK: call{{.*}}SomeUniqueName{{.*}}drop +// CHECK: call{{.*}}SomeUniqueName{{.*}}drop +// CHECK: call{{.*}}SomeUniqueName{{.*}}drop +// CHECK: call{{.*}}SomeUniqueName{{.*}}drop +// CHECK: call{{.*}}SomeUniqueName{{.*}}drop +// CHECK: call{{.*}}SomeUniqueName{{.*}}drop +// CHECK-NOT: call{{.*}}SomeUniqueName{{.*}}drop +// The next line checks for the } that ends the function definition +// CHECK-LABEL: {{^[}]}} + let _s = SomeUniqueName; + possibly_unwinding(); + let _s = SomeUniqueName; + possibly_unwinding(); + let _s = SomeUniqueName; + possibly_unwinding(); +} diff --git a/src/test/compile-fail/deriving-primitive.rs b/src/test/compile-fail/deriving-primitive.rs index e8e37d8804986..be822a173ab58 100644 --- a/src/test/compile-fail/deriving-primitive.rs +++ b/src/test/compile-fail/deriving-primitive.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,27 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::num::FromPrimitive; -use std::isize; +#[derive(FromPrimitive)] //~ERROR `#[derive]` for custom traits is not stable +enum Foo {} -#[derive(FromPrimitive)] -struct A { x: isize } -//~^^ ERROR `FromPrimitive` cannot be derived for structs -//~^^^ ERROR `FromPrimitive` cannot be derived for structs +fn main() {} -#[derive(FromPrimitive)] -struct B(isize); -//~^^ ERROR `FromPrimitive` cannot be derived for structs -//~^^^ ERROR `FromPrimitive` cannot be derived for structs - -#[derive(FromPrimitive)] -enum C { Foo(isize), Bar(usize) } -//~^^ ERROR `FromPrimitive` cannot be derived for enums with non-unit variants -//~^^^ ERROR `FromPrimitive` cannot be derived for enums with non-unit variants - -#[derive(FromPrimitive)] -enum D { Baz { x: isize } } -//~^^ ERROR `FromPrimitive` cannot be derived for enums with non-unit variants -//~^^^ ERROR `FromPrimitive` cannot be derived for enums with non-unit variants - -pub fn main() {} diff --git a/src/test/run-make/llvm-module-pass/Makefile b/src/test/run-make/llvm-module-pass/Makefile new file mode 100644 index 0000000000000..188b1f72e39b2 --- /dev/null +++ b/src/test/run-make/llvm-module-pass/Makefile @@ -0,0 +1,8 @@ +-include ../tools.mk + +all: $(call NATIVE_STATICLIB,llvm-pass) + $(RUSTC) plugin.rs -C prefer-dynamic + $(RUSTC) main.rs + +$(TMPDIR)/libllvm-pass.o: + $(CXX) $(LLVM_CXXFLAGS) -c llvm-pass.so.cc -o $(TMPDIR)/libllvm-pass.o diff --git a/src/test/run-make/llvm-module-pass/llvm-pass.so.cc b/src/test/run-make/llvm-module-pass/llvm-pass.so.cc new file mode 100644 index 0000000000000..8723f24569775 --- /dev/null +++ b/src/test/run-make/llvm-module-pass/llvm-pass.so.cc @@ -0,0 +1,55 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#include +#include +#include + +#include "llvm/IR/Module.h" + +using namespace llvm; + +namespace { + + class TestLLVMPass : public ModulePass { + + public: + + static char ID; + TestLLVMPass() : ModulePass(ID) { } + + bool runOnModule(Module &M) override; + + const char *getPassName() const override { + return "Some LLVM pass"; + } + + }; + +} + +bool TestLLVMPass::runOnModule(Module &M) { + // A couple examples of operations that previously caused segmentation faults + // https://github.com/rust-lang/rust/issues/31067 + + for (auto F = M.begin(); F != M.end(); ++F) { + /* code */ + } + + LLVMContext &C = M.getContext(); + IntegerType *Int8Ty = IntegerType::getInt8Ty(C); + llvm::Type *i = PointerType::get(Int8Ty, 0); + return true; +} + +char TestLLVMPass::ID = 0; + +static RegisterPass RegisterAFLPass( + "some-llvm-pass", "Some LLVM pass"); diff --git a/src/test/run-make/llvm-module-pass/main.rs b/src/test/run-make/llvm-module-pass/main.rs new file mode 100644 index 0000000000000..5b5ab94bcef02 --- /dev/null +++ b/src/test/run-make/llvm-module-pass/main.rs @@ -0,0 +1,14 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(plugin)] +#![plugin(some_plugin)] + +fn main() {} diff --git a/src/test/run-make/llvm-module-pass/plugin.rs b/src/test/run-make/llvm-module-pass/plugin.rs new file mode 100644 index 0000000000000..039de3c717961 --- /dev/null +++ b/src/test/run-make/llvm-module-pass/plugin.rs @@ -0,0 +1,26 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(plugin_registrar, rustc_private)] +#![crate_type = "dylib"] +#![crate_name = "some_plugin"] + +extern crate rustc; +extern crate rustc_plugin; + +#[link(name = "llvm-pass", kind = "static")] +extern {} + +use rustc_plugin::registry::Registry; + +#[plugin_registrar] +pub fn plugin_registrar(reg: &mut Registry) { + reg.register_llvm_pass("some-llvm-pass"); +}