From 229aa6d23b7dc70e3e7cc81d385cf815ac478a80 Mon Sep 17 00:00:00 2001 From: Sean Silva Date: Sat, 16 Mar 2013 16:58:20 +0000 Subject: [docs] Discuss a potential bug to be aware of. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177224 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/HowToSetUpLLVMStyleRTTI.rst | 72 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'docs/HowToSetUpLLVMStyleRTTI.rst') diff --git a/docs/HowToSetUpLLVMStyleRTTI.rst b/docs/HowToSetUpLLVMStyleRTTI.rst index b906b25621..e0f865a141 100644 --- a/docs/HowToSetUpLLVMStyleRTTI.rst +++ b/docs/HowToSetUpLLVMStyleRTTI.rst @@ -295,6 +295,78 @@ ordering right:: | OtherSpecialSquare | Circle +A Bug to be Aware Of +-------------------- + +The example just given opens the door to bugs where the ``classof``\s are +not updated to match the ``Kind`` enum when adding (or removing) classes to +(from) the hierarchy. + +Continuing the example above, suppose we add a ``SomewhatSpecialSquare`` as +a subclass of ``Square``, and update the ``ShapeKind`` enum like so: + +.. code-block:: c++ + + enum ShapeKind { + SK_Square, + SK_SpecialSquare, + SK_OtherSpecialSquare, + + SK_SomewhatSpecialSquare, + SK_Circle + } + +Now, suppose that we forget to update ``Square::classof()``, so it still +looks like: + +.. code-block:: c++ + + static bool classof(const Shape *S) { + // BUG: Returns false when S->getKind() == SK_SomewhatSpecialSquare, + // even though SomewhatSpecialSquare "is a" Square. + return S->getKind() >= SK_Square && + S->getKind() <= SK_OtherSpecialSquare; + } + +As the comment indicates, this code contains a bug. A straightforward and +non-clever way to avoid this is to introduce an explicit ``SK_LastSquare`` +entry in the enum when adding the first subclass(es). For example, we could +rewrite the example at the beginning of `Concrete Bases and Deeper +Hierarchies`_ as: + +.. code-block:: c++ + + enum ShapeKind { + SK_Square, + + SK_SpecialSquare, + + SK_OtherSpecialSquare, + + SK_LastSquare, + SK_Circle + } + ... + // Square::classof() + - static bool classof(const Shape *S) { + - return S->getKind() == SK_Square; + - } + + static bool classof(const Shape *S) { + + return S->getKind() >= SK_Square && + + S->getKind() <= SK_LastSquare; + + } + +Then, adding new subclasses is easy: + +.. code-block:: c++ + + enum ShapeKind { + SK_Square, + SK_SpecialSquare, + SK_OtherSpecialSquare, + + SK_SomewhatSpecialSquare, + SK_LastSquare, + SK_Circle + } + +Notice that ``Square::classof`` does not need to be changed. + .. _classof-contract: The Contract of ``classof`` -- cgit v1.2.3