Recently, I ended up wasting a bit of time behind a UBSan failure inside Clang:
external/llvm-project/clang/include/clang/AST/Redeclarable.h:200:15: runtime error: downcast of address 0x000120e16908 which does not point to an object of type 'clang::TranslationUnitDecl' 0x000120e16908: note: object is of type 'clang::Decl' 00 00 00 00 30 b7 ff 0d 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^~~~~~~~~~~~~~~~~~~~~~~ vptr for 'clang::Decl' #0 0x10533ad48 in clang::Redeclarable<clang::TranslationUnitDecl>::Redeclarable(clang::ASTContext const&)+0xf8 (scip-clang:arm64+0x104f02d48) #1 0x10533a8d0 in clang::TranslationUnitDecl::TranslationUnitDecl(clang::ASTContext&)+0x13c (scip-clang:arm64+0x104f028d0) #2 0x10533ad88 in clang::TranslationUnitDecl::TranslationUnitDecl(clang::ASTContext&)+0x20 (scip-clang:arm64+0x104f02d88) #3 0x105388068 in clang::TranslationUnitDecl::Create(clang::ASTContext&)+0x3c (scip-clang:arm64+0x104f50068)
Turns out, it was “user error”, the default build has turned off the vptr check since when the LLVM_USE_SANITIZER=Undefined option was introduced over 8 years ago. Introduce -DLLVM_USE_SANITIZER=Undefined CMake option to build UBSan-… · llvm/llvm-project@4ee2675 · GitHub
Based on a cursory look at the code, it seems like the problem is coming up because
operator new is coming from the parent class
Decl, and LLVM’s custom RTTI system knows that
this points to a
TranslationUnitDecl, but UBSan is presumably unaware of that, so the dynamic type check it introduces for the
Is that the right assessment of the problem? If so, is turning off the check necessary because of LLVM’s custom RTTI system, or is there a way to inform UBSan to perform the checks differently?
Relatedly, does anyone know why the
function check is disabled too? It was turned off in this commit ([CMake] Add -fno-sanitize=function to UBSan bootstrap · llvm/llvm-project@ead5b93 · GitHub) without any explanation.