Exemple #1
0
bool types_compatible_ignore_qualifiers(const type_t *type1,
                                        const type_t *type2)
{
	assert(!is_typeref(type1));
	assert(!is_typeref(type2));

	/* shortcut: the same type is always compatible */
	if (type1 == type2)
		return true;

	if (type1->kind != type2->kind) {
		/* enum types are compatible to their base integer type */
		if ((type1->kind == TYPE_ENUM
			&& is_type_atomic(type2, type1->enumt.base.akind))
		 || (type2->kind == TYPE_ENUM
		    && is_type_atomic(type1, type2->enumt.base.akind)))
		    return true;
		/* error types are compatible to everything to avoid follow-up errors */
		if (!is_type_valid(type1) || !is_type_valid(type2))
			return true;
		return false;
	}

	switch (type1->kind) {
	case TYPE_FUNCTION:
		return function_types_compatible(&type1->function, &type2->function);
	case TYPE_ATOMIC:
	case TYPE_IMAGINARY:
	case TYPE_COMPLEX:
		return type1->atomic.akind == type2->atomic.akind;
	case TYPE_ARRAY:
		return array_types_compatible(&type1->array, &type2->array);
	case TYPE_POINTER: {
		const type_t *const to1 = skip_typeref(type1->pointer.points_to);
		const type_t *const to2 = skip_typeref(type2->pointer.points_to);
		return types_compatible(to1, to2);
	}
	case TYPE_REFERENCE: {
		const type_t *const to1 = skip_typeref(type1->reference.refers_to);
		const type_t *const to2 = skip_typeref(type2->reference.refers_to);
		return types_compatible(to1, to2);
	}
	case TYPE_COMPOUND_STRUCT:
	case TYPE_COMPOUND_UNION:
		return type1->compound.compound == type2->compound.compound;
	case TYPE_ENUM:
		return type1->enumt.enume == type2->enumt.enume;
	case TYPE_ERROR:
	case TYPE_VOID:
		return true;
	case TYPE_TYPEDEF:
	case TYPE_TYPEOF:
		break; /* we already tested for is_typeref() above */
	case TYPE_BUILTIN_TEMPLATE:
		panic("unexpected type");
	}
	panic("invalid type kind");
}
Exemple #2
0
bool types_compatible(const type_t *type1, const type_t *type2)
{
	assert(!is_typeref(type1));
	assert(!is_typeref(type2));

	/* shortcut: the same type is always compatible */
	if (type1 == type2)
		return true;

	if (!is_type_valid(type1) || !is_type_valid(type2))
		return true;

	if (type1->base.qualifiers != type2->base.qualifiers)
		return false;
	if (type1->kind != type2->kind)
		return false;

	switch (type1->kind) {
	case TYPE_FUNCTION:
		return function_types_compatible(&type1->function, &type2->function);
	case TYPE_ATOMIC:
	case TYPE_IMAGINARY:
	case TYPE_COMPLEX:
		return type1->atomic.akind == type2->atomic.akind;
	case TYPE_ARRAY:
		return array_types_compatible(&type1->array, &type2->array);

	case TYPE_POINTER: {
		const type_t *const to1 = skip_typeref(type1->pointer.points_to);
		const type_t *const to2 = skip_typeref(type2->pointer.points_to);
		return types_compatible(to1, to2);
	}

	case TYPE_REFERENCE: {
		const type_t *const to1 = skip_typeref(type1->reference.refers_to);
		const type_t *const to2 = skip_typeref(type2->reference.refers_to);
		return types_compatible(to1, to2);
	}

	case TYPE_COMPOUND_STRUCT:
	case TYPE_COMPOUND_UNION: {
		break;
	}
	case TYPE_ENUM:
		/* TODO: not implemented */
		break;

	case TYPE_ERROR:
		/* Hmm, the error type should be compatible to all other types */
		return true;
	case TYPE_TYPEDEF:
	case TYPE_TYPEOF:
		panic("typerefs not skipped in compatible types?!?");
	}

	return false;
}
Exemple #3
0
bool types_compatible(const type_t *type1, const type_t *type2)
{
	assert(!is_typeref(type1));
	assert(!is_typeref(type2));

	/* shortcut: the same type is always compatible */
	if (type1 == type2)
		return true;

	if (type1->base.qualifiers == type2->base.qualifiers &&
	    type1->kind            == type2->kind) {
		switch (type1->kind) {
		case TYPE_FUNCTION:
			return function_types_compatible(&type1->function, &type2->function);
		case TYPE_ATOMIC:
		case TYPE_IMAGINARY:
		case TYPE_COMPLEX:
			return type1->atomic.akind == type2->atomic.akind;
		case TYPE_ARRAY:
			return array_types_compatible(&type1->array, &type2->array);

		case TYPE_POINTER: {
			const type_t *const to1 = skip_typeref(type1->pointer.points_to);
			const type_t *const to2 = skip_typeref(type2->pointer.points_to);
			return types_compatible(to1, to2);
		}

		case TYPE_REFERENCE: {
			const type_t *const to1 = skip_typeref(type1->reference.refers_to);
			const type_t *const to2 = skip_typeref(type2->reference.refers_to);
			return types_compatible(to1, to2);
		}

		case TYPE_COMPOUND_STRUCT:
		case TYPE_COMPOUND_UNION:
			break;

		case TYPE_ENUM:
			/* TODO: not implemented */
			break;

		case TYPE_ERROR:
		case TYPE_VOID:
			return true;

		case TYPE_TYPEDEF:
		case TYPE_TYPEOF:
			panic("typeref not skipped");
		case TYPE_BUILTIN_TEMPLATE:
			panic("unexpected type");
		}
	}

	return !is_type_valid(type1) || !is_type_valid(type2);
}
Exemple #4
0
type_t *get_qualified_type(type_t *orig_type, type_qualifiers_t const qual)
{
	type_t *type = skip_typeref(orig_type);

	type_t *copy;
	if (is_type_array(type)) {
		/* For array types the element type has to be adjusted */
		type_t *element_type      = type->array.element_type;
		type_t *qual_element_type = get_qualified_type(element_type, qual);

		if (qual_element_type == element_type)
			return orig_type;

		copy                     = duplicate_type(type);
		copy->array.element_type = qual_element_type;
	} else if (is_type_valid(type)) {
		if ((type->base.qualifiers & qual) == (int)qual)
			return orig_type;

		copy                   = duplicate_type(type);
		copy->base.qualifiers |= qual;
	} else {
		return type;
	}

	return identify_new_type(copy);
}
int idmef_value_type_compare(const idmef_value_type_t *type1,
                             const idmef_value_type_t *type2,
                             idmef_criterion_operator_t op)
{
        int ret;

        ret = is_type_valid(type1->id);
        if ( ret < 0 )
                return ret;

        if ( type1->id != type2->id ) {
                if ( type1->id != IDMEF_VALUE_TYPE_ENUM && type2->id != IDMEF_VALUE_TYPE_STRING )
                        return requiem_error(REQUIEM_ERROR_IDMEF_VALUE_TYPE_COMPARE_MISMATCH);
        }

        assert(op & ops_tbl[type1->id].operator);

        if ( ! ops_tbl[type1->id].compare )
                return requiem_error_verbose(REQUIEM_ERROR_IDMEF_VALUE_TYPE_COMPARE_UNAVAILABLE,
                                             "Object type '%s' does not support compare operation",
                                             idmef_value_type_to_string(type1->id));

        ret = ops_tbl[type1->id].compare(type1, type2, ops_tbl[type1->id].len, op & ~IDMEF_CRITERION_OPERATOR_NOT);
        if ( ret < 0 ) /* not an error -> no match */
                ret = 1;

        if ( op & IDMEF_CRITERION_OPERATOR_NOT )
                return (ret == 0) ? 1 : 0;
        else
                return ret;
}
Exemple #6
0
void layout_union_type(compound_type_t *type)
{
	assert(type->compound != NULL);

	compound_t *compound = type->compound;
	if (! compound->complete)
		return;

	il_size_t      size      = 0;
	il_alignment_t alignment = compound->alignment;

	entity_t *entry = compound->members.entities;
	for (; entry != NULL; entry = entry->base.next) {
		if (entry->kind != ENTITY_COMPOUND_MEMBER)
			continue;

		type_t *m_type = skip_typeref(entry->declaration.type);
		if (! is_type_valid(skip_typeref(m_type)))
			continue;

		entry->compound_member.offset = 0;
		il_size_t m_size = get_type_size(m_type);
		if (m_size > size)
			size = m_size;
		il_alignment_t m_alignment = get_type_alignment_compound(m_type);
		if (m_alignment > alignment)
			alignment = m_alignment;
	}
	size = (size + alignment - 1) & -alignment;

	compound->size      = size;
	compound->alignment = alignment;
}
const char *idmef_value_type_to_string(idmef_value_type_id_t type)
{
        int ret;

        ret = is_type_valid(type);
        if ( ret < 0 )
                return NULL;

        return ops_tbl[type].name;
}
nas_acl_action_t::nas_acl_action_t (BASE_ACL_ACTION_TYPE_t t)
{
    if (!is_type_valid (t)) {
        throw nas::base_exception {NAS_ACL_E_ATTR_VAL, __PRETTY_FUNCTION__,
            std::string {"Invalid action type "} + std::to_string (t)};
    }

    memset (&_a_info, 0, sizeof (_a_info));

    _a_info.action_type = t;
    _a_info.values_type = NDI_ACL_ACTION_NO_VALUE;
}
int idmef_value_type_get_applicable_operators(idmef_value_type_id_t type, idmef_criterion_operator_t *result)
{
        int ret;

        ret = is_type_valid(type);
        if ( ret < 0 )
                return ret;

        *result = ops_tbl[type].operator;

        return 0;
}
void idmef_value_type_destroy(idmef_value_type_t *type)
{
        int ret;

        ret = is_type_valid(type->id);
        if ( ret < 0 )
                return;

        if ( ! ops_tbl[type->id].destroy )
                return;

        ops_tbl[type->id].destroy(type);
}
int idmef_value_type_check_operator(idmef_value_type_id_t type, idmef_criterion_operator_t op)
{
        int ret;

        ret = is_type_valid(type);
        if ( ret < 0 )
                return ret;

        if ( (~ops_tbl[type].operator & op) == 0 )
                return 0;

        return requiem_error_verbose(REQUIEM_ERROR_IDMEF_CRITERION_UNSUPPORTED_OPERATOR,
                                     "Object type '%s' does not support operator '%s'",
                                     idmef_value_type_to_string(type), idmef_criterion_operator_to_string(op));
}
int idmef_value_type_write(const idmef_value_type_t *src, requiem_string_t *out)
{
        int ret;

        ret = is_type_valid(src->id);
        if ( ret < 0 )
                return ret;

        if ( ! ops_tbl[src->id].write )
                return requiem_error_verbose(REQUIEM_ERROR_IDMEF_VALUE_TYPE_WRITE_UNAVAILABLE,
                                             "Object type '%s' does not support write operation",
                                             idmef_value_type_to_string(src->id));

        return ops_tbl[src->id].write(src, out);
}
int idmef_value_type_ref(const idmef_value_type_t *vt)
{
        int ret;

        ret = is_type_valid(vt->id);
        if ( ret < 0 )
                return ret;

        if ( ! ops_tbl[vt->id].ref )
                return requiem_error_verbose(REQUIEM_ERROR_IDMEF_VALUE_TYPE_REF_UNAVAILABLE,
                                             "Object type '%s' does not support ref operation",
                                             idmef_value_type_to_string(vt->id));

        return ops_tbl[vt->id].ref(vt);
}
int idmef_value_type_copy(const idmef_value_type_t *src, void *dst)
{
        int ret;

        ret = is_type_valid(src->id);
        if ( ret < 0 )
                return ret;

        if ( ! ops_tbl[src->id].copy )
                return requiem_error_verbose(REQUIEM_ERROR_IDMEF_VALUE_TYPE_COPY_UNAVAILABLE,
                                             "Object type '%s' does not support copy operation",
                                             idmef_value_type_to_string(src->id));

        return ops_tbl[src->id].copy(src, dst, ops_tbl[src->id].len);
}
int idmef_value_type_read(idmef_value_type_t *dst, const char *buf)
{
        int ret;

        ret = is_type_valid(dst->id);
        if ( ret < 0 )
                return ret;

        if ( ! ops_tbl[dst->id].read )
                return requiem_error_verbose(REQUIEM_ERROR_IDMEF_VALUE_TYPE_READ_UNAVAILABLE,
                                             "Object type '%s' does not support read operation",
                                             idmef_value_type_to_string(dst->id));

        ret = ops_tbl[dst->id].read(dst, buf);
        return (ret < 0) ? ret : 0;
}
int idmef_value_type_clone(const idmef_value_type_t *src, idmef_value_type_t *dst)
{
        int ret;

        assert(dst->id == src->id);

        ret = is_type_valid(dst->id);
        if ( ret < 0 )
                return ret;

        if ( ! ops_tbl[dst->id].clone )
                return requiem_error_verbose(REQUIEM_ERROR_IDMEF_VALUE_TYPE_CLONE_UNAVAILABLE,
                                             "Object type '%s' does not support clone operation",
                                             idmef_value_type_to_string(dst->id));

        return ops_tbl[dst->id].clone(src, dst, ops_tbl[dst->id].len);
}
Exemple #17
0
void determine_enum_values(enum_t *const enume)
{
	if (enume->error)
		return;

	ir_mode   *const mode    = atomic_modes[enume->akind];
	ir_tarval *const one     = get_mode_one(mode);
	ir_tarval *      tv_next = get_mode_null(mode);

	for (entity_t *entry = enume->first_value;
	     entry != NULL && entry->kind == ENTITY_ENUM_VALUE;
	     entry = entry->base.next) {
		expression_t *const init = entry->enum_value.value;
		if (init != NULL) {
			type_t *const init_type = skip_typeref(init->base.type);
			if (!is_type_valid(init_type))
				continue;
			tv_next = fold_expression(init);
		}
		assert(entry->enum_value.tv == NULL || entry->enum_value.tv == tv_next);
		entry->enum_value.tv = tv_next;
		tv_next = tarval_add(tv_next, one);
	}
}
Exemple #18
0
void layout_compound(compound_t *const compound)
{
	bool     const is_union   = compound->base.kind == ENTITY_UNION;
	bool     const is_packed  = compound->packed;
	il_alignment_t alignment  = compound->alignment;
	size_t         bit_offset = 0;
	il_size_t      size       = 0;
	bool           need_pad   = false;
	for (entity_t *entry = compound->members.entities; entry; entry = entry->base.next) {
		if (entry->kind != ENTITY_COMPOUND_MEMBER)
			continue;

		compound_member_t *const member = &entry->compound_member;
		type_t            *const m_type = skip_typeref(member->base.type);
		if (!is_type_valid(m_type))
			continue;

		if (is_packed) {
			/* GCC: Specifying this attribute for `struct' and `union' types is
			 * equivalent to specifying the `packed' attribute on each of the
			 * structure or union members. */
			member->base.alignment = 1;
		}

		il_alignment_t const m_alignment = member->base.alignment;
		alignment = MAX(alignment, m_alignment);

		unsigned const m_size = get_type_size(m_type);
		if (is_union) {
			size = MAX(size, m_size);
		} else if (member->bitfield) {
			il_alignment_t const alignment_mask = m_alignment - 1;
			size_t         const base_size      = m_size * BITS_PER_BYTE;
			size_t         const bit_size       = member->bit_size;
			if (!is_packed) {
				bit_offset += (size & alignment_mask) * BITS_PER_BYTE;
				size       &= ~alignment_mask;

				if (bit_offset + bit_size > base_size || bit_size == 0) {
					size      += (bit_offset + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
					size       = round_up2(size, m_alignment);
					bit_offset = 0;
				}
			}

			if (target.byte_order_big_endian) {
				member->offset     = size & ~alignment_mask;
				member->bit_offset = base_size - bit_offset - bit_size;
			} else {
				member->offset     = size;
				member->bit_offset = bit_offset;
			}

			bit_offset += bit_size;
			size       += bit_offset / BITS_PER_BYTE;
			bit_offset %= BITS_PER_BYTE;
		} else {
			if (bit_offset != 0) {
				bit_offset = 0;
				size      += 1;
			}

			il_size_t const new_size = round_up2(size, m_alignment);
			if (new_size > size) {
				need_pad = true;
				size     = new_size;
			}

			member->offset = size;
			size          += m_size;
		}
	}

	if (bit_offset != 0)
		size += 1;

	il_size_t const new_size = round_up2(size, alignment);
	if (new_size > size) {
		need_pad = true;
		size     = new_size;
	}

	position_t const *const pos = &compound->base.pos;
	if (need_pad) {
		warningf(WARN_PADDED, pos, "'%N' needs padding", compound);
	} else if (is_packed) {
		warningf(WARN_PACKED, pos, "superfluous packed attribute on '%N'", compound);
	}

	compound->size      = size;
	compound->alignment = alignment;
}
Exemple #19
0
void layout_compound(compound_t *const compound)
{
	bool     const is_union   = compound->base.kind == ENTITY_UNION;
	unsigned       alignment  = compound->alignment;
	size_t         bit_offset = 0;
	unsigned       size       = 0;
	bool           need_pad   = false;
	for (entity_t *entry = compound->members.first_entity; entry;
	     entry = entry->base.next) {
		if (entry->kind != ENTITY_COMPOUND_MEMBER)
			continue;

		compound_member_t *const member = &entry->compound_member;
		type_t            *const m_type = skip_typeref(member->base.type);
		if (!is_type_valid(m_type))
			continue;

		unsigned m_alignment = get_declaration_alignment(&member->base);
		alignment = MAX(alignment, m_alignment);

		unsigned const m_size = get_ctype_size(m_type);
		if (is_union) {
			size = MAX(size, m_size);
		} else if (member->bitfield) {
			unsigned const alignment_mask = m_alignment - 1;
			size_t   const base_size      = m_size * BITS_PER_BYTE;
			size_t   const bit_size       = member->bit_size;

			bit_offset += (size & alignment_mask) * BITS_PER_BYTE;
			size       &= ~alignment_mask;
			if (bit_offset + bit_size > base_size
				|| (bit_size == 0 && !(member->base.modifiers & DM_PACKED))) {
				size      += (bit_offset + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
				size       = round_up2(size, m_alignment);
				bit_offset = 0;
			}

			if (target.byte_order_big_endian) {
				member->offset     = size & ~alignment_mask;
				member->bit_offset = base_size - bit_offset - bit_size;
			} else {
				member->offset     = size;
				member->bit_offset = bit_offset;
			}

			bit_offset += bit_size;
			size       += bit_offset / BITS_PER_BYTE;
			bit_offset %= BITS_PER_BYTE;
		} else {
			if (bit_offset != 0) {
				bit_offset = 0;
				size      += 1;
			}

			unsigned const new_size = round_up2(size, m_alignment);
			if (new_size > size) {
				need_pad = true;
				size     = new_size;
			}

			member->offset = size;
			size          += m_size;
		}
	}

	if (bit_offset != 0)
		size += 1;

	unsigned const new_size = round_up2(size, alignment);
	if (new_size > size) {
		need_pad = true;
		size     = new_size;
	}

	position_t const *const pos = &compound->base.pos;
	if (need_pad) {
		warningf(WARN_PADDED, pos, "%N needs padding", compound);
	} else if (compound->packed) {
		warningf(WARN_PACKED, pos, "superfluous packed attribute on %N",
		         compound);
	}

	compound->size      = size;
	compound->alignment = alignment;
}
Exemple #20
0
void layout_struct_type(compound_type_t *type)
{
	assert(type->compound != NULL);

	compound_t *compound = type->compound;
	if (!compound->complete)
		return;
	if (type->compound->layouted)
		return;

	il_size_t      offset    = 0;
	il_alignment_t alignment = compound->alignment;
	bool           need_pad  = false;

	entity_t *entry = compound->members.entities;
	while (entry != NULL) {
		if (entry->kind != ENTITY_COMPOUND_MEMBER) {
			entry = entry->base.next;
			continue;
		}

		type_t *const m_type  = skip_typeref(entry->declaration.type);
		if (!is_type_valid(m_type)) {
			entry = entry->base.next;
			continue;
		}

		if (entry->compound_member.bitfield) {
			entry = pack_bitfield_members(&offset, &alignment,
			                              compound->packed, entry);
			continue;
		}

		il_alignment_t m_alignment = get_type_alignment_compound(m_type);
		if (m_alignment > alignment)
			alignment = m_alignment;

		if (!compound->packed) {
			il_size_t new_offset = (offset + m_alignment-1) & -m_alignment;

			if (new_offset > offset) {
				need_pad = true;
				offset   = new_offset;
			}
		}

		entry->compound_member.offset = offset;
		offset += get_type_size(m_type);

		entry = entry->base.next;
	}

	if (!compound->packed) {
		il_size_t new_offset = (offset + alignment-1) & -alignment;
		if (new_offset > offset) {
			need_pad = true;
			offset   = new_offset;
		}
	}

	source_position_t const *const pos = &compound->base.source_position;
	if (need_pad) {
		warningf(WARN_PADDED, pos, "'%T' needs padding", type);
	} else if (compound->packed) {
		warningf(WARN_PACKED, pos, "superfluous packed attribute on '%T'", type);
	}

	compound->size      = offset;
	compound->alignment = alignment;
	compound->layouted  = true;
}