ESBMC
Efficient SMT-based Context-Bounded Model Checker
Loading...
Searching...
No Matches
clang_cpp_adjust_irep2 Class Reference

IREP2-native adjust pass for the C++ frontend (Phase 7). More...

#include <clang_cpp_adjust_irep2.h>

Inheritance diagram for clang_cpp_adjust_irep2:
[legend]

Public Member Functions

 clang_c_adjust_irep2 (contextt &_context, bool sole_adjuster=false, bool writeback_all=false)
Public Member Functions inherited from clang_c_adjust_irep2
 clang_c_adjust_irep2 (contextt &_context, bool sole_adjuster=false, bool writeback_all=false)
virtual ~clang_c_adjust_irep2 ()=default
bool adjust ()
 Walk every code symbol's IREP2 value.
void adjust_expr (expr2tc &expr)

Static Public Member Functions

static std::vector< arm_info > arm_order ()
 The arms in application order, as arm_order() is for the C pass.
Static Public Member Functions inherited from clang_c_adjust_irep2
static std::vector< arm_info > arm_order ()
 The arms in the order adjust_expr applies them.

Protected Member Functions

void gen_symbol_code (symbolt &symbol) override
 Per-symbol code the pass synthesises rather than rewrites, run before the value walk so what it emits is adjusted like the rest.
void gen_implicit_union_copy_move_body (symbolt &symbol)
 IREP2 form of clang_cpp_adjust::gen_implicit_union_copy_move_constructor.
void adjust_symbol_type (symbolt &symbol) override
 A dynamic throw(T...) specification reaches this pass with its declared types unresolved; left so, the specification permits nothing and every throw through such a function reports "exception specification violated".
void hoist_switch_declaration (expr2tc &expr)
 IREP2 form of clang_cpp_adjust::adjust_switch's declaration case.
void adjust_sole_arms (expr2tc &expr) override
 Arms that run only when this pass is the sole adjuster, applied in the order arms lists them.
void adjust_cpp_member (expr2tc &expr)
 IREP2 form of clang_cpp_adjust::adjust_cpp_member.
void adjust_cpp_catch (expr2tc &expr)
 IREP2 form of clang_cpp_adjust::adjust_catch's id assignment and of the throw arm's.
void adjust_cpp_delete (expr2tc &expr)
 IREP2 form of clang_cpp_adjust::adjust_cpp_delete: attach the destructor call delete p makes, so goto_convert emits ~T(&(*p)).
void adjust_reference (expr2tc &expr) override
 IREP2 form of clang_cpp_adjust::adjust_reference: read each operand that is a reference through, so it is used as the value it names rather than as the pointer IREP2 spells it with (scope-clang-cpp-irep2.md §3.16).
void adjust_cpp_throw (expr2tc &expr)
void align_call_return_type (expr2tc &expr, const symbolt &callee) override
 IREP2 form of clang_cpp_adjust::align_se_function_call_return_type: a call evaluates to its callee's return type.
void adjust_before_operands (expr2tc &expr) override
 IREP2 form of clang_cpp_adjust::adjust_side_effect_assign's constructor fold: obj = C(args) becomes the bare call C(&obj, args).
void fold_constructor_assignment (expr2tc &expr)
void fan_out_array_construction (expr2tc &expr)
 IREP2 form of clang_cpp_adjust::adjust_decl_block's fan-out: a local array of class type arrives with one constructor call for the whole array, and every element has to be constructed.
expr2tc array_decl_constructor (const expr2tc &stmt)
 Nil unless stmt declares a local array whose initialiser is a single whole-array constructor call; otherwise that call.
bool construct_elements (const expr2tc &array, const expr2tc &ctor, std::vector< expr2tc > &out)
 False when a dimension's size is not a constant, leaving out unusable: the caller emits nothing in that case.
bool is_constructor_call (const expr2tc &call)
 Whether call is a constructor call.
