[llvm-dev] Multiple Inheritance with dyn_cast

Riley Dulin via llvm-dev llvm-dev at lists.llvm.org
Wed Jun 28 16:06:39 PDT 2017


I recently ran into an issue where I wanted to use dyn_cast with a Multiple Inheritance hierarchy. LLVM’s help page on RTTI claims that it can be done, and that Clang’s Decl and DeclContext implement it; however, when I try to use it I run into odd behavior. Here’s my sample code which doesn’t work:

struct Base {
  void *ptr;
  bool hasInfo;

struct Info {
  int size;

  static bool classof(const Base *b) { return b->hasInfo; };

struct Child : public Base {
  Child() {
    this->ptr = this;
    this->hasInfo = false;
struct ChildWithInfo : public Base, public Info {
  ChildWithInfo() {
    this->ptr = this;
    this->hasInfo = true;
    this->size = 10;

int main() {
  Base *c = new Child();
  Base *i = new ChildWithInfo();
  try {
    if (Info *inf = llvm::dyn_cast<Info>(c)) {
      throw std::string("Casted a child to an info incorrectly");
    if (Info *inf = llvm::dyn_cast<Info>(i)) {
      if (inf->size != 10) {
        std::ostringstream str;
        str << "Object was sliced: expected 10 but got " << inf->size;
        throw str.str();
    } else {
      throw std::string("Couldn't cast child with info to info");
  } catch (std::string &msg) {
    std::cout << msg << std::endl;
  delete c;
  delete i;

Basically the error is that when a `Base` is cast to an `Info`, it starts reading out of the same offset where `ptr` is stored instead of `size`.
How can I modify my class setup so that I can use this scheme safely?

Looking at `Decl` and `DeclContext`, it is unclear to me how they set things up so that the field offsets are correct, although I have a feeling
It has something to do with the `LLVM_ALIGNAS` in the class declaration of `Decl`.

Riley Dulin

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170628/b54b7c58/attachment.html>

More information about the llvm-dev mailing list