LCOV - code coverage report
Current view: top level - /usr/lib/llvm-19/include/llvm/ADT - EpochTracker.h (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 100.0 % 3 3
Test Date: 2026-02-27 04:14:43 Functions: 100.0 % 3 3
Legend: Lines:     hit not hit

            Line data    Source code
       1              : //===- llvm/ADT/EpochTracker.h - ADT epoch tracking --------------*- 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-exception
       6              : //
       7              : //===----------------------------------------------------------------------===//
       8              : ///
       9              : /// \file
      10              : /// This file defines the DebugEpochBase and DebugEpochBase::HandleBase classes.
      11              : /// These can be used to write iterators that are fail-fast when LLVM is built
      12              : /// with asserts enabled.
      13              : ///
      14              : //===----------------------------------------------------------------------===//
      15              : 
      16              : #ifndef LLVM_ADT_EPOCHTRACKER_H
      17              : #define LLVM_ADT_EPOCHTRACKER_H
      18              : 
      19              : #include "llvm/Config/abi-breaking.h"
      20              : 
      21              : #include <cstdint>
      22              : 
      23              : namespace llvm {
      24              : 
      25              : #if LLVM_ENABLE_ABI_BREAKING_CHECKS
      26              : #define LLVM_DEBUGEPOCHBASE_HANDLEBASE_EMPTYBASE
      27              : 
      28              : /// A base class for data structure classes wishing to make iterators
      29              : /// ("handles") pointing into themselves fail-fast.  When building without
      30              : /// asserts, this class is empty and does nothing.
      31              : ///
      32              : /// DebugEpochBase does not by itself track handles pointing into itself.  The
      33              : /// expectation is that routines touching the handles will poll on
      34              : /// isHandleInSync at appropriate points to assert that the handle they're using
      35              : /// is still valid.
      36              : ///
      37              : class DebugEpochBase {
      38              :   uint64_t Epoch = 0;
      39              : 
      40              : public:
      41              :   DebugEpochBase() = default;
      42              : 
      43              :   /// Calling incrementEpoch invalidates all handles pointing into the
      44              :   /// calling instance.
      45              :   void incrementEpoch() { ++Epoch; }
      46              : 
      47              :   /// The destructor calls incrementEpoch to make use-after-free bugs
      48              :   /// more likely to crash deterministically.
      49              :   ~DebugEpochBase() { incrementEpoch(); }
      50              : 
      51              :   /// A base class for iterator classes ("handles") that wish to poll for
      52              :   /// iterator invalidating modifications in the underlying data structure.
      53              :   /// When LLVM is built without asserts, this class is empty and does nothing.
      54              :   ///
      55              :   /// HandleBase does not track the parent data structure by itself.  It expects
      56              :   /// the routines modifying the data structure to call incrementEpoch when they
      57              :   /// make an iterator-invalidating modification.
      58              :   ///
      59              :   class HandleBase {
      60              :     const uint64_t *EpochAddress = nullptr;
      61              :     uint64_t EpochAtCreation = UINT64_MAX;
      62              : 
      63              :   public:
      64              :     HandleBase() = default;
      65              : 
      66              :     explicit HandleBase(const DebugEpochBase *Parent)
      67              :         : EpochAddress(&Parent->Epoch), EpochAtCreation(Parent->Epoch) {}
      68              : 
      69              :     /// Returns true if the DebugEpochBase this Handle is linked to has
      70              :     /// not called incrementEpoch on itself since the creation of this
      71              :     /// HandleBase instance.
      72              :     bool isHandleInSync() const { return *EpochAddress == EpochAtCreation; }
      73              : 
      74              :     /// Returns a pointer to the epoch word stored in the data structure
      75              :     /// this handle points into.  Can be used to check if two iterators point
      76              :     /// into the same data structure.
      77              :     const void *getEpochAddress() const { return EpochAddress; }
      78              :   };
      79              : };
      80              : 
      81              : #else
      82              : #ifdef _MSC_VER
      83              : #define LLVM_DEBUGEPOCHBASE_HANDLEBASE_EMPTYBASE __declspec(empty_bases)
      84              : #else
      85              : #define LLVM_DEBUGEPOCHBASE_HANDLEBASE_EMPTYBASE
      86              : #endif // _MSC_VER
      87              : 
      88              : class DebugEpochBase {
      89              : public:
      90       132824 :   void incrementEpoch() {}
      91              : 
      92              :   class HandleBase {
      93              :   public:
      94              :     HandleBase() = default;
      95       811115 :     explicit HandleBase(const DebugEpochBase *) {}
      96        77103 :     bool isHandleInSync() const { return true; }
      97              :     const void *getEpochAddress() const { return nullptr; }
      98              :   };
      99              : };
     100              : 
     101              : #endif // LLVM_ENABLE_ABI_BREAKING_CHECKS
     102              : 
     103              : } // namespace llvm
     104              : 
     105              : #endif
        

Generated by: LCOV version 2.0-1