expr2tc find_constructor_call (const expr2tc &e)
Protected Member Functions inherited from clang_c_adjust_irep2
void adjust_increment_reference (expr2tc &expr)
 clang_c_adjust adjusts references on an increment or decrement, whose operand it updates in place.
void adjust_index (expr2tc &expr)
 IREP2 form of clang_c_adjust::adjust_index's rewrite.
void adjust_member (expr2tc &expr)
 IREP2 form of clang_c_adjust::adjust_member's rewrite: reach through a pointer base with a dereference, or an array base with a zero index.
void declare_implicit_callee (const expr2tc &expr)
 A call to a function with no visible declaration reaches here with no symbol in the context; clang_c_adjust::adjust_side_effect_function_call declares one.
void adjust_boolean_operands (expr2tc &expr)
 IREP2 form of clang_c_adjust::adjust_expr_{unary,binary}_boolean's live half.
void adjust_call_callee (expr2tc &expr)
 IREP2 form of the "do implicit dereference" step of clang_c_adjust::adjust_side_effect_function_call: goto_convert's do_function_call accepts a symbol or a dereference, so a pointer-typed callee – a function-pointer struct member, say – must be dereferenced first (§82).
void adjust_call_signature (expr2tc &expr)
 Rebuild a call's callee from the symbol table when the converter left its type incomplete, then let the frontend align the call's own type.
void adjust_complex_arith (expr2tc &expr)
 IREP2 form of clang_c_adjust::adjust_expr_binary_arithmetic's complex branch: decompose a op b over a complex operand into per-component arithmetic and rebuild a (real, imag) pair.
void adjust_complex_unary (expr2tc &expr)
 IREP2 form of clang_c_adjust::adjust_expr_unary_complex: -z negates both components, GNU ~z conjugates.
void adjust_if_expr (expr2tc &expr)
 IREP2 form of clang_c_adjust::adjust_if: a ternary's condition must be boolean before goto_convert lowers it, and its arms must agree with the node's type.
void adjust_special_functions (expr2tc &expr)
 IREP2 form of the __builtin_-prefixed half of clang_c_adjust::do_special_functions: fold a recognised builtin call to the node it denotes.
void adjust_derived_to_base (expr2tc &expr)
 IREP2 form of clang_c_adjust::adjust_derived_to_base: displace a derived->base conversion onto the base subobject under the flattened layout.
void adjust_base_to_derived (expr2tc &expr)
 IREP2 form of clang_c_adjust::adjust_base_to_derived: re-base a downcast off the base subobject onto the start of the derived object.
void adjust_address_of (expr2tc &expr)
 IREP2 form of clang_c_adjust::adjust_address_of's array decay (§105).
void adjust_ptr_mem (expr2tc &expr)
 IREP2 form of clang_c_adjust::adjust_ptr_mem.
void declare_polymorphic_builtin (expr2tc &expr)
 The GCC __sync_* / C11 __c11_atomic_* half of clang_c_adjust::adjust_side_effect_function_call: clang hands these builtins over body-less, so the concrete instance has to be declared and the callee repointed at it.
void adjust_expression_statement (expr2tc &expr)
 An expression statement whose value has array type – y->ss; where y points at a struct with an array member – is rewritten to &y->ss[0].
void promote_unary_bool_operand (expr2tc &expr)
 C11 6.5.3.3: the operand of unary - and ~ undergoes integer promotion, so a boolean one – a comparison, || or && – becomes int.
void adjust_struct (expr2tc &expr)
 IREP2 form of clang_c_adjust::adjust_struct's insertion loop.
void adjust_array_subtype (expr2tc &expr)
 adjust_struct retypes an element to its tag's padded layout, which leaves an enclosing array literal still naming the unpadded element type.
void adjust_decl_init (expr2tc &expr)
 IREP2 form of clang_c_adjust::adjust_decl's trailing gen_typecast: a declaration's initialiser converts to the declared type.
void adjust_dereference (expr2tc &expr)
void lower_complex_compound_assignment (expr2tc &expr)
 IREP2 form of clang_c_adjust::lower_complex_compound_assignment.
