Exemple #1
0
static bool is_externally_visible(const ir_entity *entity)
{
	switch (get_entity_visibility(entity)) {
	case ir_visibility_external:
	case ir_visibility_external_private:
	case ir_visibility_external_protected:
		return true;
	case ir_visibility_private:
	case ir_visibility_local:
		return false;
	}
	/* Return true here, the verification will fail elsewhere for this */
	return true;
}
Exemple #2
0
static bool is_externally_visible(ir_entity const *const entity)
{
	ir_visibility const vis = get_entity_visibility(entity);
	switch (vis) {
	case ir_visibility_private:
	case ir_visibility_local:
		return false;
	case ir_visibility_external:
	case ir_visibility_external_private:
	case ir_visibility_external_protected:
		return true;
	}
	panic("invalid visibility in %+F", entity);
}
Exemple #3
0
static bool check_external_linkage(const ir_entity *entity, ir_linkage linkage,
                                   const char *linkage_name)
{
	bool fine = true;
	if ((get_entity_linkage(entity) & linkage) == 0)
		return true;
	if (get_entity_visibility(entity) != ir_visibility_external) {
		report_error("entity %+F has IR_LINKAGE_%s but is not externally visible", entity, linkage_name);
		fine = false;
	}
	if (!entity_has_definition(entity)) {
		report_error("entity %+F has IR_LINKAGE_%s but is just a declaration", entity, linkage_name);
		fine = false;
	}
	return fine;
}
Exemple #4
0
int tr_verify(void)
{
	bool     fine = true;

	type_walk(check_tore, NULL, &fine);

	for (ir_segment_t s = IR_SEGMENT_FIRST; s <= IR_SEGMENT_LAST; ++s) {
		ir_type const *const segment = get_segment_type(s);
		for (size_t e = 0; e < get_compound_n_members(segment); ++e) {
			ir_entity const *const entity = get_compound_member(segment, e);
			ident           *const ld_ident = get_entity_ld_ident(entity);
			if (ld_ident == NULL &&
				get_entity_visibility(entity) != ir_visibility_private) {
				report_error("public segment member %+F has no name",
				             entity);
				fine = false;
				continue;
			}
			if (segment->flags & tf_info)
				fine &= verify_info_member(segment, entity);
		}
	}

	ir_type const *const thread_locals
		= get_segment_type(IR_SEGMENT_THREAD_LOCAL);
	for (size_t i = 0, n = get_compound_n_members(thread_locals); i < n; ++i) {
		const ir_entity *entity = get_compound_member(thread_locals, i);
		/* this is odd and should not be allowed I think */
		if (is_method_entity(entity)) {
			report_error("method %+F in thread local segment", entity);
			fine = false;
		}
		if (get_entity_linkage(entity) & IR_LINKAGE_CONSTANT) {
			report_error("entity %+F in thread local segment is constant",
			             entity);
			fine = false;
		}
	}

	return fine;
}
Exemple #5
0
int tr_verify(void)
{
	bool          fine = true;
	ir_type      *constructors;
	ir_type      *destructors;
	ir_type      *thread_locals;

	type_walk(check_tore, NULL, &fine);

	for (ir_segment_t s = IR_SEGMENT_FIRST; s <= IR_SEGMENT_LAST; ++s) {
		const ir_type *type = get_segment_type(s);
		for (size_t e = 0; e < get_compound_n_members(type); ++e) {
			ir_entity *entity = get_compound_member(type, e);
			if (get_entity_ld_ident(entity) == NULL &&
				get_entity_visibility(entity) != ir_visibility_private) {
				report_error("public segment member %+F has no name",
				             entity);
				fine = false;
			}
		}
	}

	constructors = get_segment_type(IR_SEGMENT_CONSTRUCTORS);
	for (size_t i = 0, n = get_compound_n_members(constructors); i < n; ++i) {
		const ir_entity *entity = get_compound_member(constructors, i);
		if ((get_entity_linkage(entity) & IR_LINKAGE_HIDDEN_USER) == 0) {
			report_error("entity %+F in constructors without LINKAGE_HIDDEN_USER",
			             entity);
			fine = false;
		}
		/* Mach-O doesn't like labels in this section */
		if (get_entity_ld_name(entity)[0] != '\0') {
			report_error("entity %+F in constructors must not have an ld_name",
			             entity);
			fine = false;
		}
	}
	destructors = get_segment_type(IR_SEGMENT_DESTRUCTORS);
	for (size_t i = 0, n = get_compound_n_members(destructors); i < n; ++i) {
		const ir_entity *entity = get_compound_member(destructors, i);
		if ((get_entity_linkage(entity) & IR_LINKAGE_HIDDEN_USER) == 0) {
			report_error("entity %+F in destructors without LINKAGE_HIDDEN_USER",
			             entity);
			fine = false;
		}
		/* Mach-O doesn't like labels in this section */
		if (get_entity_ld_name(entity)[0] != '\0') {
			report_error("entity %+F in destructors must not have an ld_name",
			             entity);
			fine = false;
		}
	}
	thread_locals = get_segment_type(IR_SEGMENT_THREAD_LOCAL);
	for (size_t i = 0, n = get_compound_n_members(thread_locals); i < n; ++i) {
		const ir_entity *entity = get_compound_member(thread_locals, i);
		/* this is odd and should not be allowed I think */
		if (is_method_entity(entity)) {
			report_error("method %+F in thread local segment");
			fine = false;
		}
		if (get_entity_linkage(entity) & IR_LINKAGE_CONSTANT) {
			report_error("entity %+F in thread local segment is constant");
			fine = false;
		}
	}

	return fine;
}
Exemple #6
0
int check_entity(const ir_entity *entity)
{
	bool        fine    = true;
	ir_type    *tp      = get_entity_type(entity);
	ir_linkage  linkage = get_entity_linkage(entity);

	fine &= constants_on_wrong_irg(entity);

	if (is_method_entity(entity)) {
		ir_graph *irg = get_entity_irg(entity);
		if (irg != NULL) {
			ir_entity *irg_entity = get_irg_entity(irg);
			if (irg_entity != entity) {
				report_error("entity(%+F)->irg->entity(%+F) relation invalid",
				             entity, irg_entity);
				fine = false;
			}
		}
		if (get_entity_peculiarity(entity) == peculiarity_existent) {
			ir_entity *impl = get_SymConst_entity(get_atomic_ent_value(entity));
			if (impl == NULL) {
				report_error("inherited method entity %+F must have constant pointing to existent entity.", entity);
				fine = false;
			}
		}
	}

	if (linkage & IR_LINKAGE_NO_CODEGEN) {
		if (!is_method_entity(entity)) {
			report_error("entity %+F has IR_LINKAGE_NO_CODEGEN but is not a function", entity);
			fine = false;
		} else if (get_entity_irg(entity) == NULL) {
			report_error("entity %+F has IR_LINKAGE_NO_CODEGEN but has no ir-graph anyway", entity);
			fine = false;
		}
		if (get_entity_visibility(entity) != ir_visibility_external) {
			report_error("entity %+F has IR_LINKAGE_NO_CODEGEN but is not externally visible", entity);
			fine = false;
		}
	}
	check_external_linkage(entity, IR_LINKAGE_WEAK, "WEAK");
	check_external_linkage(entity, IR_LINKAGE_GARBAGE_COLLECT,
	                       "GARBAGE_COLLECT");
	check_external_linkage(entity, IR_LINKAGE_MERGE, "MERGE");

	if (is_atomic_entity(entity) && entity->initializer != NULL) {
		ir_mode *mode = NULL;
		ir_initializer_t *initializer = entity->initializer;
		switch (initializer->kind) {
		case IR_INITIALIZER_CONST:
			mode = get_irn_mode(get_initializer_const_value(initializer));
			break;
		case IR_INITIALIZER_TARVAL:
			mode = get_tarval_mode(get_initializer_tarval_value(initializer));
			break;
		case IR_INITIALIZER_NULL:
		case IR_INITIALIZER_COMPOUND:
			break;
		}
		if (mode != NULL && mode != get_type_mode(tp)) {
			report_error("initializer of entity %+F has wrong mode.", entity);
			fine = false;
		}
	}
	return fine;
}