Open tpadioleau opened 4 months ago
I can reproduce this behavior, but I am willing to say that this is not UB - this is a static_cast
from a derived class to a base class for the CRTP pattern, which is fine as long as the object has started construction (which it has, since its base classes are already partially constructed, namely the PolymorphicObject
base class which provides the get_executor()
function that is being called via self()->get_executor()
). More precisely, this is a downcast to Bicgstab
followed by an upcast to PolymorphicObject
, we are not accessing any members of Bicgstab
, instead only members of the already constructed PolymorphicObject
. Likely, this would not give any warnings if EnableSolverBase
wasn't polymorphic, UBSAN only considers it problematic because we are using both dynamic and static polymorphism in the same class.
A more in-depth discussion of the same question: https://stackoverflow.com/questions/73172193/can-you-static-cast-this-to-a-derived-class-in-a-base-class-constructor-then-u
Thanks for taking the time to look at it. I will follow the discussion on google/sanitizers.
I agree that it may not be a UB but isn't it fragile ? In your example, EnableB
assumes that EnableA
, as part of Derived
, is already initialized right ? If someone inverts them by mistake, then it becomes UB ?
It definitely depends on the order of base classes, but in our case, it would fail very loudly because it will lead to an uninitialized shared_ptr
for the executor, so I feel somewhat okay with it. I don't think there is a way to enforce this statically.
Hello, the following C++ snippet triggers the undefined sanitizer:
The sanitizer reports
It was compiled with the following
CMakeLists.txt
using the cmake command
cmake -B build -DCMAKE_CXX_COMPILER=g++-10 -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-fsanitize=undefined -fno-omit-frame-pointer"
Thanks, Thomas