blob: fd20a9b7a2949476fc1a3f946834999dc51e0c9e [file] [log] [blame]
/* Every class defined here represents a single bit value of a variable.
Every variable will be represented as a vector of these classes which later
will be used for bit-level symbolic execution.
Copyright (C) 2022-2025 Free Software Foundation, Inc.
Contributed by Matevos Mehrabyan <matevosmehrabyan@gmail.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/>. */
#include "sym-exec-expr-is-a-helper.h"
/* Returns type of the bit. */
value_type
value_bit::get_type () const
{
return m_type;
}
/* Constructor that sets the bit's initial position and its origin. */
symbolic_bit::symbolic_bit (size_t i, tree orig)
: value_bit (i), m_origin (orig)
{
m_type = SYMBOLIC_BIT;
}
/* Constructor that sets m_val to the specified value. */
bit::bit (unsigned char i) : m_val (i)
{
m_type = BIT;
}
/* Returns left operand of the expression. */
value_bit *
bit_expression::get_left ()
{
return m_left;
}
/* Returns right operand of the expression. */
value_bit *
bit_expression::get_right ()
{
return m_right;
}
/* Sets left operand of the expression. */
void
bit_expression::set_left (value_bit *expr)
{
m_left = expr;
}
/* Sets right operand of the expression. */
void
bit_expression::set_right (value_bit *expr)
{
m_right = expr;
}
/* Returns the bit's initial index in bit-vector. */
size_t
value_bit::get_index () const
{
return m_index;
}
/* Returns the value of the bit. */
unsigned char
bit::get_val () const
{
return m_val;
}
/* Sets the value of the bit. */
void
bit::set_val (unsigned char new_val)
{
m_val = new_val;
}
/* Constructor that sets the left and right side bits
of the bit_complement_expression sign. */
bit_complement_expression::bit_complement_expression (value_bit *right)
{
/* As complement has only one argument, we use only the m_right. */
this->m_left = nullptr;
this->m_right = right;
m_type = BIT_COMPLEMENT_EXPRESSION;
}
/* Copy constructor for bit_complement_expression. */
bit_complement_expression::bit_complement_expression (
const bit_complement_expression &expr)
{
bit_expression::copy (&expr);
}
/* Destructor for bit_expression. */
bit_expression::~bit_expression ()
{
delete m_left;
m_left = nullptr;
delete m_right;
m_right = nullptr;
}
/* Returns a copy of the bit. */
value_bit *
symbolic_bit::copy () const
{
return new symbolic_bit (*this);
}
/* Return a copy of the bit. */
value_bit *
bit::copy () const
{
return new bit (*this);
}
/* Copies the given expression to it by copying the left and right operands. */
void
bit_expression::copy (const bit_expression *expr)
{
if (expr->m_left)
m_left = expr->m_left->copy ();
if (expr->m_right)
m_right = expr->m_right->copy ();
m_type = expr->m_type;
}
/* Returns a copy of the expression. */
value_bit *
bit_xor_expression::copy () const
{
return new bit_xor_expression (*this);
}
/* Returns a copy of the expression. */
value_bit *
bit_and_expression::copy () const
{
return new bit_and_expression (*this);
}
/* Returns a copy of the expression. */
value_bit *
bit_or_expression::copy () const
{
return new bit_or_expression (*this);
}
/* Returns a copy of the expression. */
value_bit *
shift_right_expression::copy () const
{
return new shift_right_expression (*this);
}
/* Returns a copy of the expression. */
value_bit *
shift_left_expression::copy () const
{
return new shift_left_expression (*this);
}
/* Returns a copy of the expression. */
value_bit *
add_expression::copy () const
{
return new add_expression (*this);
}
/* Returns a copy of the expression. */
value_bit *
sub_expression::copy () const
{
return new sub_expression (*this);
}
/* Returns a copy of the expression. */
value_bit *
bit_complement_expression::copy () const
{
return new bit_complement_expression (*this);
}
/* Constructor that sets the left and right side bits
of the bit_xor_expression sign. */
bit_xor_expression::bit_xor_expression (value_bit *left, value_bit *right)
{
this->m_left = left;
this->m_right = right;
m_type = BIT_XOR_EXPRESSION;
}
/* Copy constructor for bit_xor_expression. */
bit_xor_expression::bit_xor_expression (const bit_xor_expression &expr)
{
bit_expression::copy (&expr);
}
/* Constructor that sets the left and right side bits
of the bit_and_expression sign. */
bit_and_expression::bit_and_expression (value_bit *left, value_bit *right)
{
this->m_left = left;
this->m_right = right;
m_type = BIT_AND_EXPRESSION;
}
/* Copy constructor for bit_and_expression. */
bit_and_expression::bit_and_expression (const bit_and_expression &expr)
{
bit_expression::copy (&expr);
}
/* Constructor that sets the left and right side bits
of the bit_or_expression sign. */
bit_or_expression::bit_or_expression (value_bit *left, value_bit *right)
{
this->m_left = left;
this->m_right = right;
m_type = BIT_OR_EXPRESSION;
}
/* Copy constructor for bit_or_expression. */
bit_or_expression::bit_or_expression (const bit_or_expression &expr)
{
bit_expression::copy (&expr);
}
/* Constructor that sets the left and right side bits
of the shift_right_expression sign. */
shift_right_expression::shift_right_expression (value_bit *left,
value_bit *right)
{
this->m_left = left;
this->m_right = right;
m_type = SHIFT_RIGHT_EXPRESSION;
}
/* Copy constructor for shift_right_expression. */
shift_right_expression::shift_right_expression (
const shift_right_expression &expr)
{
bit_expression::copy (&expr);
}
/* Constructor that sets the left and right side bits
of the shift_left_expression sign. */
shift_left_expression::shift_left_expression (value_bit *left, value_bit *right)
{
this->m_left = left;
this->m_right = right;
m_type = SHIFT_LEFT_EXPRESSION;
}
/* Copy constructor for shift_left_expression. */
shift_left_expression::shift_left_expression (const shift_left_expression &expr)
{
bit_expression::copy (&expr);
}
/* Constructor that sets the left and right side bits
of the add_expression sign. */
add_expression::add_expression (value_bit *left, value_bit *right)
{
this->m_left = left;
this->m_right = right;
m_type = ADD_EXPRESSION;
}
/* Copy constructor for add_expression. */
add_expression::add_expression (const add_expression &expr)
{
bit_expression::copy (&expr);
}
/* Constructor that sets the left and right side bits
of the sub_expression sign. */
sub_expression::sub_expression (value_bit *left, value_bit *right)
{
this->m_left = left;
this->m_right = right;
m_type = SUB_EXPRESSION;
}
/* Copy constructor for sub_expression. */
sub_expression::sub_expression (const sub_expression &expr)
{
bit_expression::copy (&expr);
}
/* Returns the origin of the bit, to whom it belongs. */
tree
symbolic_bit::get_origin ()
{
return m_origin;
}
/* Prints the bit. */
void
symbolic_bit::print ()
{
if (dump_file)
{
print_generic_expr (dump_file, m_origin, dump_flags);
fprintf (dump_file, "[%zu]", m_index);
}
}
/* Prints the bit. */
void
bit::print ()
{
if (dump_file)
fprintf (dump_file, "%u", m_val);
}
/* Depending on the expression, prints its sign. */
void
bit_expression::print_expr_sign ()
{
switch (m_type)
{
case BIT_XOR_EXPRESSION:
fprintf (dump_file, " ^ ");
break;
case BIT_AND_EXPRESSION:
fprintf (dump_file, " & ");
break;
case BIT_OR_EXPRESSION:
fprintf (dump_file, " | ");
break;
case SHIFT_RIGHT_EXPRESSION:
fprintf (dump_file, " >> ");
break;
case SHIFT_LEFT_EXPRESSION:
fprintf (dump_file, " << ");
break;
case ADD_EXPRESSION:
fprintf (dump_file, " + ");
break;
case SUB_EXPRESSION:
fprintf (dump_file, " - ");
break;
default:
fprintf (dump_file, " ?? ");
}
}
/* Prints the expression. */
void
bit_expression::print ()
{
if (dump_file)
{
fprintf (dump_file, "(");
if (m_left)
m_left->print ();
else
fprintf (dump_file, "null");
print_expr_sign ();
if (m_right)
m_right->print ();
else
fprintf (dump_file, "null");
fprintf (dump_file, ")");
}
}
/* Prints the expression. */
void
bit_complement_expression::print ()
{
if (dump_file)
{
fprintf (dump_file, "!");
if (m_right)
m_right->print ();
else
fprintf (dump_file, "null");
}
}