void adjust_vector_float_arith (expr2tc &expr)
 clang emits ieee_* for scalar float arithmetic itself, but hands over a plain +/-/*// when the operands are vectors of float and leaves clang_c_adjust::adjust_float_arith to promote it.
void hoist_for_init (expr2tc &expr)
void pad_type_symbol (symbolt &symbol)
 Pad a complete struct or union type symbol to its ABI layout (§96).
void adjust_binary_arith_operands (expr2tc &expr)
 IREP2 form of clang_c_adjust::adjust_expr_binary_arithmetic's conversion half: the usual arithmetic conversions over the operands, then the node's own type.
void adjust_shift_operands (expr2tc &expr)
 IREP2 form of clang_c_adjust::adjust_expr_shifts.
void adjust_plain_assignment (expr2tc &expr)
 IREP2 form of clang_c_adjust::adjust_side_effect_assignment's plain "assign" case: the node takes the target's type, and the source converts to it.
void adjust_compound_assignment (expr2tc &expr)
 IREP2 form of clang_c_adjust::adjust_side_effect_assignment's tail: the compound operators take the usual arithmetic conversions on both operands (C11 6.5.16.2p3 – b += a is b = b + a, so a narrow target promotes), while the node keeps the target's type.
void adjust_statement_condition (expr2tc &expr)
 IREP2 form of the gen_typecast_bool that adjust_ifthenelse, adjust_while and adjust_for apply to a statement's controlling expression (§95).
bool adjust_float_builtin (expr2tc &expr, const irep_idt &name, const std::vector< expr2tc > &args)
 The name-matched half of do_special_functions: isnan, abs, sqrt, inf and friends.
void adjust_relational (expr2tc &expr)
 IREP2 form of clang_c_adjust::adjust_expr_rel's operand half: the usual arithmetic conversions over a comparison's operands, which is also what decays an array operand compared against a pointer (§96).
void adjust_call_arguments (expr2tc &expr)
 IREP2 form of clang_c_adjust::adjust_function_call_arguments' conversion half: convert each argument to its parameter type, which is what decays a function designator to a pointer at a call (§108).
void adjust_function_designators (expr2tc &expr)
 IREP2 form of clang_c_adjust::adjust_symbol's function-designator sugar (§100).
void adjust_comma_type (expr2tc &expr)
 A comma expression takes its right operand's type (C11 6.5.17p2).

Additional Inherited Members

Protected Types inherited from clang_c_adjust_irep2
using arm = adjust_arm<clang_c_adjust_irep2>
Protected Attributes inherited from clang_c_adjust_irep2
contextt & context
const bool sole_adjuster
const bool writeback_all
locationt enclosing_location
 Location of the innermost enclosing statement, for the nodes that carry none of their own.
namespacet ns {context}
Static Protected Attributes inherited from clang_c_adjust_irep2
static const arm arms []
 The chain in application order.

Detailed Description

IREP2-native adjust pass for the C++ frontend (Phase 7).

Mirrors the legacy hierarchy, where clang_cpp_adjust derives from clang_c_adjust and overrides the arms whose C++ behaviour differs.

It substitutes its own arm table rather than adding rows to the C one: the table is typed on the pass, so this one can order the arms it inherits alongside its own (docs/roadmap/scope-clang-cpp-irep2.md §3.1).

The table currently lists only inherited arms. That is deliberate and measurable: running it as the sole adjuster over regression/esbmc-cpp enumerates what C++ needs that C does not, which is a measured list where §3's name-mapping was a guess.

Member Function Documentation

◆ adjust_before_operands()

void clang_cpp_adjust_irep2::adjust_before_operands ( expr2tc & expr)
overrideprotectedvirtual

IREP2 form of clang_cpp_adjust::adjust_side_effect_assign's constructor fold: obj = C(args) becomes the bare call C(&obj, args).

Left as an assignment, remove_sideeffects materialises a temporary for the call's value and that temporary acquires destructors of its own (docs/roadmap/scope-clang-cpp-irep2.md §3.14). Runs before the operand walk: the call-site arms must see the object argument, since they convert each argument against the matching parameter and a constructor's first parameter is this. Legacy asserts the callee is a constructor and that the object roots at a symbol; both are declines here, since a pass that substitutes for the legacy one should leave a node it does not understand alone rather than abort on it.

Reimplemented from clang_c_adjust_irep2.

◆ adjust_cpp_catch()

void clang_cpp_adjust_irep2::adjust_cpp_catch ( expr2tc & expr)
protected

IREP2 form of clang_cpp_adjust::adjust_catch's id assignment and of the throw arm's.

Both nodes hold their catchable-type ids in an exception_list field, which the converter leaves empty; remove_exceptions dereferences it, so an unpopulated list is a crash rather than a lost property (docs/roadmap/scope-clang-cpp-irep2.md §3.3).

◆ adjust_cpp_delete()

void clang_cpp_adjust_irep2::adjust_cpp_delete ( expr2tc & expr)
protected

IREP2 form of clang_cpp_adjust::adjust_cpp_delete: attach the destructor call delete p makes, so goto_convert emits ~T(&(*p)).

Without it the object's destructors never run (scope-clang-cpp-irep2.md §3.14). The call travels in sideeffect2t::arguments[0], which the seam already carries.

◆ adjust_cpp_member()

void clang_cpp_adjust_irep2::adjust_cpp_member ( expr2tc & expr)
protected

IREP2 form of clang_cpp_adjust::adjust_cpp_member.

OBJECT.setX() reaches the pass with a code-typed member as its callee; goto_convert accepts only a symbol or a dereference there, so the member is replaced by the symbol naming the method. The object is already the call's first argument, put there by the converter, so only the callee changes.

◆ adjust_cpp_throw()

void clang_cpp_adjust_irep2::adjust_cpp_throw ( expr2tc & expr)
protected

◆ adjust_reference()

void clang_cpp_adjust_irep2::adjust_reference ( expr2tc & expr)
overrideprotectedvirtual

IREP2 form of clang_cpp_adjust::adjust_reference: read each operand that is a reference through, so it is used as the value it names rather than as the pointer IREP2 spells it with (scope-clang-cpp-irep2.md §3.16).

Reimplemented from clang_c_adjust_irep2.

◆ adjust_sole_arms()

void clang_cpp_adjust_irep2::adjust_sole_arms ( expr2tc & expr)
overrideprotectedvirtual

Arms that run only when this pass is the sole adjuster, applied in the order arms lists them.

Virtual so a derived pass substitutes its own table: one virtual for the whole dispatch, rather than the per-arm virtuals §3 of the C++ scope rejected.

Reimplemented from clang_c_adjust_irep2.

◆ adjust_symbol_type()

void clang_cpp_adjust_irep2::adjust_symbol_type ( symbolt & symbol)
overrideprotectedvirtual

A dynamic throw(T...) specification reaches this pass with its declared types unresolved; left so, the specification permits nothing and every throw through such a function reports "exception specification violated".

The legacy pass resolves it in adjust_symbol, which this pass replaces.

Reimplemented from clang_c_adjust_irep2.

◆ align_call_return_type()

void clang_cpp_adjust_irep2::align_call_return_type ( expr2tc & expr,
const symbolt & callee )
overrideprotectedvirtual

IREP2 form of clang_cpp_adjust::align_se_function_call_return_type: a call evaluates to its callee's return type.

Constructors are excluded — their "return type" names the class, not the call's value.

Reimplemented from clang_c_adjust_irep2.

◆ arm_order()

std::vector< clang_cpp_adjust_irep2::arm_info > clang_cpp_adjust_irep2::arm_order ( )
static

The arms in application order, as arm_order() is for the C pass.

◆ array_decl_constructor()

expr2tc clang_cpp_adjust_irep2::array_decl_constructor ( const expr2tc & stmt)
protected

Nil unless stmt declares a local array whose initialiser is a single whole-array constructor call; otherwise that call.

◆ clang_c_adjust_irep2()

clang_c_adjust_irep2::clang_c_adjust_irep2 ( contextt & _context,
bool sole_adjuster = false,
bool writeback_all = false )
inlineexplicit
Parameters
sole_adjustertrue under –clang-c-irep2-adjust-only, where this pass replaces clang_c_adjust. Work that substitutes for the legacy pass – declaring an implicitly-declared callee (§70) – must run only then: in shadow mode the legacy pass has already done it, and doing it twice adds conflicting symbols for library functions.
writeback_alldiagnostic only (–clang-c-irep2-adjust-writeback-all): refresh every symbol's legacy value, not just the ones this pass changed. adjust() gates the write-back on value != before so an untouched body never pays migrate_expr_back's losses – but that also means --symbol-table-only prints the converter's tree for those bodies, not this pass's, and the two differ wherever migrate_expr normalises (§135). Set this to see what the pass actually produced.

◆ construct_elements()

bool clang_cpp_adjust_irep2::construct_elements ( const expr2tc & array,
const expr2tc & ctor,
std::vector< expr2tc > & out )
protected

False when a dimension's size is not a constant, leaving out unusable: the caller emits nothing in that case.

◆ fan_out_array_construction()

void clang_cpp_adjust_irep2::fan_out_array_construction ( expr2tc & expr)
protected

IREP2 form of clang_cpp_adjust::adjust_decl_block's fan-out: a local array of class type arrives with one constructor call for the whole array, and every element has to be constructed.

Operates on the enclosing block because one declaration becomes several statements; rewriting the declaration into a block of its own would end the object's scope at that block's brace (esbmc/esbmc#4715).

◆ find_constructor_call()

expr2tc clang_cpp_adjust_irep2::find_constructor_call ( const expr2tc & e)
protected

◆ fold_constructor_assignment()

void clang_cpp_adjust_irep2::fold_constructor_assignment ( expr2tc & expr)
protected

◆ gen_implicit_union_copy_move_body()

void clang_cpp_adjust_irep2::gen_implicit_union_copy_move_body ( symbolt & symbol)
protected

IREP2 form of clang_cpp_adjust::gen_implicit_union_copy_move_constructor.

A union's implicitly-defined copy/move constructor copies the object representation ([class.copy.ctor]/14), which here is one assignment of the whole union. Generated before the value walk so the assignment goes through the arms like any other statement (docs/roadmap/scope-clang-cpp-irep2.md §8.2).

◆ gen_symbol_code()

void clang_cpp_adjust_irep2::gen_symbol_code ( symbolt & )
overrideprotectedvirtual

Per-symbol code the pass synthesises rather than rewrites, run before the value walk so what it emits is adjusted like the rest.

Distinct from an arm: an arm rewrites one node, this takes the whole symbol. C generates nothing (docs/roadmap/scope-clang-cpp-irep2.md §3.6).

Reimplemented from clang_c_adjust_irep2.

◆ hoist_switch_declaration()

void clang_cpp_adjust_irep2::hoist_switch_declaration ( expr2tc & expr)
protected

IREP2 form of clang_cpp_adjust::adjust_switch's declaration case.

C++ lets a switch condition be a declaration – switch (int x = 0) – and the declaration has to be hoisted ahead of the switch, which then switches on the declared symbol. Left in place the declaration is the switched value and reaches the solver as a statement (docs/roadmap/scope-clang-cpp-irep2.md §8.1).

◆ is_constructor_call()

bool clang_cpp_adjust_irep2::is_constructor_call ( const expr2tc & call)
protected

Whether call is a constructor call.

The converter's #constructor marker does not cross the seam, so the constructor return-type spelling is read from the symbol table instead. The two are not the same set – legacy sets the marker only where it built the call – but every shape measured so far wants the same answer (§3.16).


The documentation for this class was generated from the following files: