OikawaKirie created this revision.
OikawaKirie added reviewers: aaron.ballman, avl, mehdi_amini, ilya-biryukov, 
tejohnson, jansvoboda11.
OikawaKirie added projects: LLVM, clang.
Herald added subscribers: llvm-commits, cfe-commits, dexonsmith, steven_wu, 
hiraditya.
OikawaKirie requested review of this revision.

All these potential null pointer dereferences are reported by my static 
analyzer for null smart pointer dereferences, which has a different 
implementation from `alpha.cplusplus.SmartPtr`.

The checked pointers are:

- The return value of `createArgument` in file 
clang/utils/TableGen/ClangAttrEmitter.cpp. Although there are a lot of checks 
in the function, nullptr is still allowed to be returned. As a recursive 
function it is, I added checks to all the places where the function is called.
- The local variable `Unit` in function `DWARFLinker::loadClangModule` in file 
llvm/lib/DWARFLinker/DWARFLinker.cpp. If the variable is not set in the loop 
below its definition, it will trigger a null pointer dereference after the loop.
- The local variable `Index` in function `ThinLTOCodeGenerator::run` in file 
llvm/lib/LTO/ThinLTOCodeGenerator.cpp. When function 
`ThinLTOCodeGenerator::linkCombinedIndex` returns nullptr, the pointer `Index` 
will be null and be dereferenced below.
- The parameter variable `Buffer` in function `InMemoryFileSystem::addFile` in 
file llvm/lib/Support/VirtualFileSystem.cpp. The assertion in this function 
(`assert(!(HardLinkTarget && Buffer))`) only checks whether these two 
parameters can both be non-null. But It can be inferred that both pointers can 
be null together. A null `Buffer` pointer can be dereferenced without a check.
- The return value of function `ModuleLazyLoaderCache::operator` in file 
llvm/tools/llvm-link/llvm-link.cpp. According to the bug report of my static 
analyzer, the std::function variable `ModuleLazyLoaderCache::createLazyModule` 
points to function `loadFile`, which may return nullptr when error. And the 
pointer is returned as a reference without a check to the return value.
- The local variable `Ret` in function `MarshallingKindInfo::create` in file 
`llvm/utils/TableGen/OptParserEmitter.cpp`. If not all MarshallingKind's are 
handled, variable `Ret` will be kept as nullptr.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D91844

Files:
  clang/utils/TableGen/ClangAttrEmitter.cpp
  llvm/lib/DWARFLinker/DWARFLinker.cpp
  llvm/lib/LTO/ThinLTOCodeGenerator.cpp
  llvm/lib/Support/VirtualFileSystem.cpp
  llvm/tools/llvm-link/llvm-link.cpp
  llvm/utils/TableGen/OptParserEmitter.cpp

Index: llvm/utils/TableGen/OptParserEmitter.cpp
===================================================================
--- llvm/utils/TableGen/OptParserEmitter.cpp
+++ llvm/utils/TableGen/OptParserEmitter.cpp
@@ -183,6 +183,7 @@
     Ret = std::make_unique<MarshallingInfoBooleanFlag>(
         R, *R.getValueAsDef("NegOption"));
   }
+  assert(Ret && "Unknown MarshallingInfoKind.");
 
   Ret->ShouldAlwaysEmit = R.getValueAsBit("ShouldAlwaysEmit");
   Ret->KeyPath = R.getValueAsString("KeyPath");
Index: llvm/tools/llvm-link/llvm-link.cpp
===================================================================
--- llvm/tools/llvm-link/llvm-link.cpp
+++ llvm/tools/llvm-link/llvm-link.cpp
@@ -243,8 +243,10 @@
 Module &ModuleLazyLoaderCache::operator()(const char *argv0,
                                           const std::string &Identifier) {
   auto &Module = ModuleMap[Identifier];
-  if (!Module)
+  if (!Module) {
     Module = createLazyModule(argv0, Identifier);
+    assert(Module && "Failed to create lazy module!");
+  }
   return *Module;
 }
 } // anonymous namespace
Index: llvm/lib/Support/VirtualFileSystem.cpp
===================================================================
--- llvm/lib/Support/VirtualFileSystem.cpp
+++ llvm/lib/Support/VirtualFileSystem.cpp
@@ -732,6 +732,7 @@
         if (HardLinkTarget)
           Child.reset(new detail::InMemoryHardLink(P.str(), *HardLinkTarget));
         else {
+          assert(Buffer && "Non-HardLink without a buffer?");
           // Create a new file or directory.
           Status Stat(P.str(), getNextVirtualUniqueID(),
                       llvm::sys::toTimePoint(ModificationTime), ResolvedUser,
@@ -771,6 +772,7 @@
         return false;
 
       // Return false only if the new file is different from the existing one.
+      assert(Buffer);
       if (auto Link = dyn_cast<detail::InMemoryHardLink>(Node)) {
         return Link->getResolvedFile().getBuffer()->getBuffer() ==
                Buffer->getBuffer();
Index: llvm/lib/LTO/ThinLTOCodeGenerator.cpp
===================================================================
--- llvm/lib/LTO/ThinLTOCodeGenerator.cpp
+++ llvm/lib/LTO/ThinLTOCodeGenerator.cpp
@@ -959,6 +959,7 @@
 
   // Sequential linking phase
   auto Index = linkCombinedIndex();
+  assert(Index);
 
   // Save temps: index.
   if (!SaveTempsDir.empty()) {
Index: llvm/lib/DWARFLinker/DWARFLinker.cpp
===================================================================
--- llvm/lib/DWARFLinker/DWARFLinker.cpp
+++ llvm/lib/DWARFLinker/DWARFLinker.cpp
@@ -2145,6 +2145,7 @@
       Unit->markEverythingAsKept();
     }
   }
+  assert(Unit && "CompileUnit is not set!");
   if (!Unit->getOrigUnit().getUnitDIE().hasChildren())
     return Error::success();
   if (!Quiet && Options.Verbose) {
Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===================================================================
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2311,6 +2311,7 @@
     bool HasFakeArg = false;
     for (const auto *ArgRecord : ArgRecords) {
       Args.emplace_back(createArgument(*ArgRecord, R.getName()));
+      assert(Args.back());
       if (Header) {
         Args.back()->writeDeclarations(OS);
         OS << "\n\n";
@@ -2926,6 +2927,7 @@
     Args.clear();
     for (const auto *Arg : ArgRecords) {
       Args.emplace_back(createArgument(*Arg, R.getName()));
+      assert(Args.back());
       Args.back()->writePCHReadDecls(OS);
     }
     OS << "    New = new (Context) " << R.getName() << "Attr(Context, Info";
@@ -2966,8 +2968,11 @@
     OS << "    Record.push_back(A->isImplicit());\n";
     OS << "    Record.push_back(A->isPackExpansion());\n";
 
-    for (const auto *Arg : Args)
-      createArgument(*Arg, R.getName())->writePCHWrite(OS);
+    for (const auto *Arg : Args) {
+      auto A = createArgument(*Arg, R.getName());
+      assert(A);
+      A->writePCHWrite(OS);
+    }
     OS << "    break;\n";
     OS << "  }\n";
   }
@@ -3249,8 +3254,11 @@
        << "    return false;\n";
 
     std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
-    for (const auto *Arg : ArgRecords)
-      createArgument(*Arg, R.getName())->writeASTVisitorTraversal(OS);
+    for (const auto *Arg : ArgRecords) {
+      auto A = createArgument(*Arg, R.getName());
+      assert(A);
+      A->writeASTVisitorTraversal(OS);
+    }
 
     OS << "  return true;\n";
     OS << "}\n\n";
@@ -3313,8 +3321,10 @@
     std::vector<std::unique_ptr<Argument>> Args;
     Args.reserve(ArgRecords.size());
 
-    for (const auto *ArgRecord : ArgRecords)
+    for (const auto *ArgRecord : ArgRecords) {
       Args.emplace_back(createArgument(*ArgRecord, R.getName()));
+      assert(Args.back());
+    }
 
     for (auto const &ai : Args)
       ai->writeTemplateInstantiation(OS);
@@ -3368,7 +3378,9 @@
 }
 
 static bool isArgVariadic(const Record &R, StringRef AttrName) {
-  return createArgument(R, AttrName)->isVariadic();
+  auto A = createArgument(R, AttrName);
+  assert(A);
+  return A->isVariadic();
 }
 
 static void emitArgInfo(const Record &R, raw_ostream &OS) {
@@ -3917,8 +3929,11 @@
       SS << "    OS << \" \" << A->getSpelling();\n";
 
     Args = R.getValueAsListOfDefs("Args");
-    for (const auto *Arg : Args)
-      createArgument(*Arg, R.getName())->writeDump(SS);
+    for (const auto *Arg : Args) {
+      auto A = createArgument(*Arg, R.getName());
+      assert(A);
+      A->writeDump(SS);
+    }
 
     if (SS.tell()) {
       OS << "  void Visit" << R.getName() << "Attr(const " << R.getName()
@@ -3945,8 +3960,11 @@
     llvm::raw_string_ostream SS(FunctionContent);
 
     Args = R.getValueAsListOfDefs("Args");
-    for (const auto *Arg : Args)
-      createArgument(*Arg, R.getName())->writeDumpChildren(SS);
+    for (const auto *Arg : Args) {
+      auto A = createArgument(*Arg, R.getName());
+      assert(A);
+      A->writeDumpChildren(SS);
+    }
     if (SS.tell()) {
       OS << "  void Visit" << R.getName() << "Attr(const " << R.getName()
          << "Attr *A) {\n";
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D91844: [l... Ella Ma via Phabricator via cfe-commits

Reply via email to