Open llvmbot opened 10 years ago
Seems reasonable - h's 'x' parameter is really just foo *, isn't it?
struct bar: foo { };
bar b; h(&b);
compiles/runs/is well-defined, so far as I know. So I don't think h's call to f can be devirtualized safely.
Yes, my incorrect understanding was that array types were a bit stronger than that. I was expecting an error if passing a bar[2] for example.
I guess the only thing we can devirtualize along these lines is something like:
struct foo { virtual int f() {return 0;} }; struct zed { foo x[2]; }; int h(zed *x) { return x->x[1].f(); }
Seems reasonable - h's 'x' parameter is really just foo *, isn't it?
struct bar: foo { };
bar b; h(&b);
compiles/runs/is well-defined, so far as I know. So I don't think h's call to f can be devirtualized safely.
Extended Description
In the following example clang produces non virtual calls in g, but not in h.
struct foo { virtual int f() {return 0;} }; int g(foo x) { return x.f(); } int h(foo x[2]) { return x[0].f(); }