Skip to content

Conversation

@pcanal
Copy link
Member

@pcanal pcanal commented Aug 31, 2017

This introduces TStatusBitsChecker which allows to check whether there is 'Status bits' overlap in a given class hierarchy.

Expectedly, there are several overlaps ....

This merge request also annotate (by properly naming the enum type as EStatusBits) as needed and resolves the reported errors in core, io/io, tree/tree and hist/hist.

Some overlaps can not be resolve to preserve forward compatibility and after analysis of which bit is overlapping should be 'harmless' and thus are marked to be ignored by the checker tools (by adding a enum type named EStatusBitsDupExceptions).

Usage example:

return TStatusBitsChecker::CheckAlClasses();

// or without EStatusBitsDupExceptions in TStreamerElement.
TStatusBitsChecker::Check("TStreamerElement");

Error in <TStatusBitsChecker>: In TStreamerElement class hierarchy, there are duplicates bits:
Error in <TStatusBitsChecker>:    Bit   6 used in TStreamerElement as kHasRange
Error in <TStatusBitsChecker>:    Bit   6 used in TObject as kCannotPick
Error in <TStatusBitsChecker>:    Bit  13 used in TStreamerElement as kDoNotDelete
Error in <TStatusBitsChecker>:    Bit  13 used in TObject as kInvalidObject

@phsft-bot
Copy link

Starting build on centos7/gcc49, mac1012/native, slc6/gcc49, slc6/gcc62, ubuntu14/native with flags -Dvc=OFF -Dimt=ON -Dccache=ON
How to customize builds

@phsft-bot
Copy link

Build failed on slc6/gcc62.
See console output.

Failing tests:

@phsft-bot
Copy link

Build failed on mac1012/native.
See console output.

Failing tests:

@phsft-bot
Copy link

Build failed on ubuntu14/native.
See console output.

Failing tests:

@phsft-bot
Copy link

Build failed on centos7/gcc49.
See console output.

Failing tests:

@phsft-bot
Copy link

Build failed on slc6/gcc49.
See console output.

Failing tests:

Copy link
Member

@Axel-Naumann Axel-Naumann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only tiny comments - plus I don't think this really addresses the problem but any alternative is too expensive... LGTM after addressing the test failure.

enum EStatusBits {
kClassSaved = BIT(12),
kIgnoreTObjectStreamer = BIT(15),
kUnloaded = BIT(16), // The library containing the dictionary for this class was
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you're touching this anyway, can you use pre-member doxygen doc like so:

/// The library containing the dictionary for this class was
/// loaded and has been unloaded from memory.
kUnloaded    = BIT(16),

This makes it easier to read and write precise documentation and enables doxygen to actually pick it up.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The annoying part is that (visually at the very least), unless there is a empy line above the comment, I never 'know' whether the comment applies to the one before or after.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we're paid by lines of code, so adding empty lines is a wonderful thing! ;-)

kStartWithTObject = BIT(20), // see comments for IsStartingWithTObject()
kWarned = BIT(21),
kHasNameMapNode = BIT(22),
kHasCustomStreamerMember = BIT(23) // The class has a Streamer method and it is implemented by the user or an older (not StreamerInfo based) automatic streamer.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above

kWarn = BIT(14)
};

enum EStatusBitsOldValues {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you document why you have this?

kWarn = BIT(14)
};

