mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-24 12:20:00 +00:00
[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
This commit is contained in:
parent
551152f7d8
commit
229aa6d23b
@ -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``
|
||||
|
Loading…
Reference in New Issue
Block a user