Ericsson / clang

Cross Translation Unit analysis capability for Clang Static Analyzer. (Fork of official clang at http://llvm.org/git/clang)
http://clang.llvm.org/
Other
15 stars 10 forks source link

UB in analyzer engine: reference binding to null pointer #487

Closed martong closed 5 years ago

martong commented 6 years ago

Asan/ubsan detects:

../../git/llvm/tools/clang/lib/Analysis/CFG.cpp:2258:22: runtime error: reference binding to null pointer of type 'clang::Decl *const'
SUMMARY: AddressSanitizer: undefined-behavior ../../git/llvm/tools/clang/lib/Analysis/CFG.cpp:2258:22 in
martong commented 6 years ago

During the import, we create a DeclGroup(Ref) which is empty. the DS DeclStmt contains this group, and then we call DS->decl_begin(), which returns a nullptr in case of an empty DeclGroup.

  if (isa<LabelDecl>(*DS->decl_begin()))

Above, in CFG.cpp, the isa is taking a const reference to it's parameter which is a nullptr in this case. Thus ubsan indicates the error.

Why do we create an empty DeclGroup? We try to import a FieldDecl (with type std::stringbuf) and lookup finds another FieldDecl with the same name, but structuralEquivalency yields they are different. This results in returning a nullptr.

The two fields are different because: stringbuf references streambuf, which references std::locale which references local::_Impl which has a friend template __use_cache. The whole chains yields false equivalency because of one inequivalency in a leaf. The leaf nodes (__use_cache) are inequivalent because the redecl chain is not built up properly, thus here

  // Determine whether we've already produced a tentative equivalence for D1.
  Decl *&EquivToD1 = Context.TentativeEquivalences[D1->getCanonicalDecl()];
  if (EquivToD1)
    return EquivToD1 == D2->getCanonicalDecl(); // <<<<<< HERE !

we bump into an other independent redecl chain, which results a false equivalency.

dkrupp commented 5 years ago

this has been fixed