Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

Missing devirtualization #19544

Open Quuxplusone opened 10 years ago

Quuxplusone commented 10 years ago
Bugzilla Link PR19545
Status NEW
Importance P normal
Reported by Rafael Ávila de Espíndola (rafael@espindo.la)
Reported on 2014-04-24 08:32:02 -0700
Last modified on 2014-09-24 10:07:37 -0700
Version unspecified
Hardware PC All
CC dblaikie@gmail.com, dgregor@apple.com, llvm-bugs@lists.llvm.org, nlewycky@google.com, zinovy.nis@gmail.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
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();
}
Quuxplusone commented 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.
Quuxplusone commented 10 years ago
(In reply to comment #1)
> 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();
}