79 lines · cpp
1//===- LifetimeSafety.cpp - C++ Lifetime Safety Analysis -*--------- C++-*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the main LifetimeSafetyAnalysis class, which coordinates10// the various components (fact generation, loan propagation, live origins11// analysis, and checking) to detect lifetime safety violations in C++ code.12//13//===----------------------------------------------------------------------===//14#include "clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h"15#include "clang/AST/Decl.h"16#include "clang/AST/Expr.h"17#include "clang/AST/Type.h"18#include "clang/Analysis/Analyses/LifetimeSafety/Checker.h"19#include "clang/Analysis/Analyses/LifetimeSafety/Facts.h"20#include "clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h"21#include "clang/Analysis/Analyses/LifetimeSafety/LiveOrigins.h"22#include "clang/Analysis/Analyses/LifetimeSafety/LoanPropagation.h"23#include "clang/Analysis/AnalysisDeclContext.h"24#include "clang/Analysis/CFG.h"25#include "llvm/ADT/FoldingSet.h"26#include "llvm/Support/Debug.h"27#include "llvm/Support/ErrorHandling.h"28#include "llvm/Support/TimeProfiler.h"29#include <memory>30 31namespace clang::lifetimes {32namespace internal {33 34LifetimeSafetyAnalysis::LifetimeSafetyAnalysis(AnalysisDeclContext &AC,35 LifetimeSafetyReporter *Reporter)36 : AC(AC), Reporter(Reporter) {}37 38void LifetimeSafetyAnalysis::run() {39 llvm::TimeTraceScope TimeProfile("LifetimeSafetyAnalysis");40 41 const CFG &Cfg = *AC.getCFG();42 DEBUG_WITH_TYPE("PrintCFG", Cfg.dump(AC.getASTContext().getLangOpts(),43 /*ShowColors=*/true));44 FactMgr.init(Cfg);45 46 FactsGenerator FactGen(FactMgr, AC);47 FactGen.run();48 DEBUG_WITH_TYPE("LifetimeFacts", FactMgr.dump(Cfg, AC));49 50 /// TODO(opt): Consider optimizing individual blocks before running the51 /// dataflow analysis.52 /// 1. Expression Origins: These are assigned once and read at most once,53 /// forming simple chains. These chains can be compressed into a single54 /// assignment.55 /// 2. Block-Local Loans: Origins of expressions are never read by other56 /// blocks; only Decls are visible. Therefore, loans in a block that57 /// never reach an Origin associated with a Decl can be safely dropped by58 /// the analysis.59 /// 3. Collapse ExpireFacts belonging to same source location into a single60 /// Fact.61 LoanPropagation = std::make_unique<LoanPropagationAnalysis>(62 Cfg, AC, FactMgr, Factory.OriginMapFactory, Factory.LoanSetFactory);63 64 LiveOrigins = std::make_unique<LiveOriginsAnalysis>(65 Cfg, AC, FactMgr, Factory.LivenessMapFactory);66 DEBUG_WITH_TYPE("LiveOrigins",67 LiveOrigins->dump(llvm::dbgs(), FactMgr.getTestPoints()));68 69 runLifetimeChecker(*LoanPropagation, *LiveOrigins, FactMgr, AC, Reporter);70}71} // namespace internal72 73void runLifetimeSafetyAnalysis(AnalysisDeclContext &AC,74 LifetimeSafetyReporter *Reporter) {75 internal::LifetimeSafetyAnalysis Analysis(AC, Reporter);76 Analysis.run();77}78} // namespace clang::lifetimes79