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

V.1k (b) IREP2-native Python adjuster (phases B.0–B.2). More...

#include <python_adjust.h>

Public Member Functions

 python_adjust (contextt &_context)
bool adjust ()
 Two-phase walk mirroring clang_c_adjust::adjust(): first complete every type symbol's IREP2 type via adjust_type (macro expansion, padding), so the value resolution below always follows fixed-up tags; then walk every code symbol's IREP2 value.
void adjust_expr (expr2tc &expr)
 Recursively visit expr and its sub-expressions, resolving transient symbol_type2t member2t/index2t sources to their followed aggregate type (the V.1k two-phase source invariant), and completing a by-name constant_struct2t literal (S2): follow + pad its type and insert zero-valued padding operands when missing.
void adjust_type (type2tc &type)
 IREP2-native clang_c_adjust::adjust_type (V.1k/B.5 milestone step S1): expand a macro symbol_type2t to the symbol's type, adjust an array's (VLA) size expression and element type, and complete a struct/union by recursing its member types and inserting alignment padding.

Protected Member Functions

bool resolve_source (expr2tc &source)
 If source is a member2t/index2t source carrying a transient symbol_type2t, follow it to the resolved struct/union/array and retype the node in place (returns true); otherwise leave it (returns false).
bool wrap_function_pointer_callee (expr2tc &fn, std::vector< expr2tc > &args)
 If fn is a symbol whose table type is pointer-to-code — the lambda/def-alias call variable — re-type it from the table, wrap it in a dereference onto the code type, and cast each argument to its declared parameter type.
bool decay_array_arguments (const expr2tc &fn, std::vector< expr2tc > &args)
 Decay an array-typed call argument to &arg[0] when the callee's declared parameter is a pointer — the array half of clang_c_adjust::adjust_function_call_arguments, which converts each argument to its parameter type through c_typecastt (whose array case decays).
std::vector< irep_idt > derive_exception_ids (const type2tc &type) const
 Derive a cpp-throw's exception-id chain from its operand's type, mirroring clang_cpp_adjust::convert_exception_id: the bare class name followed by its direct bases for a class operand (both the by-name symbol_type2t tag and the S2-resolved struct_type2t shape), "void_ptr" for the untypeable-raise any_type() operand, a _ptr suffix through real pointers, and — like legacy — a synthetic type-id fallback so the result is never empty (remove_exceptions dereferences front()).
void derive_exception_ids_rec (const type2tc &type, const std::string &suffix, std::vector< irep_idt > &ids) const
 Recursive worker for derive_exception_ids, threading the legacy _ptr suffix accumulation.
void collect_unresolved_sources (const expr2tc &expr, std::vector< std::string > &out) const
 Post-adjust strong-invariant probe (V.1k B.4): append to out one human-readable entry per unresolved node reachable from expr — a member2t/index2t source or constant_struct2t type still carrying a transient symbol_type2t (the three relaxed construction asserts, irep2_expr.h), or a resolved-struct literal whose operand count disagrees with its component list.

Protected Attributes

contextt & context
namespacet ns

Detailed Description

V.1k (b) IREP2-native Python adjuster (phases B.0–B.2).

Replaces, for the Python frontend, the legacy clang_cpp_adjust round-trip on Python output (python_language.cpp). It walks each code symbol's IREP2 value (symbolt::get_value2()) and follows a transient symbol_type2t member2t/index2t source to its resolved struct_type2t/array_type2t (the V.1k "two-phase source invariant": relaxed at construction, re-enforced here before symex) — covering both a plain instance source and a dereferenced instance pointer.

