Skip to content

Commit 0268cb7

Browse files
jrudermanbrson
authored andcommitted
Get expr-moving fuzzer working again
1 parent acac6ab commit 0268cb7

File tree

1 file changed

+81
-64
lines changed

1 file changed

+81
-64
lines changed

src/fuzzer/fuzzer.rs

Lines changed: 81 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,6 @@ import rustc::syntax::codemap;
2121
import rustc::syntax::parse::parser;
2222
import rustc::syntax::print::pprust;
2323

24-
/*
25-
// Imports for "the rest of driver::compile_input"
26-
import driver = rustc::driver::rustc; // see https://github.com/graydon/rust/issues/624
27-
import rustc::back::link;
28-
import rustc::driver::rustc::time;
29-
import rustc::driver::session;
30-
31-
import rustc::metadata::creader;
32-
import rustc::metadata::cstore;
33-
import rustc::syntax::parse::parser;
34-
import rustc::syntax::parse::token;
35-
import rustc::front;
36-
import rustc::front::attr;
37-
import rustc::middle;
38-
import rustc::middle::trans;
39-
import rustc::middle::resolve;
40-
import rustc::middle::ty;
41-
import rustc::middle::typeck;
42-
import rustc::middle::tstate::ck;
43-
import rustc::syntax::print::pp;
44-
import rustc::util::ppaux;
45-
import rustc::lib::llvm;
46-
*/
4724

4825
fn read_whole_file(filename: &str) -> str {
4926
str::unsafe_from_bytes_ivec(ioivec::file_reader(filename).read_whole_stream())
@@ -53,6 +30,8 @@ fn write_file(filename: &str, content: &str) {
5330
ioivec::file_writer(filename,
5431
~[ioivec::create,
5532
ioivec::truncate]).write_str(content);
33+
// Work around https://github.com/graydon/rust/issues/726
34+
std::run::run_program("chmod", ["644", filename]);
5635
}
5736

5837
fn file_contains(filename: &str, needle: &str) -> bool {
@@ -71,7 +50,7 @@ fn find_rust_files(files: &mutable str[], path: str) {
7150
} else { files += ~[path]; }
7251
} else if (fs::file_is_dir(path) && str::find(path, "compile-fail") == -1)
7352
{
74-
for p: str in fs::list_dir(path) { find_rust_files(files, p); }
53+
for p in fs::list_dir(path) { find_rust_files(files, p); }
7554
}
7655
}
7756