enum EStatusBitsOldValues {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

#include "TStatusBitsChecker.h"

#include "TClass.h"
#include "TBaseClass.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The order is "almost-alphabetical" ;-)


void TStatusBitsChecker::Registry::RegisterBits(TClass &classRef /* = false */)
{
TEnum *eStatusBits = (TEnum*)classRef.GetListOfEnums()->FindObject("EStatusBits");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the name is different (as in many examples in ROOT before your patch)?
Isn't the relevant criterium that SetBit() is called on such an enum constant? That would mean we need an external tool looking at invocations...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the relevant criterium that SetBit() is called on such an enum constant? That would
mean we need an external tool looking at invocations...

Yes and it would technically have to parse the entire world's sources to find out. Doing so with the ROOT source would be a good start though :) .... Anyway, this way is 'much' cheaper (for me) to write (it would also have to deal with indirect setting and combinations SetBit(aliasOne | aliasTwo))

As importantly, having this enum clearly name helps with documentation ... (i.e if one was to write the parsing tool, it could complain that a bit is not listed in EStatusBits)

Lastly writing the EStatusBitsDupExceptions or equivalent would still be necessary in some cases ...

if (eStatusBits) {

for(auto c : *eStatusBits->GetConstants()) {
TEnumConstant *constant = dynamic_cast<TEnumConstant*>(c);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverity will be unhappy with you :-) What if the dyn_cast fails?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can't :) the 'original' version of the code was

TEnumConstant *constant = (TEnumConstant*)(c);


}

// Return false if there is any unexpected duplicates BIT constant in
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why isn't this a proper doxygen comment?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does doxygen do with this lame comment?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

humm ... actually what is our current strategy ... the official documentation is in the header files. Should we leave the source file completely undocumented?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ROOT's function doc is in the sources.

return Registry().Check(classRef,verbose);
}

// Return false if there is any unexpected duplicates BIT constant in
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doxygen?

{
bool result = true;

// start from begining
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

speling.

@vgvassilev
Copy link
Member

Could you add a gtest for this new feature?

@phsft-bot
Copy link

Starting build on centos7/gcc49, mac1012/native, slc6/gcc49, slc6/gcc62, ubuntu14/native with flags -Dvc=OFF -Dimt=ON -Dccache=ON
How to customize builds

@phsft-bot
Copy link

Starting build on centos7/gcc49, mac1012/native, slc6/gcc49, slc6/gcc62, ubuntu14/native with flags -Dvc=OFF -Dimt=ON -Dccache=ON
How to customize builds

@phsft-bot
Copy link

Build failed on ubuntu14/native.
See console output.

Failing tests:

@phsft-bot
Copy link

Build failed on mac1012/native.
See console output.

Failing tests:

@phsft-bot
Copy link

Build failed on slc6/gcc49.
See console output.

Failing tests:

@phsft-bot
Copy link

Build failed on centos7/gcc49.
See console output.

Failing tests:

@phsft-bot
Copy link

Build failed on slc6/gcc62.
See console output.

Failing tests:

It was conflicting with TObject::kCanDelete.

Even-though it is persistent information, it is only ever used when first creating the branch
and thus changing the value should have not practical down-side.
…reamerInfo

This specially named Enum will allow to annotate the EStatusBits enum to list
the bit that are intentionally/knowingly duplicated other bits in the clas
hierarchy
  TStatusBitsChecker::Check and TStatusBitsChecker::CheckAllClasses will
   determine if the set of "status bit" declared in the class and its
   base classes presents any overlap.  The status bit are declared in
   a given class by declaring an enum type named EStatusBits.
   If some of the duplication is intentional, those duplication can
   be registered in an enum type named EStatusBitsDupExceptions.

   ~~~ {.cpp}
   // TStreamerElement status bits
   enum EStatusBits {
      kHasRange     = BIT(6),
      kCache        = BIT(9),
      kRepeat       = BIT(10),
      kRead         = BIT(11),
      kWrite        = BIT(12),
      kDoNotDelete  = BIT(13),
      kWholeObject  = BIT(14)
   };

   enum class EStatusBitsDupExceptions {
      // This bit duplicates TObject::kInvalidObject. As the semantic of kDoNotDelete is a persistent,
      // we can not change its value without breaking forward compatibility.
      // Furthermore, TObject::kInvalidObject and its semantic is not (and should not be)
      // used in TStreamerElement
      kDoNotDelete  = TStreamerElement::kDoNotDelete,

      // This bit duplicates TObject::kCannotPick. As the semantic of kHasRange is a persistent,
      // we can not change its value without breaking forward compatibility.
      // Furthermore, TObject::kCannotPick and its semantic is not (and should not be)
      // used in TStreamerElement
      kHasRange = TStreamerElement::kHasRange
   };
  ~~~ {.cpp}

  Without the EStatusBitsDupExceptions enum you would see

  ~~~ {.cpp}
TStatusBitsChecker::Check("TStreamerElement");

Error in <TStatusBitsChecker>: In TStreamerElement class hierarchy, there are duplicates bits:
Error in <TStatusBitsChecker>:    Bit   6 used in TStreamerElement as kHasRange
Error in <TStatusBitsChecker>:    Bit   6 used in TObject as kCannotPick
Error in <TStatusBitsChecker>:    Bit  13 used in TStreamerElement as kDoNotDelete
Error in <TStatusBitsChecker>:    Bit  13 used in TObject as kInvalidObject
  ~~~ {.cpp}
frexp ultimately give the same information (what power of 2 is this number) but is 3 times faster
than the pair (log2, nearbyint).
…ubmerger.

Error in <TStatusBitsChecker>: In TProofPlayer class hierarchy, there are duplicates bits:
Error in <TStatusBitsChecker>:    Bit  16 used in TProofPlayer as kIsProcessing
Error in <TStatusBitsChecker>:    Bit  16 used in TVirtualProofPlayer as kIsSubmerger

Error in <TStatusBitsChecker>: In TProofServ class hierarchy, there are duplicates bits:
Error in <TStatusBitsChecker>:    Bit  16 used in TProofServ as kHighMemory
Error in <TStatusBitsChecker>:    Bit  16 used in TApplication as kDefaultApplication
@phsft-bot
Copy link

Starting build on centos7/gcc49, mac1012/native, slc6/gcc49, slc6/gcc62, ubuntu14/native with flags -Dvc=OFF -Dimt=ON -Dccache=ON
How to customize builds

@pcanal pcanal requested a review from peremato as a code owner September 1, 2017 22:06
@phsft-bot
Copy link

Starting build on centos7/gcc49, mac1012/native, slc6/gcc49, slc6/gcc62, ubuntu14/native with flags -Dvc=OFF -Dimt=ON -Dccache=ON
How to customize builds

@phsft-bot
Copy link

Build failed on centos7/gcc49.
See console output.

Failing tests:

@phsft-bot
Copy link

Build failed on ubuntu14/native.
See console output.

Failing tests:

@phsft-bot
Copy link

Build failed on mac1012/native.
See console output.

Failing tests:

@phsft-bot
Copy link

Build failed on slc6/gcc62.
See console output.

Failing tests:

@phsft-bot
Copy link

Build failed on slc6/gcc49.
See console output.

Failing tests:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants