Repository: llvm/llvm-project
File: clang/lib/Frontend/CompilerInstance.cpp (C++)

Code before:
  }

  return MS_ModuleNotFound;
}

ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST(
    StringRef ModuleName, SourceLocation ImportLoc,
    SourceLocation ModuleNameLoc, bool IsInclusionDirective) {
  // Search for a module with the given name.
  HeaderSearch &HS = PP->getHeaderSearchInfo();
  Module *M =
      HS.lookupModule(ModuleName, ImportLoc, true, !IsInclusionDirective);

  // Select the source and filename for loading the named module.
  std::string ModuleFilename;
  ModuleSource Source =
      selectModuleSource(M, ModuleName, ModuleFilename, BuiltModules, HS);
  if (Source == MS_ModuleNotFound) {
    // We can't find a module, error out here.
    getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found)
        << ModuleName << SourceRange(ImportLoc, ModuleNameLoc);
    return nullptr;
  }
  if (ModuleFilename.empty()) {
    if (M && M->HasIncompatibleModuleFile) {
      // We tried and failed to load a module file for this module. Fall
      // back to textual inclusion for its headers.
      return ModuleLoadResult::ConfigMismatch;
    }

    getDiagnostics().Report(ModuleNameLoc, diag::err_module_build_disabled)
        << ModuleName;
    return nullptr;
  }

  // Create an ASTReader on demand.
  if (!getASTReader())
    createASTReader();

  // Time how long it takes to load the module.
  llvm::Timer Timer;
  if (FrontendTimerGroup)
    Timer.init("loading." + ModuleFilename, "Loading " + ModuleFilename,
               *FrontendTimerGroup);
  llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr);
  llvm::TimeTraceScope TimeScope("Module Load", ModuleName);

  // Try to load the module file. If we are not trying to load from the
  // module cache, we don't know how to rebuild modules.
  unsigned ARRFlags = Source == MS_ModuleCache
                          ? ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing |

Review comment (bug):
@Bigcheese you added this `nullptr` check here but below `selectModuleSource` takes `M` and eventually in `getPrebuiltImplicitModuleFileName` will unconditionally dereference the same pointer. 

So either this check is incorrect or this change needed to do more.

Code after:
    if (!ModuleFilename.empty())
      return MS_PrebuiltModulePath;
  }

  // Try to load the module from the module cache.
  if (M) {
    ModuleFilename = HS.getCachedModuleFileName(M);
    return MS_ModuleCache;
  }

  return MS_ModuleNotFound;
}

ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST(
    StringRef ModuleName, SourceLocation ImportLoc,
    SourceLocation ModuleNameLoc, bool IsInclusionDirective) {
  // Search for a module with the given name.
  HeaderSearch &HS = PP->getHeaderSearchInfo();
  Module *M =
      HS.lookupModule(ModuleName, ImportLoc, true, !IsInclusionDirective);

  // Check for any configuration macros that have changed. This is done
  // immediately before potentially building a module in case this module
  // depends on having one of its configuration macros defined to successfully
  // build. If this is not done the user will never see the warning.
  if (M)
    checkConfigMacros(getPreprocessor(), M, ImportLoc);

  // Select the source and filename for loading the named module.
  std::string ModuleFilename;
  ModuleSource Source =
      selectModuleSource(M, ModuleName, ModuleFilename, BuiltModules, HS);
  if (Source == MS_ModuleNotFound) {
    // We can't find a module, error out here.
    getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found)
        << ModuleName << SourceRange(ImportLoc, ModuleNameLoc);
    return nullptr;
  }
  if (ModuleFilename.empty()) {
    if (M && M->HasIncompatibleModuleFile) {
      // We tried and failed to load a module file for this module. Fall
      // back to textual inclusion for its headers.
      return ModuleLoadResult::ConfigMismatch;
    }

    getDiagnostics().Report(ModuleNameLoc, diag::err_module_build_disabled)
        << ModuleName;
    return nullptr;
  }

  // Create an ASTReader on demand.