@@ -85,6 +85,9 @@ fn safe_to_steal(e: ast::expr_) -> bool {
85
85
ast:: expr_ret( option:: none. ) { false }
86
86
ast:: expr_put( option:: none. ) { false }
87
87
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
+
88
91
_ {
89
92
true
90
93
}
@@ -149,7 +152,7 @@ fn as_str(f: fn(ioivec::writer) ) -> str {
149
152
ret w. get_str ( ) ;
150
153
}
151
154
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 ) {
153
156
let exprs = steal_exprs ( crate ) ;
154
157
let exprsL = ivec:: len ( exprs) ;
155
158
if ( exprsL < 100 u) {
@@ -166,11 +169,64 @@ fn pp_variants(crate: &ast::crate, codemap: &codemap::codemap, filename: &str) {
166
169
// 1u would be sane here, but the pretty-printer currently has lots of whitespace and paren issues,
167
170
// and https://github.com/graydon/rust/issues/766 is hilarious.
168
171
check_roundtrip_convergence ( str3, 7 u) ;
172
+ //check_whole_compiler(str3);
169
173
}
170
174
}
171
175
}
172
176
}
173
177
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
+
174
230
fn parse_and_print ( code : & str ) -> str {
175
231
let filename = "tmp.rs" ;
176
232
let codemap = codemap:: new_codemap ( ) ;
@@ -186,7 +242,9 @@ fn content_is_dangerous_to_modify(code: &str) -> bool {
186
242
let dangerous_patterns = [
187
243
"obj" , // not safe to steal; https://github.com/graydon/rust/issues/761
188
244
"#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
190
248
] ;
191
249
192
250
for p: str in dangerous_patterns { if contains ( code, p) { ret true ; } }
@@ -277,18 +335,18 @@ fn check_convergence(files: &str[]) {
277
335
}
278
336
}
279
337
280
- fn check_convergence_of_variants ( files : & str [ ] ) {
338
+ fn check_variants ( files : & str [ ] ) {
281
339
for file in files {
282
340
if !file_is_confusing ( file) {
283
341
let s = read_whole_file ( file) ;
284
342
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;
286
344
let codemap = codemap:: new_codemap ( ) ;
287
345
let crate = parser:: parse_crate_from_source_str ( file, s, ~[ ] , codemap) ;
288
346
log_err as_str( bind pprust:: print_crate ( codemap, crate , file,
289
347
ioivec:: string_reader ( s) , _,
290
348
pprust:: no_ann ( ) ) ) ;
291
- pp_variants ( * crate , codemap, file) ;
349
+ check_variants_of_ast ( * crate , codemap, file) ;
292
350
}
293
351
}
294
352
}
@@ -303,7 +361,8 @@ fn main(args: vec[str]) {
303
361
304
362
find_rust_files ( files, root) ;
305
363
check_convergence ( files) ;
306
- check_convergence_of_variants ( files) ;
364
+ check_variants ( files) ;
365
+ log_err "Fuzzer done" ;
307
366
}
308
367
309
368
// Local Variables:
0 commit comments