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

#include <clang_c_adjust_irep2.h>

Inheritance diagram for clang_c_adjust_irep2:
[legend]

Classes

struct  arm_info
 One arm of the dispatch, as much of it as a caller may see: what it is called, and the guard deciding whether it claims a node. More...

Public Member Functions

 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 the order adjust_expr applies them.

Protected Types

using arm = adjust_arm<clang_c_adjust_irep2>

Protected Member Functions

virtual void adjust_reference (expr2tc &)
 Read a reference-typed operand through, where the operand is used as a value: r becomes *r.
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.
virtual void align_call_return_type (expr2tc &, const symbolt &)
 The call's type follows its callee's return type in C++ but not in C, where clang_c_adjust::align_se_function_call_return_type is empty.
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).
virtual void gen_symbol_code (symbolt &)
 Per-symbol code the pass synthesises rather than rewrites, run before the value walk so what it emits is adjusted like the rest.
virtual void adjust_symbol_type (symbolt &)
 Per-symbol type work, run for every symbol including the value-less ones.
virtual void adjust_before_operands (expr2tc &)
 A rewrite whose result must be walked, so it cannot be an arm: the arms run after the operand walk.
virtual void adjust_sole_arms (expr2tc &expr)
 Arms that run only when this pass is the sole adjuster, applied in the order arms lists them.
void adjust_comma_type (expr2tc &expr)
 A comma expression takes its right operand's type (C11 6.5.17p2).

Protected Attributes

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

static const arm arms []
 The chain in application order.

Member Typedef Documentation

◆ arm

Constructor & Destructor Documentation

◆ 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.

◆ ~clang_c_adjust_irep2()

virtual clang_c_adjust_irep2::~clang_c_adjust_irep2 ( )
virtualdefault

Member Function Documentation

◆ adjust()

bool clang_c_adjust_irep2::adjust ( )

Walk every code symbol's IREP2 value.

Returns false; there is no failure mode yet, and the signature matches clang_c_adjust::adjust() so the driver can call either.

◆ adjust_address_of()

void clang_c_adjust_irep2::adjust_address_of ( expr2tc & expr)
protected

IREP2 form of clang_c_adjust::adjust_address_of's array decay (§105).

◆ adjust_array_subtype()

void clang_c_adjust_irep2::adjust_array_subtype ( expr2tc & expr)
protected

adjust_struct retypes an element to its tag's padded layout, which leaves an enclosing array literal still naming the unpadded element type.

The operands are walked before the node itself, so the retyped elements are already in place here; value_sett::assign's base_type_eq rejects the pair otherwise.

◆ adjust_base_to_derived()

void clang_c_adjust_irep2::adjust_base_to_derived ( expr2tc & expr)
protected

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.

◆ adjust_before_operands()

virtual void clang_c_adjust_irep2::adjust_before_operands ( expr2tc & )
inlineprotectedvirtual

A rewrite whose result must be walked, so it cannot be an arm: the arms run after the operand walk.

The legacy passes dispatch top-down and get this ordering for free. C has no such rewrite (docs/roadmap/scope-clang-cpp-irep2.md §3.15).

Reimplemented in clang_cpp_adjust_irep2.

◆ adjust_binary_arith_operands()

void clang_c_adjust_irep2::adjust_binary_arith_operands ( expr2tc & expr)
protected

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.

adjust_float_arith's ieee_* promotion is not part of this (§104.2).

◆ adjust_boolean_operands()

void clang_c_adjust_irep2::adjust_boolean_operands ( expr2tc & expr)
protected

IREP2 form of clang_c_adjust::adjust_expr_{unary,binary}_boolean's live half.

Their type write is dead for C (§58.1); the operand conversion is not – goto_convert's short-circuit lowering rejects a non-boolean operand outright. Portable here, unlike §58's dispatch-point shape, because this walk migrates once and does not round-trip per node (§78).

◆ adjust_call_arguments()

void clang_c_adjust_irep2::adjust_call_arguments ( expr2tc & expr)
protected

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).

◆ adjust_call_callee()

void clang_c_adjust_irep2::adjust_call_callee ( expr2tc & expr)
protected

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).

◆ adjust_call_signature()

void clang_c_adjust_irep2::adjust_call_signature ( expr2tc & expr)
protected

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.

IREP2 form of the callee refresh in clang_c_adjust::adjust_side_effect_function_call: a converter can leave the callee's type incomplete – the Solidity frontend emits a call whose callee has no code type at all – and legacy repairs it by rebuilding the symbol expression from the table.

Aligning the call's own type to the callee's return type is C++'s, not C's (align_se_function_call_return_type is empty in clang_c_adjust), so that half is a hook.

◆ adjust_comma_type()

void clang_c_adjust_irep2::adjust_comma_type ( expr2tc & expr)
protected

A comma expression takes its right operand's type (C11 6.5.17p2).

Clang hands it the decayed type when the right operand is an array, so leaving it makes (c, a[i])[0] index a pointer rather than the row – which loses the named array-bounds check for the generic dereference one. Same rewrite as adjust_comma_at_dispatch, which the –clang-c-irep2-adjust probe uses.

◆ adjust_complex_arith()

void clang_c_adjust_irep2::adjust_complex_arith ( expr2tc & expr)
protected

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.

Unported, a complex / reaches goto_check's div_by_zero_check, which asks gen_zero for a complex zero and aborts – the default path never gets there because it lowers to ieee_div, which is exempt from that check (§88).

◆ adjust_complex_unary()

void clang_c_adjust_irep2::adjust_complex_unary ( expr2tc & expr)
protected

IREP2 form of clang_c_adjust::adjust_expr_unary_complex: -z negates both components, GNU ~z conjugates.

Unported, either reaches the solver still carrying a complex type and segfaults it (§90).

◆ adjust_compound_assignment()

void clang_c_adjust_irep2::adjust_compound_assignment ( expr2tc & expr)
protected

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.

◆ adjust_decl_init()

void clang_c_adjust_irep2::adjust_decl_init ( expr2tc & expr)
protected

IREP2 form of clang_c_adjust::adjust_decl's trailing gen_typecast: a declaration's initialiser converts to the declared type.

Distinct from adjust_plain_assignment, which handles the expression form (sideeffect_assign2t). Without it a narrower declared type keeps the promoted operand type – _ExtInt(10) z = x + y initialises from an int – and the solver is handed mismatching sorts.

◆ adjust_dereference()

void clang_c_adjust_irep2::adjust_dereference ( expr2tc & expr)
protected

◆ adjust_derived_to_base()

void clang_c_adjust_irep2::adjust_derived_to_base ( expr2tc & expr)
protected

IREP2 form of clang_c_adjust::adjust_derived_to_base: displace a derived->base conversion onto the base subobject under the flattened layout.

The offset comes from base_displacement, ESBMC's own layout oracle – recomputing it from clang's record layout is the mistake #3894 records.

◆ adjust_expr()

void clang_c_adjust_irep2::adjust_expr ( expr2tc & expr)

◆ adjust_expression_statement()

void clang_c_adjust_irep2::adjust_expression_statement ( expr2tc & expr)
protected

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].

clang_c_adjust does this because the dereference code does not assume such an object exists; the statement's value is unused, so taking the first element's address is free (clang_c_adjust_code.cpp:57-74).

An assignment operand is exempt there and here: the array is the assignment target, not a value being discarded.

◆ adjust_float_builtin()

bool clang_c_adjust_irep2::adjust_float_builtin ( expr2tc & expr,
const irep_idt & name,
const std::vector< expr2tc > & args )
protected

The name-matched half of do_special_functions: isnan, abs, sqrt, inf and friends.

sqrt's legacy arm additionally skips a py:-prefixed callee; this pass is constructed only from clang_c_languaget::typecheck, so no Python symbol can reach it and the guard has nothing to test.

Split from adjust_special_functions because these spellings are not reserved, so they run behind builtin_shadows_user_definition (§94).

◆ adjust_function_designators()

void clang_c_adjust_irep2::adjust_function_designators ( expr2tc & expr)
protected

IREP2 form of clang_c_adjust::adjust_symbol's function-designator sugar (§100).

A function designator used as a value is sugar for &f (clang_c_adjust::adjust_symbol).

Applied from the parent rather than at the symbol itself: address_of2t asserts its operand is not another address_of, so a user-written &f must not be wrapped again – where the legacy pass builds &(&f) and collapses it in adjust_address_of, this never builds it.

◆ adjust_if_expr()

void clang_c_adjust_irep2::adjust_if_expr ( expr2tc & expr)
protected

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.

if2t is the only value-level kind carrying a location (§49.2), so the rebuild passes the original through (§84).

◆ adjust_increment_reference()

void clang_c_adjust_irep2::adjust_increment_reference ( expr2tc & expr)
protected

clang_c_adjust adjusts references on an increment or decrement, whose operand it updates in place.

Without it f()++, where f returns a reference, does arithmetic on the reference instead of on the referent (scope-clang-cpp-irep2.md §3.16).

◆ adjust_index()

void clang_c_adjust_irep2::adjust_index ( expr2tc & expr)
protected

IREP2 form of clang_c_adjust::adjust_index's rewrite.

The legacy arm keeps the operand recursion and returns before this point when the flag is on (scope-clang-c-irep2.md §19.2).

◆ adjust_member()

void clang_c_adjust_irep2::adjust_member ( expr2tc & expr)
protected

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.

