GCC Middle and Back End API Reference
gimple-harden-control-flow.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "memmodel.h"
#include "tm_p.h"
#include "tree.h"
#include "fold-const.h"
#include "gimple.h"
#include "gimplify.h"
#include "tree-pass.h"
#include "ssa.h"
#include "gimple-iterator.h"
#include "gimple-pretty-print.h"
#include "tree-cfg.h"
#include "tree-cfgcleanup.h"
#include "tree-eh.h"
#include "except.h"
#include "sbitmap.h"
#include "basic-block.h"
#include "cfghooks.h"
#include "cfgloop.h"
#include "cgraph.h"
#include "alias.h"
#include "varasm.h"
#include "output.h"
#include "langhooks.h"
#include "diagnostic.h"
#include "intl.h"
Include dependency graph for gimple-harden-control-flow.cc:

Data Structures

class  rt_bb_visited

Macros

#define INCLUDE_ALGORITHM   /* find @endverbatim */

Typedefs

typedef auto_vec< edge, 10 > chk_edges_t

Functions

static bool check_returning_calls_p ()
static gimplehardcfr_scan_block (basic_block bb, tree **retptr)
static bool returning_call_p (gcall *call)
static bool hardcfr_sibcall_search_preds (basic_block bb, chk_edges_t &chk_edges, int &count_chkcall, auto_sbitmap &chkcall_blocks, int &count_postchk, auto_sbitmap &postchk_blocks, tree *retptr)
static bool hardcfr_sibcall_search_block (basic_block bb, chk_edges_t &chk_edges, int &count_chkcall, auto_sbitmap &chkcall_blocks, int &count_postchk, auto_sbitmap &postchk_blocks, tree *retptr)
static bool always_throwing_noreturn_call_p (gimple *stmt)
gimple_opt_passmake_pass_harden_control_flow_redundancy (gcc::context *ctxt)

Macro Definition Documentation

◆ INCLUDE_ALGORITHM

#define INCLUDE_ALGORITHM   /* find @endverbatim */
Control flow redundancy hardening. Copyright (C) 2022-2025 Free Software Foundation, Inc. Contributed by Alexandre Oliva <oliva@adacore.com>. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>.

Typedef Documentation

◆ chk_edges_t

typedef auto_vec<edge, 10> chk_edges_t

Function Documentation

◆ always_throwing_noreturn_call_p()

bool always_throwing_noreturn_call_p ( gimple * stmt)
static
Avoid checking before noreturn calls that are known (expected, really) to finish by throwing an exception, rather than by ending the program or looping forever. Such functions have to be annotated, with an attribute (expected_throw) or flag (ECF_XTHROW), so that exception-raising functions, such as C++'s __cxa_throw, __cxa_rethrow, and Ada's gnat_rcheck_*, gnat_reraise*, ada.exception.raise_exception*, and the language-independent unwinders could be detected here and handled differently from other noreturn functions.

References as_a(), gimple_call_expected_throw_p(), gimple_call_noreturn_p(), and is_a().

◆ check_returning_calls_p()

bool check_returning_calls_p ( )
static
Return TRUE iff CFR checks should be inserted before returning calls.

Referenced by hardcfr_sibcall_search_block(), and returning_call_p().

◆ hardcfr_scan_block()

gimple * hardcfr_scan_block ( basic_block bb,
tree ** retptr )
static
Scan BB from the end, updating *RETPTR if given as return stmts and copies are found. Return a call or a stmt that cannot appear after a tail call, or NULL if the top of the block is reached without finding any.

References as_a(), gcc_checking_assert, gimple_assign_lhs(), gimple_assign_rhs1_ptr(), gimple_assign_single_p(), gimple_clobber_p(), gimple_return_retval_ptr(), gsi_end_p(), gsi_last_bb(), gsi_prev(), gsi_stmt(), is_gimple_call(), is_gimple_debug(), and NULL.

Referenced by hardcfr_sibcall_search_block(), and returning_call_p().

◆ hardcfr_sibcall_search_block()

bool hardcfr_sibcall_search_block ( basic_block bb,
chk_edges_t & chk_edges,
int & count_chkcall,
auto_sbitmap & chkcall_blocks,
int & count_postchk,
auto_sbitmap & postchk_blocks,
tree * retptr )
static
Search backwards from the end of BB for a mandatory or potential sibcall. Schedule the block to be handled sort-of like noreturn if so. Recurse to preds, with updated RETPTR, if the block only contains stmts that may follow such a call, scheduling checking at edges and marking blocks as post-check as needed. Return true iff, at the end of the block, a check will have already been performed.

References as_a(), bitmap_set_bit, check_returning_calls_p(), gcc_checking_assert, gcc_unreachable, gimple_call_lhs(), gimple_call_must_tail_p(), gimple_call_noreturn_p(), gimple_call_tail_p(), hardcfr_scan_block(), hardcfr_sibcall_search_preds(), basic_block_def::index, is_a(), NULL, returning_call_p(), single_succ_edge(), and single_succ_p().

Referenced by hardcfr_sibcall_search_preds().

◆ hardcfr_sibcall_search_preds()

bool hardcfr_sibcall_search_preds ( basic_block bb,
chk_edges_t & chk_edges,
int & count_chkcall,
auto_sbitmap & chkcall_blocks,
int & count_postchk,
auto_sbitmap & postchk_blocks,
tree * retptr )
static
Declare for mutual recursion.
Search preds of BB for a mandatory or potential sibcall or returning call, and arrange for the blocks containing them to have a check inserted before the call, like noreturn calls. If any preds are found to perform checking, schedule checks at the edges of those that don't, and mark BB as postcheck..

References as_a(), bitmap_set_bit, EDGE_COUNT, EDGE_PRED, gcc_checking_assert, gcc_unreachable, gimple_bb(), gimple_phi_arg_def_ptr(), gimple_phi_result(), hardcfr_sibcall_search_block(), i, basic_block_def::index, is_a(), NULL, NUM_FIXED_BLOCKS, basic_block_def::preds, SSA_NAME_DEF_STMT, SSA_NAME_IS_DEFAULT_DEF, and TREE_CODE.

Referenced by hardcfr_sibcall_search_block().

◆ make_pass_harden_control_flow_redundancy()

gimple_opt_pass * make_pass_harden_control_flow_redundancy ( gcc::context * ctxt)
Instantiate a hardcfr pass.

◆ returning_call_p()

bool returning_call_p ( gcall * call)
static
Return TRUE iff CALL is to be preceded by a CFR checkpoint, i.e., if it's a returning call (one whose result is ultimately returned without intervening non-copy statements) and we're checking returning calls, a __builtin_return call (noreturn with a path to the exit block), a must-tail call, or a tail call.

References as_a(), cfun, check_returning_calls_p(), EDGE_COUNT, EDGE_PRED, EXIT_BLOCK_PTR_FOR_FN, gcc_checking_assert, gimple_bb(), gimple_call_lhs(), gimple_call_must_tail_p(), gimple_call_noreturn_p(), gimple_call_tail_p(), gimple_phi_arg_def_ptr(), gimple_phi_result(), hardcfr_scan_block(), i, is_a(), n_basic_blocks_for_fn, NULL, NUM_FIXED_BLOCKS, path, basic_block_def::preds, single_succ(), single_succ_edge(), single_succ_p(), SSA_NAME_DEF_STMT, SSA_NAME_IS_DEFAULT_DEF, and TREE_CODE.

Referenced by hardcfr_sibcall_search_block().