Wired into python_languaget::typecheck behind --python-irep2-adjust (default off ⇒ byte-identical): it runs after clang_cpp_adjust and, until the converter emits transient sources pre-adjust, resolves nothing — so the path is dead-but-tested, mirroring the "add the machinery, prove it inert, wire it later" pattern (esbmc/esbmc#5265). #cpp_type/#member_name carriage and dropping the legacy hop remain later phases (B.4/B.5). See docs/roadmap/irep2-migration.md, section "V.1k (b)-adjuster".

Constructor & Destructor Documentation

◆ python_adjust()

python_adjust::python_adjust ( contextt & _context)
explicit

Member Function Documentation

◆ adjust()

bool python_adjust::adjust ( )

Two-phase walk mirroring clang_c_adjust::adjust(): first complete every type symbol's IREP2 type via adjust_type (macro expansion, padding), so the value resolution below always follows fixed-up tags; then walk every code symbol's IREP2 value.

Returns true on error — specifically if the post-adjust strong invariant is violated (a member2t/index2t source or a constant_struct2t type still carries an unresolved symbol_type2t after resolution, or a resolved literal's operand count disagrees with its component list); false on success.

◆ adjust_expr()

void python_adjust::adjust_expr ( expr2tc & expr)

Recursively visit expr and its sub-expressions, resolving transient symbol_type2t member2t/index2t sources to their followed aggregate type (the V.1k two-phase source invariant), and completing a by-name constant_struct2t literal (S2): follow + pad its type and insert zero-valued padding operands when missing.

Note S2 resolves eagerly where the legacy adjust_struct leaves the literal's type lazily by-name (the deliberate RV-adj6 divergence — IREP2's strong construction invariant requires the resolved type on the node). Recurses operands first, so nested sources (self.b.a) resolve inner-to-outer.

◆ adjust_type()

void python_adjust::adjust_type ( type2tc & type)

IREP2-native clang_c_adjust::adjust_type (V.1k/B.5 milestone step S1): expand a macro symbol_type2t to the symbol's type, adjust an array's (VLA) size expression and element type, and complete a struct/union by recursing its member types and inserting alignment padding.

Padding reuses the legacy add_padding through the type round-trip (migrate_type_back → add_padding → migrate_type) — lossless for every type the Python frontend emits (a packed union would drop its packed flag, but the converter emits no unions) — so the layout is byte-identical to the legacy pass by construction (risk RV-adj5). A non-macro tag reference deliberately stays by-name, exactly as the legacy pass leaves it (parity subtlety RV-adj6); IREP2 has no incomplete aggregates (an incomplete type stays a symbol_type2t), so the legacy !type.incomplete() guard has no analogue here.

Known scope limits vs the legacy pass, deliberate until later S-steps: (1) an unknown top-level type symbol is left by-name for the exit invariant instead of abort()ing; (2) no vector_typet arm (the Python frontend never emits vector types); (3) non-type symbols' own types (e.g. a function's code type) are not adjusted — the legacy adjust_symbol completes them (clang_c_adjust_expr.cpp:70-74), and clang_cpp_adjust still does on the live pipeline. Type symbols ARE completed: adjust() runs a type-symbol pre-pass before value resolution, mirroring the legacy two-phase order. (4) The pre-pass write-back (set_type(type2tc)) cannot carry legacy-only struct metadata — the "bases" sub-irep (read by exception_typeid.cpp and base_type.cpp for Python exception-hierarchy/catch matching) and component access/#is_padding flags are lost if the write-back fires. Inert today (the write-back never fires post-clang_cpp_adjust); the B.5 flip must either re-attach the preserved sub-ireps on a legacy write-back or move the "bases" carriage to IREP2 (W3/V.2) first.

◆ collect_unresolved_sources()

void python_adjust::collect_unresolved_sources ( const expr2tc & expr,
std::vector< std::string > & out ) const
protected

Post-adjust strong-invariant probe (V.1k B.4): append to out one human-readable entry per unresolved node reachable from expr — a member2t/index2t source or constant_struct2t type still carrying a transient symbol_type2t (the three relaxed construction asserts, irep2_expr.h), or a resolved-struct literal whose operand count disagrees with its component list.

adjust() logs these entries when the exit invariant fires — the per-node detail is the work-list the B.5-era resolution steps (S3+) drain. Recursive.

◆ decay_array_arguments()

bool python_adjust::decay_array_arguments ( const expr2tc & fn,
std::vector< expr2tc > & args )
protected

Decay an array-typed call argument to &arg[0] when the callee's declared parameter is a pointer — the array half of clang_c_adjust::adjust_function_call_arguments, which converts each argument to its parameter type through c_typecastt (whose array case decays).

Without it symex aborts binding the argument. Returns true when any argument was rewritten.

◆ derive_exception_ids()

std::vector< irep_idt > python_adjust::derive_exception_ids ( const type2tc & type) const
protected

Derive a cpp-throw's exception-id chain from its operand's type, mirroring clang_cpp_adjust::convert_exception_id: the bare class name followed by its direct bases for a class operand (both the by-name symbol_type2t tag and the S2-resolved struct_type2t shape), "void_ptr" for the untypeable-raise any_type() operand, a _ptr suffix through real pointers, and — like legacy — a synthetic type-id fallback so the result is never empty (remove_exceptions dereferences front()).

Used by adjust_expr to complete an empty code_cpp_throw2t::exception_list — flip blocker #1 (docs/roadmap/irep2-migration.md, "Flip-probe census").

◆ derive_exception_ids_rec()

void python_adjust::derive_exception_ids_rec ( const type2tc & type,
const std::string & suffix,
std::vector< irep_idt > & ids ) const
protected

Recursive worker for derive_exception_ids, threading the legacy _ptr suffix accumulation.

◆ resolve_source()

bool python_adjust::resolve_source ( expr2tc & source)
protected

If source is a member2t/index2t source carrying a transient symbol_type2t, follow it to the resolved struct/union/array and retype the node in place (returns true); otherwise leave it (returns false).

The source is a plain symbol2t (the instance) or a dereference2t of a pointer→tag-Cls instance pointer — both arrive as a symbol_type2t source, since a member/index cannot be constructed over a raw pointer.

◆ wrap_function_pointer_callee()

bool python_adjust::wrap_function_pointer_callee ( expr2tc & fn,
std::vector< expr2tc > & args )
protected

If fn is a symbol whose table type is pointer-to-code — the lambda/def-alias call variable — re-type it from the table, wrap it in a dereference onto the code type, and cast each argument to its declared parameter type.

Returns true when rewritten.

Member Data Documentation

◆ context

contextt& python_adjust::context
protected

◆ ns

namespacet python_adjust::ns
protected

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