◆ adjust_plain_assignment()

void clang_c_adjust_irep2::adjust_plain_assignment ( expr2tc & expr)
protected

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.

IREP2 form of clang_c_adjust::adjust_side_effect_assignment's "assign" case: the node takes the target's type and the source converts to it.

The compound operators ("assign+", ...) are a larger arm carrying a complex lowering of their own, and are left where this mode already had them.

◆ adjust_ptr_mem()

void clang_c_adjust_irep2::adjust_ptr_mem ( expr2tc & expr)
protected

IREP2 form of clang_c_adjust::adjust_ptr_mem.

*a on an array is a[0] (C11 6.5.3.2p4 through the 6.3.2.1p3 decay), and clang_c_adjust::adjust_dereference rewrites it to that index.

obj->*pmf dereferences its base, and a bound member selection – which carries clang's BoundMember type, empty after the seam – becomes the member function itself, with this prepended to the pointed-to code type's parameters. Left standing, the node reaches goto_convert as a callee it cannot read (docs/roadmap/scope-clang-cpp-irep2.md §7.5).

Left as a dereference the node reaches the encoder as a pointer built from an array rather than a named element, and it aborts there: Unexpected type in int/ptr typecast.

Legacy tests is_array_like, which also admits a vector; clang rejects *v on one ("indirection requires pointer operand"), so no input reaches that half and it is not reproduced here. Incomplete arrays need no arm of their own – migrate_type gives them array_type2t with size_is_infinite. Not every shape aborts: *"abc" returned a wrong verdict instead.

Then: dereferencing a pointer to a function yields a function designator, which converts straight back to a pointer (C11 6.3.2.1p4) – so *f is f, and ******f too. Left bare, the code-typed dereference reaches a consumer that wants a pointer.

Legacy's remaining arm retypes the node to the pointer's subtype; the migration already builds that type, so no corpus input distinguishes it.

◆ adjust_reference()

virtual void clang_c_adjust_irep2::adjust_reference ( expr2tc & )
inlineprotectedvirtual

Read a reference-typed operand through, where the operand is used as a value: r becomes *r.

Empty for C, which has no references, and overridden by the C++ pass – exactly as clang_c_adjust::adjust_reference is (scope-clang-cpp-irep2.md §3.16).

Reimplemented in clang_cpp_adjust_irep2.

◆ adjust_relational()

void clang_c_adjust_irep2::adjust_relational ( expr2tc & expr)
protected

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).

◆ adjust_shift_operands()

void clang_c_adjust_irep2::adjust_shift_operands ( expr2tc & expr)
protected

IREP2 form of clang_c_adjust::adjust_expr_shifts.

C11 6.5.7p3 performs the integer promotions on each operand separately – not the usual arithmetic conversions – and 6.5.7p4 gives the result the promoted left operand's type. A _Bool left operand left unpromoted reaches bitwuzla as a one-bit sort where the shift wants a bitvector, and aborts it.

The shr to lshr/ashr selection legacy also does here has no IREP2 counterpart: there is no shr2t, so the migration has already chosen.

◆ adjust_sole_arms()

void clang_c_adjust_irep2::adjust_sole_arms ( expr2tc & expr)
protectedvirtual

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 in clang_cpp_adjust_irep2.

◆ adjust_special_functions()

void clang_c_adjust_irep2::adjust_special_functions ( expr2tc & expr)
protected

IREP2 form of the __builtin_-prefixed half of clang_c_adjust::do_special_functions: fold a recognised builtin call to the node it denotes.

These spellings are reserved, so unlike the name-matched family (is_name_matched_builtin) a program cannot supply its own definition and no shadows_user_definition query is needed (§90).

◆ adjust_statement_condition()

void clang_c_adjust_irep2::adjust_statement_condition ( expr2tc & expr)
protected

IREP2 form of the gen_typecast_bool that adjust_ifthenelse, adjust_while and adjust_for apply to a statement's controlling expression (§95).

IREP2 form of the gen_typecast_bool each of adjust_ifthenelse, adjust_while and adjust_for applies to its controlling expression.

goto_convert's branch lowering rejects a non-boolean guard, so this is the statement-level counterpart of adjust_if_expr's operand half.

◆ adjust_struct()

void clang_c_adjust_irep2::adjust_struct ( expr2tc & expr)
protected

IREP2 form of clang_c_adjust::adjust_struct's insertion loop.

A struct literal reaches this pass with an operand per declared member, while add_padding has given the type its synthetic ones; unpadded, the value is short a component and a downstream member read resolves by position onto the wrong field. pad_struct_operands is the shared helper the Python adjuster already uses for the same job (irep2/irep2_utils.h).

◆ adjust_symbol_type()

virtual void clang_c_adjust_irep2::adjust_symbol_type ( symbolt & )
inlineprotectedvirtual

