Probably, with a slightly tricky ownership issue leading to use after free (a well known source of exploits http://cwe.mitre.org/data/definitions/416.html) e.g. allocate to the heap, pass to a function which deallocates it (assuming that it has ownership) and use it after the call, e.g.
#include <stdlib.h>
#include <stdio.h>
void destroyer(int* val) {
printf("%d\n", *val);
free(val);
}
int main(int argc, char** argv) {
int* v = malloc(sizeof(int));
*v = 3;
destroyer(v);
printf("%d\n", *v);
return 0
}
Which compiles without warnings using Clang (unless -Weverything, and even then the warnings are not related to use-after-free), works "correctly" in O0 and O1 (prints "3" twice) then breaks starting at O2 (prints "3" then "0"). (note: it always prints "3" twice with GCC 4.8, showing how fun these things are)meanwhile the equivalent
fn main() {
let v = ~3;
destroyer(v);
println!("{}", *v)
}
fn destroyer(val: ~int) {
println!("{}", *val)
}
refuses to compile and explains why: test.rs:4:20: 4:21 error: use of moved value: `v`
test.rs:4 println!("{}", *v)
^
note: in expansion of format_args!
<std-macros>:224:8: 224:50 note: expansion site
<std-macros>:223:4: 225:6 note: in expansion of format!
<std-macros>:241:45: 241:63 note: expansion site
<std-macros>:240:4: 242:5 note: in expansion of println!
test.rs:4:4: 5:1 note: expansion site
test.rs:3:14: 3:15 note: `v` moved here because it has type `~int`, which is non-copyable (perhaps you meant to use clone()?)
test.rs:3 destroyer(v);
^
error: aborting due to previous error
which can be fixed either by explicitly cloning the value, or by altering the sub-function to not consider it owns the pointer (or by removing the `println!` call in `main()`, thus transferring the ownership of the pointer to the sub-function safely, of course)