@@ -102,15 +81,10 @@ fn safe_to_steal(e: ast::expr_) -> bool {
10281
ast::expr_binary(_, _, _) { false }
10382
ast::expr_assign(_, _) { false }
10483
ast::expr_assign_op(_, _, _) { false }
105-
106-
107-
// https://github.com/graydon/rust/issues/676
108-
ast::expr_ret(option::none.) {
109-
false
110-
}
84+
ast::expr_fail(option::none.) { false /* https://github.com/graydon/rust/issues/764 */ }
85+
ast::expr_ret(option::none.) { false }
11186
ast::expr_put(option::none.) { false }
11287

113-
11488
_ {
11589
true
11690
}
@@ -175,33 +149,50 @@ fn as_str(f: fn(ioivec::writer) ) -> str {
175149
ret w.get_str();
176150
}
177151

178-
/*
179-
fn pp_variants(&ast::crate crate, &codemap::codemap cmap, &str filename) {
180-
auto exprs = steal_exprs(crate);
181-
auto exprsL = ivec::len(exprs);
152+
fn pp_variants(crate: &ast::crate, codemap: &codemap::codemap, filename: &str) {
153+
let exprs = steal_exprs(crate);
154+
let exprsL = ivec::len(exprs);
182155
if (exprsL < 100u) {
183-
for each (uint i in under(uint::min(exprsL, 20u))) {
156+
for each i: uint in under(uint::min(exprsL, 20u)) {
184157
log_err "Replacing... " + pprust::expr_to_str(@exprs.(i));
185-
for each (uint j in under(uint::min(exprsL, 5u))) {
158+
for each j: uint in under(uint::min(exprsL, 5u)) {
186159
log_err "With... " + pprust::expr_to_str(@exprs.(j));
187-
auto crate2 = @replace_expr_in_crate(crate, i, exprs.(j).node);
188-
check_roundtrip(crate2, cmap, filename + ".4.rs");
160+
let crate2 = @replace_expr_in_crate(crate, i, exprs.(j).node);
161+
// It would be best to test the *crate* for stability, but testing the
162+
// string for stability is easier and ok for now.
163+
let str3 = as_str(bind pprust::print_crate(codemap, crate2, filename,
164+
ioivec::string_reader(""), _,
165+
pprust::no_ann()));
166+
// 1u would be sane here, but the pretty-printer currently has lots of whitespace and paren issues,
167+
// and https://github.com/graydon/rust/issues/766 is hilarious.
168+
check_roundtrip_convergence(str3, 7u);
189169
}
190170
}
191171
}
192172
}
193-
*/
194173

195174
fn parse_and_print(code: &str) -> str {
196-
let filename = "";
175+
let filename = "tmp.rs";
197176
let codemap = codemap::new_codemap();
177+
//write_file(filename, code);
198178
let crate =
199179
parser::parse_crate_from_source_str(filename, code, ~[], codemap);
200180
ret as_str(bind pprust::print_crate(codemap, crate, filename,
201181
ioivec::string_reader(code), _,
202182
pprust::no_ann()));
203183
}
204184

185+
fn content_is_dangerous_to_modify(code: &str) -> bool {
186+
let dangerous_patterns = [
187+
"obj", // not safe to steal; https://github.com/graydon/rust/issues/761
188+
"#macro", // not safe to steal things inside of it, because they have a special syntax
189+
" be " // don't want to replace its child with a non-call: "Non-call expression in tail call"
190+
];
191+
192+
for p: str in dangerous_patterns { if contains(code, p) { ret true; } }
193+
ret false;
194+
}
195+
205196
fn content_is_confusing(code: &str) -> bool {
206197
let // https://github.com/graydon/rust/issues/671
207198
// https://github.com/graydon/rust/issues/669
@@ -212,14 +203,21 @@ fn content_is_confusing(code: &str) -> bool {
212203
// more precedence issues?
213204
confusing_patterns =
214205
["#macro", "][]", "][mutable]", "][mutable ]", "self", "spawn",
215-
"bind"];
216-
217-
for p: str in confusing_patterns { if contains(code, p) { ret true; } }
206+
"bind",
207+
"\n\n\n\n\n", // https://github.com/graydon/rust/issues/759
208+
" : ", // https://github.com/graydon/rust/issues/760
209+
"if ret",
210+
"alt ret",
211+
"if fail",
212+
"alt fail"
213+
];
214+
215+
for p: str in confusing_patterns { if contains(code, p) { ret true; } }
218216
ret false;
219217
}
220218

221219
fn file_is_confusing(filename: &str) -> bool {
222-
let
220+
let
223221

224222
// https://github.com/graydon/rust/issues/674
225223

@@ -231,49 +229,67 @@ fn file_is_confusing(filename: &str) -> bool {
231229
// --pretty normal"???
232230
confusing_files =
233231
["block-expr-precedence.rs", "nil-pattern.rs",
234-
"syntax-extension-fmt.rs"];
232+
"syntax-extension-fmt.rs",
233+
"newtype.rs" // modifying it hits something like https://github.com/graydon/rust/issues/670
234+
];
235235

236-
for f: str in confusing_files { if contains(filename, f) { ret true; } }
236+
for f in confusing_files { if contains(filename, f) { ret true; } }
237237

238238
ret false;
239239
}
240240

241-
fn check_roundtrip_convergence(code: &str) {
241+
fn check_roundtrip_convergence(code: &str, maxIters: uint) {
242242

243-
let i = 0;
243+
let i = 0u;
244244
let new = code;
245245
let old = code;
246246

247-
while i < 10 {
247+
while i < maxIters {
248248
old = new;
249+
if content_is_confusing(old) { ret; }
249250
new = parse_and_print(old);
250-
if content_is_confusing(new) { ret; }
251-
i += 1;
252-
log #fmt("cycle %d", i);
251+
if old == new { break; }
252+
i += 1u;
253253
}
254254

255-
256-
if old != new {
255+
if old == new {
256+
log_err #fmt("Converged after %u iterations", i);
257+
} else {
258+
log_err #fmt("Did not converge after %u iterations!", i);
257259
write_file("round-trip-a.rs", old);
258260
write_file("round-trip-b.rs", new);
259-
std::run::run_program("kdiff3",
260-
["round-trip-a.rs", "round-trip-b.rs"]);
261+
std::run::run_program("diff", ["-w", "-u", "round-trip-a.rs", "round-trip-b.rs"]);
261262
fail "Mismatch";
262263
}
263264
}
265+
264266
fn check_convergence(files: &str[]) {
265267
log_err #fmt("pp convergence tests: %u files", ivec::len(files));
266-
for file: str in files {
267-
268-
log_err #fmt("pp converge: %s", file);
268+
for file in files {
269269
if !file_is_confusing(file) {
270270
let s = read_whole_file(file);
271-
if !content_is_confusing(s) { check_roundtrip_convergence(s); }
271+
if !content_is_confusing(s) {
272+
log_err #fmt("pp converge: %s", file);
273+
// Change from 7u to 2u when https://github.com/graydon/rust/issues/759 is fixed
274+
check_roundtrip_convergence(s, 7u);
275+
}
272276
}
277+
}
278+
}
273279

274-
//pprust::print_crate(cm, crate, file, devnull(), pprust::no_ann());
275-
// Currently hits https://github.com/graydon/rust/issues/675
276-
//pp_variants(*crate, cm, file);
280+
fn check_convergence_of_variants(files: &str[]) {
281+
for file in files {
282+
if !file_is_confusing(file) {
283+
let s = read_whole_file(file);
284+
if content_is_dangerous_to_modify(s) || content_is_confusing(s) { cont; }
285+
log_err "check_convergence_of_variants: " + file;
286+
let codemap = codemap::new_codemap();
287+
let crate = parser::parse_crate_from_source_str(file, s, ~[], codemap);
288+
log_err as_str(bind pprust::print_crate(codemap, crate, file,
289+
ioivec::string_reader(s), _,
290+
pprust::no_ann()));
291+
pp_variants(*crate, codemap, file);
292+
}
277293
}
278294
}
279295

@@ -287,6 +303,7 @@ fn main(args: vec[str]) {
287303

288304
find_rust_files(files, root);
289305
check_convergence(files);
306+
check_convergence_of_variants(files);
290307
}
291308

292309
// Local Variables:

0 commit comments

Comments
 (0)