Per-symbol type work, run for every symbol including the value-less ones.

C has none; C++ resolves a dynamic exception specification here (docs/roadmap/scope-clang-cpp-irep2.md §7.7).

Reimplemented in clang_cpp_adjust_irep2.

◆ adjust_vector_float_arith()

void clang_c_adjust_irep2::adjust_vector_float_arith ( expr2tc & expr)
protected

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.

Unpromoted, the backend is handed a bitvector operator over a floating-point vector and aborts.

The legacy arm returns before attaching a rounding mode for a vector ("BUG: setting rounding_mode breaks migration"), and migrate_rounding_mode then synthesises the default symbol for the attribute-less node – so the node the default path produces carries that symbol, and this builds the same one.

◆ align_call_return_type()

virtual void clang_c_adjust_irep2::align_call_return_type ( expr2tc & ,
const symbolt &  )
inlineprotectedvirtual

The call's type follows its callee's return type in C++ but not in C, where clang_c_adjust::align_se_function_call_return_type is empty.

Reimplemented in clang_cpp_adjust_irep2.

◆ arm_order()

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

The arms in the order adjust_expr applies them.

The order is load-bearing – the reasons are stated on the rows in clang_c_adjust_irep2.cpp – and was previously legible only as statement position, which no test could read. unit/clang-c-frontend/adjust_arms.test.cpp reads this.

◆ declare_implicit_callee()

void clang_c_adjust_irep2::declare_implicit_callee ( const expr2tc & expr)
protected

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.

That is a symbol-table side effect rather than an expression rewrite, so it ports independently of the rest of that arm (§70).

◆ declare_polymorphic_builtin()

void clang_c_adjust_irep2::declare_polymorphic_builtin ( expr2tc & expr)
protected

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.

A symbol-table side effect, so it ports independently of the rest of that arm, exactly as declare_implicit_callee does (§130).

◆ gen_symbol_code()

virtual void clang_c_adjust_irep2::gen_symbol_code ( symbolt & )
inlineprotectedvirtual

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 in clang_cpp_adjust_irep2.

◆ hoist_for_init()

void clang_c_adjust_irep2::hoist_for_init ( expr2tc & expr)
protected

◆ lower_complex_compound_assignment()

void clang_c_adjust_irep2::lower_complex_compound_assignment ( expr2tc & expr)
protected

IREP2 form of clang_c_adjust::lower_complex_compound_assignment.

a op= b over a complex operand becomes a = a op b, with the binary node handed to adjust_complex_arith for the component-level decomposition. goto_convert's remove_assignment rebuilds the compound form long after adjustment, so a node left here reaches the SMT layer as a raw complex operator and the backend faults on it (#6713).

◆ pad_type_symbol()

void clang_c_adjust_irep2::pad_type_symbol ( symbolt & symbol)
protected

Pad a complete struct or union type symbol to its ABI layout (§96).

add_padding on a complete struct or union, which is the half of clang_c_adjust::adjust_type that the corpus shows is load-bearing here.

The function is shared (clang-c-frontend/padding.h) and idempotent – adjust_type asserts that re-padding is a no-op – so this reuses it rather than reimplementing a layout algorithm over type2tc.

◆ promote_unary_bool_operand()

void clang_c_adjust_irep2::promote_unary_bool_operand ( expr2tc & expr)
protected

C11 6.5.3.3: the operand of unary - and ~ undergoes integer promotion, so a boolean one – a comparison, || or && – becomes int.

Left boolean it reaches the solver where a bitvector is wanted (#4078).

Member Data Documentation

◆ arms

const clang_c_adjust_irep2::arm clang_c_adjust_irep2::arms
staticprotected

The chain in application order.

The arms that run when this pass is the sole adjuster, in application order.

Defined in clang_c_adjust_irep2.cpp, beside the predicates it names. An unknown-bound declaration completed out of line: every initialiser is an address constant, so the table is constant-initialised rather than built at start-up.

The order is load-bearing wherever a comment below says so; everywhere else the guards are disjoint by expr_id and the row order is free. Each guard is re-evaluated against the current node, so an arm that rewrites a node into another kind hands it to that kind's arm below – which is how adjust_index's p[i] becomes a dereference the dereference arm then sees.

◆ context

contextt& clang_c_adjust_irep2::context
protected

◆ enclosing_location

locationt clang_c_adjust_irep2::enclosing_location
protected

Location of the innermost enclosing statement, for the nodes that carry none of their own.

◆ ns

namespacet clang_c_adjust_irep2::ns {context}
protected

◆ sole_adjuster

const bool clang_c_adjust_irep2::sole_adjuster
protected

◆ writeback_all

const bool clang_c_adjust_irep2::writeback_all
protected

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