LCOV - code coverage report
Current view: top level - gcc/cp - contracts.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 100.0 % 10 10
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 2 2
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Definitions for C++26 contracts.
       2              : 
       3              :    Copyright (C) 2020-2026 Free Software Foundation, Inc.
       4              :    Originally by Jeff Chapman II (jchapman@lock3software.com) for proposed
       5              :    C++20 contracts.
       6              :    Rewritten for C++26 contracts by:
       7              :      Nina Ranns (dinka.ranns@googlemail.com)
       8              :      Iain Sandoe (iain@sandoe.co.uk)
       9              :      Ville Voutilainen (ville.voutilainen@gmail.com).
      10              : 
      11              : This file is part of GCC.
      12              : 
      13              : GCC is free software; you can redistribute it and/or modify
      14              : it under the terms of the GNU General Public License as published by
      15              : the Free Software Foundation; either version 3, or (at your option)
      16              : any later version.
      17              : 
      18              : GCC is distributed in the hope that it will be useful,
      19              : but WITHOUT ANY WARRANTY; without even the implied warranty of
      20              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      21              : GNU General Public License for more details.
      22              : 
      23              : You should have received a copy of the GNU General Public License
      24              : along with GCC; see the file COPYING3.  If not see
      25              : <http://www.gnu.org/licenses/>.  */
      26              : 
      27              : #ifndef GCC_CP_CONTRACT_H
      28              : #define GCC_CP_CONTRACT_H
      29              : 
      30              : #include <cstdint>
      31              : 
      32              : /* Contract assertion kind */
      33              : /* Must match relevant enums in <contracts> header  */
      34              : 
      35              : enum contract_assertion_kind : uint16_t {
      36              :   CAK_INVALID = 0 ,
      37              :   CAK_PRE = 1 ,
      38              :   CAK_POST = 2 ,
      39              :   CAK_ASSERT = 3,
      40              : };
      41              : 
      42              : /* Per P2900R14 + D3290R3 + extensions.  */
      43              : enum contract_evaluation_semantic : uint16_t {
      44              :   CES_INVALID = 0,
      45              :   CES_IGNORE = 1,
      46              :   CES_OBSERVE = 2,
      47              :   CES_ENFORCE = 3,
      48              :   CES_QUICK = 4,
      49              : };
      50              : 
      51              : enum detection_mode : uint16_t {
      52              :   CDM_UNSPECIFIED = 0,
      53              :   CDM_PREDICATE_FALSE = 1,
      54              :   CDM_EVAL_EXCEPTION = 2
      55              : };
      56              : 
      57              : /* Contract evaluation_semantic */
      58              : #define CONTRACT_EVALUATION_SEMANTIC(NODE) \
      59              :   (TREE_OPERAND (CONTRACT_CHECK (NODE), 0))
      60              : 
      61              : #define CONTRACT_ASSERTION_KIND(NODE) \
      62              :   (TREE_OPERAND (CONTRACT_CHECK (NODE), 1))
      63              : 
      64              : #define CONTRACT_CHECK(NODE) \
      65              :   (TREE_CHECK3 (NODE, ASSERTION_STMT, PRECONDITION_STMT, POSTCONDITION_STMT))
      66              : 
      67              : /* True if NODE is any kind of contract.  */
      68              : #define CONTRACT_P(NODE)                        \
      69              :   (TREE_CODE (NODE) == ASSERTION_STMT           \
      70              :    || TREE_CODE (NODE) == PRECONDITION_STMT     \
      71              :    || TREE_CODE (NODE) == POSTCONDITION_STMT)
      72              : 
      73              : /* True if NODE is a contract condition.  */
      74              : #define CONTRACT_CONDITION_P(NODE)              \
      75              :   (TREE_CODE (NODE) == PRECONDITION_STMT        \
      76              :    || TREE_CODE (NODE) == POSTCONDITION_STMT)
      77              : 
      78              : /* True if NODE is a precondition.  */
      79              : #define PRECONDITION_P(NODE)           \
      80              :   (TREE_CODE (NODE) == PRECONDITION_STMT)
      81              : 
      82              : /* True if NODE is a postcondition.  */
      83              : #define POSTCONDITION_P(NODE)          \
      84              :   (TREE_CODE (NODE) == POSTCONDITION_STMT)
      85              : 
      86              : /* True iff the FUNCTION_DECL NODE currently has any contracts.  */
      87              : #define DECL_HAS_CONTRACTS_P(NODE) \
      88              :   (get_fn_contract_specifiers (NODE) != NULL_TREE)
      89              : 
      90              : /* The wrapper of the original source location of a list of contracts.  */
      91              : #define CONTRACT_SOURCE_LOCATION_WRAPPER(NODE) \
      92              :   (TREE_PURPOSE (TREE_VALUE (NODE)))
      93              : 
      94              : /* The original source location of a list of contracts.  */
      95              : #define CONTRACT_SOURCE_LOCATION(NODE) \
      96              :   (EXPR_LOCATION (CONTRACT_SOURCE_LOCATION_WRAPPER (NODE)))
      97              : 
      98              : /* The actual code _STMT for a contract specifier.  */
      99              : #define CONTRACT_STATEMENT(NODE) \
     100              :   (TREE_VALUE (TREE_VALUE (NODE)))
     101              : 
     102              : /* The parsed condition of the contract.  */
     103              : #define CONTRACT_CONDITION(NODE) \
     104              :   (TREE_OPERAND (CONTRACT_CHECK (NODE), 2))
     105              : 
     106              : /* True iff the condition of the contract NODE is not yet parsed.  */
     107              : #define CONTRACT_CONDITION_DEFERRED_P(NODE) \
     108              :   (TREE_CODE (CONTRACT_CONDITION (NODE)) == DEFERRED_PARSE)
     109              : 
     110              : /* The raw comment of the contract.  */
     111              : #define CONTRACT_COMMENT(NODE) \
     112              :   (TREE_OPERAND (CONTRACT_CHECK (NODE), 3))
     113              : 
     114              : /* A std::source_location, if provided.  */
     115              : #define CONTRACT_STD_SOURCE_LOC(NODE) \
     116              :   (TREE_OPERAND (CONTRACT_CHECK (NODE), 4))
     117              : 
     118              : /* The VAR_DECL of a postcondition result. For deferred contracts, this
     119              :    is an IDENTIFIER.  */
     120              : #define POSTCONDITION_IDENTIFIER(NODE) \
     121              :   (TREE_OPERAND (POSTCONDITION_STMT_CHECK (NODE), 5))
     122              : 
     123              : /* For a FUNCTION_DECL of a guarded function, this holds the function decl
     124              :    where pre contract checks are emitted.  */
     125              : #define DECL_PRE_FN(NODE) \
     126              :   (get_precondition_function ((NODE)))
     127              : 
     128              : /* For a FUNCTION_DECL of a guarded function, this holds the function decl
     129              :    where post contract checks are emitted.  */
     130              : #define DECL_POST_FN(NODE) \
     131              :   (get_postcondition_function ((NODE)))
     132              : 
     133              : /* True iff the FUNCTION_DECL is the pre function for a guarded function.  */
     134              : #define DECL_IS_PRE_FN_P(NODE) \
     135              :   (DECL_DECLARES_FUNCTION_P (NODE) && DECL_LANG_SPECIFIC (NODE) \
     136              :    && CONTRACT_HELPER (NODE) == ldf_contract_pre)
     137              : 
     138              : /* True iff the FUNCTION_DECL is the post function for a guarded function.  */
     139              : #define DECL_IS_POST_FN_P(NODE) \
     140              :   (DECL_DECLARES_FUNCTION_P (NODE) && DECL_LANG_SPECIFIC (NODE) \
     141              :    && CONTRACT_HELPER (NODE) == ldf_contract_post)
     142              : 
     143              : #define DECL_IS_WRAPPER_FN_P(NODE) \
     144              :   (DECL_DECLARES_FUNCTION_P (NODE) && DECL_LANG_SPECIFIC (NODE) && \
     145              :    DECL_CONTRACT_WRAPPER (NODE))
     146              : 
     147              : /* Allow specifying a sub-set of contract kinds to copy.  */
     148              : enum contract_match_kind
     149              : {
     150              :   cmk_all,
     151              :   cmk_pre,
     152              :   cmk_post
     153              : };
     154              : 
     155              : /* contracts.cc */
     156              : 
     157              : extern void init_contracts                      (void);
     158              : 
     159              : extern tree grok_contract                       (tree, tree, tree, cp_expr, location_t);
     160              : extern tree finish_contract_specifier           (tree, tree);
     161              : extern tree finish_contract_condition           (cp_expr);
     162              : extern void update_late_contract                (tree, tree, cp_expr);
     163              : extern void check_redecl_contract               (tree, tree);
     164              : extern tree invalidate_contract                 (tree);
     165              : extern tree copy_and_remap_contracts            (tree, tree, contract_match_kind = cmk_all);
     166              : extern tree constify_contract_access            (tree);
     167              : extern tree view_as_const                       (tree);
     168              : 
     169              : extern void set_fn_contract_specifiers          (tree, tree);
     170              : extern void update_fn_contract_specifiers       (tree, tree);
     171              : extern tree get_fn_contract_specifiers          (tree);
     172              : extern void remove_decl_with_fn_contracts_specifiers (tree);
     173              : extern void remove_fn_contract_specifiers       (tree);
     174              : extern void update_contract_arguments           (tree, tree);
     175              : 
     176              : extern tree make_postcondition_variable         (cp_expr);
     177              : extern tree make_postcondition_variable         (cp_expr, tree);
     178              : extern void check_param_in_postcondition        (tree, location_t);
     179              : extern void check_postconditions_in_redecl      (tree, tree);
     180              : extern void maybe_update_postconditions         (tree);
     181              : extern void rebuild_postconditions              (tree);
     182              : extern bool check_postcondition_result          (tree, tree, location_t);
     183              : 
     184              : extern bool contract_any_deferred_p             (tree);
     185              : 
     186              : extern tree get_precondition_function           (tree);
     187              : extern tree get_postcondition_function          (tree);
     188              : extern tree get_orig_for_outlined               (tree);
     189              : 
     190              : extern void start_function_contracts            (tree);
     191              : extern void maybe_apply_function_contracts      (tree);
     192              : extern void finish_function_outlined_contracts  (tree);
     193              : extern void set_contract_functions              (tree, tree, tree);
     194              : 
     195              : extern tree maybe_contract_wrap_call            (tree, tree);
     196              : extern bool emit_contract_wrapper_func          (bool);
     197              : extern void maybe_emit_violation_handler_wrappers (void);
     198              : 
     199              : extern tree build_contract_check                (tree);
     200              : 
     201              : /* Test if EXP is a contract const wrapper node.  */
     202              : 
     203              : inline bool
     204      7544861 : contract_const_wrapper_p (const_tree exp)
     205              : {
     206              :   /* A wrapper node has code VIEW_CONVERT_EXPR, and the flag base.private_flag
     207              :      is set. The wrapper node is used to used to constify entities inside
     208              :      contract assertions.  */
     209      1102652 :   return ((TREE_CODE (exp) == VIEW_CONVERT_EXPR) && CONST_WRAPPER_P (exp));
     210              : }
     211              : 
     212              : /* If EXP is a contract_const_wrapper_p, return the wrapped expression.
     213              :    Otherwise, do nothing. */
     214              : 
     215              : inline tree
     216      7543224 : strip_contract_const_wrapper (tree exp)
     217              : {
     218      7543224 :   if (contract_const_wrapper_p (exp))
     219           24 :     return TREE_OPERAND (exp, 0);
     220              :   else
     221              :     return exp;
     222              : }
     223              : 
     224              : /* TODO : decide if we should push the tests into contracts.cc  */
     225              : extern contract_evaluation_semantic get_evaluation_semantic (const_tree);
     226              : 
     227              : /* Will this contract be ignored.  */
     228              : 
     229              : inline bool
     230           12 : contract_ignored_p (const_tree contract)
     231              : {
     232           12 :   return (get_evaluation_semantic (contract) <= CES_IGNORE);
     233              : }
     234              : 
     235              : /* Will this contract be evaluated?  */
     236              : 
     237              : inline bool
     238              : contract_evaluated_p (const_tree contract)
     239              : {
     240              :   return (get_evaluation_semantic (contract) >= CES_OBSERVE);
     241              : }
     242              : 
     243              : /* Is the contract terminating?  */
     244              : 
     245              : inline bool
     246           12 : contract_terminating_p (const_tree contract)
     247              : {
     248           12 :   return (get_evaluation_semantic (contract) == CES_ENFORCE
     249           12 :           || get_evaluation_semantic (contract) == CES_QUICK);
     250              : }
     251              : 
     252              : #endif /* ! GCC_CP_CONTRACT_H */
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.