Skip to content

Commit 4642300

Browse files
jrudermanmarijnh
authored andcommitted
Make the fuzzer check for obvious errors in the 'rest of the compiler', not just the parser. (Disabled by default because it's slow and messy.)
1 parent 56d680a commit 4642300

File tree

1 file changed

+65
-6
lines changed

1 file changed

+65
-6
lines changed

src/fuzzer/fuzzer.rs

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ fn safe_to_steal(e: ast::expr_) -> bool {
8585
ast::expr_ret(option::none.) { false }
8686
ast::expr_put(option::none.) { false }
8787

88+
ast::expr_ret(_) { false /* lots of code generation issues, such as https://github.com/graydon/rust/issues/770 */ }
89+
ast::expr_fail(_) { false }
90+
8891
_ {
8992
true
9093
}
@@ -149,7 +152,7 @@ fn as_str(f: fn(ioivec::writer) ) -> str {
149152
ret w.get_str();
150153
}
151154

152-
fn pp_variants(crate: &ast::crate, codemap: &codemap::codemap, filename: &str) {
155+
fn check_variants_of_ast(crate: &ast::crate, codemap: &codemap::codemap, filename: &str) {
153156
let exprs = steal_exprs(crate);
154157
let exprsL = ivec::len(exprs);
155158
if (exprsL < 100u) {
@@ -166,11 +169,64 @@ fn pp_variants(crate: &ast::crate, codemap: &codemap::codemap, filename: &str) {
166169
// 1u would be sane here, but the pretty-printer currently has lots of whitespace and paren issues,
167170
// and https://github.com/graydon/rust/issues/766 is hilarious.
168171
check_roundtrip_convergence(str3, 7u);
172+
//check_whole_compiler(str3);
169173
}
170174
}
171175
}
172176
}
173177

178+
// We'd find more bugs if we could take an AST here, but
179+
// - that would find many "false positives" or unimportant bugs
180+
// - that would be tricky, requiring use of tasks or serialization or randomness.
181+
// This seems to find plenty of bugs as it is :)
182+
fn check_whole_compiler(code: &str) {
183+
let filename = "test.rs";
184+
write_file(filename, code);
185+
let p = std::run::program_output("/Users/jruderman/code/rust/build/stage1/rustc", ["-c", filename]);
186+
//log_err #fmt("Status: %d", p.status);
187+
//log_err "Output: " + p.out;
188+
if p.err != "" {
189+
if contains(p.err, "argument of incompatible type") {
190+
log_err "https://github.com/graydon/rust/issues/769";
191+
} else if contains(p.err, "Cannot create binary operator with two operands of differing type") {
192+
log_err "https://github.com/graydon/rust/issues/770";
193+
} else if contains(p.err, "May only branch on boolean predicates!") {
194+
log_err "https://github.com/graydon/rust/issues/770 or https://github.com/graydon/rust/issues/776";
195+
} else if contains(p.err, "Invalid constantexpr cast!") && contains(code, "!") {
196+
log_err "https://github.com/graydon/rust/issues/777";
197+
} else if contains(p.err, "Both operands to ICmp instruction are not of the same type!") && contains(code, "!") {
198+
log_err "https://github.com/graydon/rust/issues/777 #issuecomment-1678487";
199+
} else if contains(p.err, "Ptr must be a pointer to Val type!") && contains(code, "!") {
200+
log_err "https://github.com/graydon/rust/issues/779";
201+
} else if contains(p.err, "Calling a function with bad signature!") && (contains(code, "iter") || contains(code, "range")) {
202+
log_err "https://github.com/graydon/rust/issues/771 - calling an iter fails";
203+
} else if contains(p.err, "Calling a function with a bad signature!") && contains(code, "empty") {
204+
log_err "https://github.com/graydon/rust/issues/775 - possibly a modification of run-pass/import-glob-crate.rs";
205+
} else if contains(p.err, "Invalid type for pointer element!") && contains(code, "put") {
206+
log_err "https://github.com/graydon/rust/issues/773 - put put ()";
207+
} else if contains(p.err, "pointer being freed was not allocated") && contains(p.out, "Out of stack space, sorry") {
208+
log_err "https://github.com/graydon/rust/issues/768 + https://github.com/graydon/rust/issues/778"
209+
} else {
210+
log_err "Stderr: " + p.err;
211+
fail "Unfamiliar error message";
212+
}
213+
} else if contains(p.out, "non-exhaustive match failure") && contains(p.out, "alias.rs") {
214+
log_err "https://github.com/graydon/rust/issues/772";
215+
} else if contains(p.out, "non-exhaustive match failure") && contains(p.out, "trans.rs") && contains(code, "put") {
216+
log_err "https://github.com/graydon/rust/issues/774";
217+
} else if contains(p.out, "Out of stack space, sorry") {
218+
log_err "Possibly a variant of https://github.com/graydon/rust/issues/768";
219+
} else if p.status == 256 {
220+
if !contains(p.out, "error:") {
221+
fail "Exited with status 256 without a span-error";
222+
}
223+
} else if p.status == 11 {
224+
log_err "What is this I don't even";
225+
} else if p.status != 0 {
226+
fail "Unfamiliar status code";
227+
}
228+
}
229+
174230
fn parse_and_print(code: &str) -> str {
175231
let filename = "tmp.rs";
176232
let codemap = codemap::new_codemap();
@@ -186,7 +242,9 @@ fn content_is_dangerous_to_modify(code: &str) -> bool {
186242
let dangerous_patterns = [
187243
"obj", // not safe to steal; https://github.com/graydon/rust/issues/761
188244
"#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"
245+
"#", // strange representation of the arguments to #fmt, for example
246+
" be ", // don't want to replace its child with a non-call: "Non-call expression in tail call"
247+
"@" // hangs when compiling: https://github.com/graydon/rust/issues/768
190248
];
191249

192250
for p: str in dangerous_patterns { if contains(code, p) { ret true; } }
@@ -277,18 +335,18 @@ fn check_convergence(files: &str[]) {
277335
}
278336
}
279337

280-
fn check_convergence_of_variants(files: &str[]) {
338+
fn check_variants(files: &str[]) {
281339
for file in files {
282340
if !file_is_confusing(file) {
283341
let s = read_whole_file(file);
284342
if content_is_dangerous_to_modify(s) || content_is_confusing(s) { cont; }
285-
log_err "check_convergence_of_variants: " + file;
343+
log_err "check_variants: " + file;
286344
let codemap = codemap::new_codemap();
287345
let crate = parser::parse_crate_from_source_str(file, s, ~[], codemap);
288346
log_err as_str(bind pprust::print_crate(codemap, crate, file,
289347
ioivec::string_reader(s), _,
290348
pprust::no_ann()));
291-
pp_variants(*crate, codemap, file);
349+
check_variants_of_ast(*crate, codemap, file);
292350
}
293351
}
294352
}
@@ -303,7 +361,8 @@ fn main(args: vec[str]) {
303361

304362
find_rust_files(files, root);
305363
check_convergence(files);
306-
check_convergence_of_variants(files);
364+
check_variants(files);
365+
log_err "Fuzzer done";
307366
}
308367

309368
// Local Variables:

0 commit comments

Comments
 (0)