[llvm-dev] Multiple Inheritance with dyn_cast

Craig Topper via llvm-dev llvm-dev at lists.llvm.org
Wed Jun 28 18:46:51 PDT 2017


I think the magic for Decl/DeclContext is the overrides of "doit" at the
bottom of DeclBase. This is replacing the default casting implementation to
make this work. Unfortunately I'm on my phone so I can't get a lot more
details.

On Wed, Jun 28, 2017 at 6:04 PM Riley Dulin via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> Hello,
>
>
>
> 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`.
>
> Regards,
>
> Riley Dulin
>
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
-- 
~Craig
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170629/0630490f/attachment.html>


More information about the llvm-dev mailing list