[STATEMENT_MS_TRY] = sizeof(ms_try_statement_t),
[STATEMENT_LEAVE] = sizeof(leave_statement_t)
};
- assert(kind < lengthof(sizes));
+ assert((size_t)kind < lengthof(sizes));
assert(sizes[kind] != 0);
return sizes[kind];
}
if (kind >= EXPR_BINARY_FIRST && kind <= EXPR_BINARY_LAST) {
return sizes[EXPR_BINARY_FIRST];
}
- assert(kind < lengthof(sizes));
+ assert((size_t)kind < lengthof(sizes));
assert(sizes[kind] != 0);
return sizes[kind];
}
[INITIALIZER_LIST] = sizeof(initializer_list_t),
[INITIALIZER_DESIGNATOR] = sizeof(initializer_designator_t)
};
- assert(kind < lengthof(sizes));
+ assert((size_t)kind < lengthof(sizes));
assert(sizes[kind] != 0);
return sizes[kind];
}
assert(namespc != NAMESPACE_INVALID);
entity_t *entity = symbol->entity;
for (; entity != NULL; entity = entity->base.symbol_next) {
- if (entity->base.namespc == namespc)
+ if ((namespace_tag_t)entity->base.namespc == namespc)
return entity;
}
entity_kind_tag_t const kind)
{
entity_t *entity = get_entity(symbol, NAMESPACE_TAG);
- if (entity != NULL && entity->kind != kind) {
+ if (entity != NULL && (entity_kind_tag_t)entity->kind != kind) {
errorf(HERE,
"'%Y' defined as wrong kind of tag (previous definition %P)",
symbol, &entity->base.source_position);
}
/**
- * Checks if a given expression can be used as an constant initializer.
+ * Checks if a given expression can be used as a constant initializer.
*/
static bool is_initializer_constant(const expression_t *expression)
{
- return
- is_constant_expression(expression) != EXPR_CLASS_VARIABLE ||
- is_address_constant(expression) != EXPR_CLASS_VARIABLE;
+ return is_constant_expression(expression) != EXPR_CLASS_VARIABLE ||
+ is_linker_constant(expression) != EXPR_CLASS_VARIABLE;
}
/**
* existing definition in outer scope */
entity = NULL;
} else if (entity->compound.complete && token.type == '{') {
- errorf(&pos, "multiple definitions of '%s %Y' (previous definition %P)",
- is_struct ? "struct" : "union", symbol,
- &entity->base.source_position);
+ source_position_t const *const ppos = &entity->base.source_position;
+ errorf(&pos, "multiple definitions of '%N' (previous definition %P)", entity, ppos);
/* clear members in the hope to avoid further errors */
entity->compound.members.entities = NULL;
}
* existing definition in outer scope */
entity = NULL;
} else if (entity->enume.complete && token.type == '{') {
- errorf(&pos, "multiple definitions of 'enum %Y' (previous definition %P)",
- symbol, &entity->base.source_position);
+ source_position_t const *const ppos = &entity->base.source_position;
+ errorf(&pos, "multiple definitions of '%N' (previous definition %P)", entity, ppos);
}
}
break;
break;
#define CHECK_DOUBLE_TYPE() \
+ do { \
if ( type != NULL) \
- errorf(HERE, "multiple data types in declaration specifiers");
+ errorf(HERE, "multiple data types in declaration specifiers"); \
+ } while(0)
case T_struct:
CHECK_DOUBLE_TYPE();
* incomplete type. */
type_t *type = skip_typeref(entity->declaration.type);
if (is_type_incomplete(type)) {
- errorf(&entity->base.source_position,
- "parameter '%#T' has incomplete type",
- entity->declaration.type, entity->base.symbol);
+ errorf(&entity->base.source_position, "'%N' has incomplete type", entity);
}
}
static type_t *semantic_parameter(const source_position_t *pos,
type_t *type,
const declaration_specifiers_t *specifiers,
- symbol_t *symbol)
+ entity_t const *const param)
{
/* §6.7.5.3:7 A declaration of a parameter as ``array of type''
* shall be adjusted to ``qualified pointer to type'',
type = automatic_type_conversion(type);
if (specifiers->is_inline && is_type_valid(type)) {
- errorf(pos, "parameter '%#T' declared 'inline'", type, symbol);
+ errorf(pos, "'%N' declared 'inline'", param);
}
/* §6.9.1:6 The declarations in the declaration list shall contain
specifiers->storage_class != STORAGE_CLASS_NONE &&
specifiers->storage_class != STORAGE_CLASS_REGISTER)
) {
- errorf(pos, "invalid storage class for parameter '%#T'", type, symbol);
+ errorf(pos, "invalid storage class for '%N'", param);
}
/* delay test for incomplete type, because we might have (void)
}
}
} else if (flags & DECL_IS_PARAMETER) {
- orig_type = semantic_parameter(&env.source_position, orig_type,
- specifiers, env.symbol);
-
- entity = allocate_entity_zero(ENTITY_PARAMETER, NAMESPACE_NORMAL, env.symbol);
+ entity = allocate_entity_zero(ENTITY_PARAMETER, NAMESPACE_NORMAL, env.symbol);
+ orig_type = semantic_parameter(&env.source_position, orig_type, specifiers, entity);
} else if (is_type_function(type)) {
entity = allocate_entity_zero(ENTITY_FUNCTION, NAMESPACE_NORMAL, env.symbol);
entity->function.is_inline = specifiers->is_inline;
specifiers->storage_class != STORAGE_CLASS_NONE &&
(in_function_scope || specifiers->storage_class != STORAGE_CLASS_STATIC)
)) {
- errorf(&env.source_position,
- "invalid storage class for function '%Y'", env.symbol);
+ errorf(&env.source_position, "invalid storage class for '%N'", entity);
}
}
} else {
if (env.symbol != NULL) {
if (specifiers->is_inline && is_type_valid(type)) {
- errorf(&env.source_position,
- "variable '%Y' declared 'inline'", env.symbol);
+ errorf(&env.source_position, "'%N' declared 'inline'", entity);
}
bool invalid_storage_class = false;
}
}
if (invalid_storage_class) {
- errorf(&env.source_position,
- "invalid storage class for variable '%Y'", env.symbol);
+ errorf(&env.source_position, "invalid storage class for variable '%N'", entity);
}
}
}
static void error_redefined_as_different_kind(const source_position_t *pos,
const entity_t *old, entity_kind_t new_kind)
{
- errorf(pos, "redeclaration of %s '%Y' as %s (declared %P)",
- get_entity_kind_name(old->kind), old->base.symbol,
- get_entity_kind_name(new_kind), &old->base.source_position);
+ char const *const what = get_entity_kind_name(new_kind);
+ source_position_t const *const ppos = &old->base.source_position;
+ errorf(pos, "redeclaration of '%N' as %s (declared %P)", old, what, ppos);
}
static bool is_entity_valid(entity_t *const ent)
assert(is_type_function(type));
if (type->function.unspecified_parameters &&
- warning.strict_prototypes &&
- previous_entity == NULL) {
- warningf(pos, "function declaration '%#T' is not a prototype",
- orig_type, symbol);
+ warning.strict_prototypes &&
+ previous_entity == NULL &&
+ !entity->declaration.implicit) {
+ warningf(pos, "function declaration '%#N' is not a prototype", entity);
}
if (warning.main && current_scope == file_scope
}
}
- if (is_declaration(entity) &&
- warning.nested_externs &&
- entity->declaration.storage_class == STORAGE_CLASS_EXTERN &&
- current_scope != file_scope) {
- warningf(pos, "nested extern declaration of '%#T'",
- entity->declaration.type, symbol);
+ if (is_declaration(entity) &&
+ warning.nested_externs &&
+ entity->declaration.storage_class == STORAGE_CLASS_EXTERN &&
+ current_scope != file_scope &&
+ !entity->declaration.implicit) {
+ warningf(pos, "nested extern declaration of '%#N'", entity);
}
if (previous_entity != NULL) {
+ source_position_t const *const ppos = &previous_entity->base.source_position;
+
if (previous_entity->base.parent_scope == ¤t_function->parameters &&
previous_entity->base.parent_scope->depth + 1 == current_scope->depth) {
assert(previous_entity->kind == ENTITY_PARAMETER);
- errorf(pos,
- "declaration '%#T' redeclares the parameter '%#T' (declared %P)",
- entity->declaration.type, symbol,
- previous_entity->declaration.type, symbol,
- &previous_entity->base.source_position);
+ errorf(pos, "declaration of '%N' redeclares the '%N' (declared %P)", entity, previous_entity, ppos);
goto finish;
}
goto finish;
}
if (previous_entity->kind == ENTITY_ENUM_VALUE) {
- errorf(pos, "redeclaration of enum entry '%Y' (declared %P)",
- symbol, &previous_entity->base.source_position);
+ errorf(pos, "redeclaration of '%N' (declared %P)", entity, ppos);
goto finish;
}
if (previous_entity->kind == ENTITY_TYPEDEF) {
/* TODO: C++ allows this for exactly the same type */
- errorf(pos, "redefinition of typedef '%Y' (declared %P)",
- symbol, &previous_entity->base.source_position);
+ errorf(pos, "redefinition of '%N' (declared %P)", entity, ppos);
goto finish;
}
return previous_entity;
}
- type_t *const orig_type = decl->type;
- assert(orig_type != NULL);
- type_t *const type = skip_typeref(orig_type);
+ type_t *const type = skip_typeref(decl->type);
type_t *const prev_type = skip_typeref(prev_decl->type);
if (!types_compatible(type, prev_type)) {
- errorf(pos,
- "declaration '%#T' is incompatible with '%#T' (declared %P)",
- orig_type, symbol, prev_decl->type, symbol,
- &previous_entity->base.source_position);
+ errorf(pos, "declaration '%#N' is incompatible with '%#N' (declared %P)", entity, previous_entity, ppos);
} else {
unsigned old_storage_class = prev_decl->storage_class;
!prev_decl->used &&
!(prev_decl->modifiers & DM_USED) &&
prev_decl->storage_class == STORAGE_CLASS_STATIC) {
- warningf(&previous_entity->base.source_position,
- "unnecessary static forward declaration for '%#T'",
- prev_decl->type, symbol);
+ warningf(ppos, "unnecessary static forward declaration for '%#N'", previous_entity);
}
storage_class_t new_storage_class = decl->storage_class;
if (warning.missing_prototypes &&
prev_type->function.unspecified_parameters &&
!is_sym_main(symbol)) {
- warningf(pos, "no previous prototype for '%#T'",
- orig_type, symbol);
+ warningf(pos, "no previous prototype for '%#N'", entity);
}
} else if (new_storage_class == STORAGE_CLASS_NONE) {
new_storage_class = STORAGE_CLASS_EXTERN;
} else if (!is_definition &&
warning.redundant_decls &&
is_type_valid(prev_type) &&
- strcmp(previous_entity->base.source_position.input_name,
- "<builtin>") != 0) {
- warningf(pos,
- "redundant declaration for '%Y' (declared %P)",
- symbol, &previous_entity->base.source_position);
+ strcmp(ppos->input_name, "<builtin>") != 0) {
+ warningf(pos, "redundant declaration for '%Y' (declared %P)", symbol, ppos);
}
} else if (current_function == NULL) {
if (old_storage_class != STORAGE_CLASS_STATIC &&
new_storage_class == STORAGE_CLASS_STATIC) {
- errorf(pos,
- "static declaration of '%Y' follows non-static declaration (declared %P)",
- symbol, &previous_entity->base.source_position);
+ errorf(pos, "static declaration of '%Y' follows non-static declaration (declared %P)", symbol, ppos);
} else if (old_storage_class == STORAGE_CLASS_EXTERN) {
prev_decl->storage_class = STORAGE_CLASS_NONE;
prev_decl->declared_storage_class = STORAGE_CLASS_NONE;
} else if (is_type_valid(prev_type)) {
if (old_storage_class == new_storage_class) {
error_redeclaration:
- errorf(pos, "redeclaration of '%Y' (declared %P)",
- symbol, &previous_entity->base.source_position);
+ errorf(pos, "redeclaration of '%Y' (declared %P)", symbol, ppos);
} else {
- errorf(pos,
- "redeclaration of '%Y' with different linkage (declared %P)",
- symbol, &previous_entity->base.source_position);
+ errorf(pos, "redeclaration of '%Y' with different linkage (declared %P)", symbol, ppos);
}
}
}
if (warning.shadow ||
(warning.shadow_local && previous_entity->base.parent_scope != file_scope)) {
- warningf(pos, "%s '%Y' shadows %s (declared %P)",
- get_entity_kind_name(entity->kind), symbol,
- get_entity_kind_name(previous_entity->kind),
- &previous_entity->base.source_position);
+ char const *const what = get_entity_kind_name(previous_entity->kind);
+ warningf(pos, "'%N' shadows %s (declared %P)", entity, what, ppos);
}
}
if (is_definition &&
entity->declaration.storage_class != STORAGE_CLASS_STATIC) {
if (warning.missing_prototypes && !is_sym_main(symbol)) {
- warningf(pos, "no previous prototype for '%#T'",
- entity->declaration.type, symbol);
+ warningf(pos, "no previous prototype for '%#N'", entity);
} else if (warning.missing_declarations && !is_sym_main(symbol)) {
- warningf(pos, "no previous declaration for '%#T'",
- entity->declaration.type, symbol);
+ warningf(pos, "no previous declaration for '%#N'", entity);
}
}
- } else if (warning.missing_declarations &&
- entity->kind == ENTITY_VARIABLE &&
- current_scope == file_scope) {
- declaration_t *declaration = &entity->declaration;
- if (declaration->storage_class == STORAGE_CLASS_NONE) {
- warningf(pos, "no previous declaration for '%#T'",
- declaration->type, symbol);
+ } else if (entity->kind == ENTITY_VARIABLE) {
+ if (warning.missing_declarations &&
+ current_scope == file_scope &&
+ entity->declaration.storage_class == STORAGE_CLASS_NONE) {
+ warningf(pos, "no previous declaration for '%#N'", entity);
}
}
type_t *orig_type = type_error_type;
if (entity->base.kind == ENTITY_TYPEDEF) {
- errorf(&entity->base.source_position,
- "typedef '%Y' is initialized (use __typeof__ instead)",
- entity->base.symbol);
+ source_position_t const *const pos = &entity->base.source_position;
+ errorf(pos, "'%N' is initialized (use __typeof__ instead)", entity);
} else {
assert(is_declaration(entity));
orig_type = entity->declaration.type;
}
if (is_type_function(type)) {
- errorf(&entity->base.source_position,
- "function '%#T' is initialized like a variable",
- orig_type, entity->base.symbol);
+ source_position_t const *const pos = &entity->base.source_position;
+ errorf(pos, "'%N' is initialized like a variable", entity);
orig_type = type_error_type;
}
decl->storage_class == STORAGE_CLASS_STATIC)
return;
- type_t *const orig_type = decl->type;
- type_t *const type = skip_typeref(orig_type);
+ type_t *const type = skip_typeref(decl->type);
if (!is_type_incomplete(type))
return;
return;
}
- errorf(&ent->base.source_position, "variable '%#T' has incomplete type",
- orig_type, ent->base.symbol);
+ errorf(&ent->base.source_position, "variable '%#N' has incomplete type", ent);
}
if (decl->storage_class != STORAGE_CLASS_EXTERN) {
type_t *type = decl->type;
if (is_type_reference(skip_typeref(type))) {
- errorf(&entity->base.source_position,
- "reference '%#T' must be initialized",
- type, entity->base.symbol);
+ source_position_t const *const pos = &entity->base.source_position;
+ errorf(pos, "reference '%#N' must be initialized", entity);
}
}
}
}
if (is_definition) {
- errorf(HERE, "parameter '%Y' is initialised", entity->base.symbol);
+ errorf(HERE, "'%N' is initialised", entity);
}
return record_entity(entity, false);
if (parameter_type == NULL) {
source_position_t const* const pos = ¶meter->base.source_position;
if (strict_mode) {
- errorf(pos, "no type specified for function parameter '%Y'", parameter->base.symbol);
+ errorf(pos, "no type specified for function '%N'", parameter);
parameter_type = type_error_type;
} else {
if (warning.implicit_int) {
- warningf(pos, "no type specified for function parameter '%Y', using 'int'", parameter->base.symbol);
+ warningf(pos, "no type specified for function '%N', using 'int'", parameter);
}
parameter_type = type_int;
}
parameter_type = not_promoted;
}
}
- function_parameter_t *const parameter
+ function_parameter_t *const function_parameter
= allocate_parameter(parameter_type);
- *anchor = parameter;
- anchor = ¶meter->next;
+ *anchor = function_parameter;
+ anchor = &function_parameter->next;
}
new_type->function.parameters = parameters;
new_type = identify_new_type(new_type);
if (warning.other && need_incompatible_warning) {
- type_t *proto_type_type = proto_type->declaration.type;
- warningf(&entity->base.source_position,
- "declaration '%#T' is incompatible with '%#T' (declared %P)",
- proto_type_type, proto_type->base.symbol,
- new_type, entity->base.symbol,
- &proto_type->base.source_position);
+ source_position_t const *const pos = &entity->base.source_position;
+ source_position_t const *const ppos = &proto_type->base.source_position;
+ symbol_t const *const sym = entity->base.symbol;
+ warningf(pos, "declaration '%#N' is incompatible with '%#T' (declared %P)", proto_type, new_type, sym, ppos);
}
-
entity->declaration.type = new_type;
rem_anchor_token('{');
{
if (first_err) {
first_err = false;
- diagnosticf("%s: In function '%Y':\n",
- current_function->base.base.source_position.input_name,
- current_function->base.base.symbol);
+ char const *const file = current_function->base.base.source_position.input_name;
+ diagnosticf("%s: In '%N':\n", file, (entity_t const*)current_function);
}
}
label_t *label = goto_statement->label;
if (label->base.source_position.input_name == NULL) {
print_in_function();
- errorf(&goto_statement->base.source_position,
- "label '%Y' used but not defined", label->base.symbol);
+ source_position_t const *const pos = &goto_statement->base.source_position;
+ errorf(pos, "'%N' used but not defined", (entity_t const*)label);
}
}
if (! label->used) {
print_in_function();
- warningf(&label_statement->base.source_position,
- "label '%Y' defined but not used", label->base.symbol);
+ source_position_t const *const pos = &label_statement->base.source_position;
+ warningf(pos, "'%N' defined but not used", (entity_t const*)label);
}
}
}
if (!declaration->used) {
print_in_function();
- const char *what = get_entity_kind_name(entity->kind);
- warningf(&entity->base.source_position, "%s '%Y' is unused",
- what, entity->base.symbol);
+ warningf(&entity->base.source_position, "'%N' is unused", entity);
} else if (entity->kind == ENTITY_VARIABLE && !entity->variable.read) {
print_in_function();
- const char *what = get_entity_kind_name(entity->kind);
- warningf(&entity->base.source_position, "%s '%Y' is never read",
- what, entity->base.symbol);
+ warningf(&entity->base.source_position, "'%N' is never read", entity);
}
}
}
case STATEMENT_DECLARATION: {
declaration_statement_t const *const decl = &stmt->declaration;
entity_t const * ent = decl->declarations_begin;
- entity_t const *const last = decl->declarations_end;
+ entity_t const *const last_decl = decl->declarations_end;
if (ent != NULL) {
for (;; ent = ent->base.next) {
if (ent->kind == ENTITY_VARIABLE &&
- ent->variable.initializer != NULL &&
- !initializer_returns(ent->variable.initializer)) {
+ ent->variable.initializer != NULL &&
+ !initializer_returns(ent->variable.initializer)) {
return;
}
- if (ent == last)
+ if (ent == last_decl)
break;
}
}
if (!is_type_function(type)) {
if (is_type_valid(type)) {
- errorf(HERE, "declarator '%#T' has a body but is not a function type",
- type, ndeclaration->base.symbol);
+ errorf(HERE, "declarator '%#N' has a body but is not a function type", ndeclaration);
}
eat_block();
return;
- } else if (is_typeref(orig_type)) {
+ }
+
+ source_position_t const *const pos = &ndeclaration->base.source_position;
+ if (is_typeref(orig_type)) {
/* §6.9.1:2 */
- errorf(&ndeclaration->base.source_position,
- "type of function definition '%#T' is a typedef",
- orig_type, ndeclaration->base.symbol);
+ errorf(pos, "type of function definition '%#N' is a typedef", ndeclaration);
}
if (warning.aggregate_return &&
is_type_compound(skip_typeref(type->function.return_type))) {
- warningf(&ndeclaration->base.source_position, "function '%Y' returns an aggregate",
- ndeclaration->base.symbol);
+ warningf(pos, "'%N' returns an aggregate", ndeclaration);
}
if (warning.traditional && !type->function.unspecified_parameters) {
- warningf(&ndeclaration->base.source_position, "traditional C rejects ISO C style function definition of function '%Y'",
- ndeclaration->base.symbol);
+ warningf(pos, "traditional C rejects ISO C style definition of '%N'", ndeclaration);
}
if (warning.old_style_definition && type->function.unspecified_parameters) {
- warningf(&ndeclaration->base.source_position, "old-style function definition '%Y'",
- ndeclaration->base.symbol);
+ warningf(pos, "old-style definition of '%N'", ndeclaration);
}
/* §6.7.5.3:14 a function definition with () means no
if (warning.missing_noreturn &&
noreturn_candidate &&
!(function->base.modifiers & DM_NORETURN)) {
- warningf(&body->base.source_position,
- "function '%#T' is candidate for attribute 'noreturn'",
- type, entity->base.symbol);
+ source_position_t const *const pos = &body->base.source_position;
+ warningf(pos, "function '%#N' is candidate for attribute 'noreturn'", entity);
}
}
if ((entity->declaration.modifiers & DM_DEPRECATED) == 0)
return;
- char const *const prefix = get_entity_kind_name(entity->kind);
- const char *deprecated_string
- = get_deprecated_string(entity->declaration.attributes);
- if (deprecated_string != NULL) {
- warningf(source_position, "%s '%Y' is deprecated (declared %P): \"%s\"",
- prefix, entity->base.symbol, &entity->base.source_position,
- deprecated_string);
+ source_position_t const *const pos = &entity->base.source_position;
+ char const* const msg = get_deprecated_string(entity->declaration.attributes);
+ if (msg != NULL) {
+ warningf(source_position, "'%N' is deprecated (declared %P): \"%s\"", entity, pos, msg);
} else {
- warningf(source_position, "%s '%Y' is deprecated (declared %P)", prefix,
- entity->base.symbol, &entity->base.source_position);
+ warningf(source_position, "'%N' is deprecated (declared %P)", entity, pos);
}
}
} else {
entity = parse_declarator(specifiers,
DECL_MAY_BE_ABSTRACT | DECL_CREATE_COMPOUND_MEMBER);
+ source_position_t const *const pos = &entity->base.source_position;
if (entity->kind == ENTITY_TYPEDEF) {
- errorf(&entity->base.source_position,
- "typedef not allowed as compound member");
+ errorf(pos, "typedef not allowed as compound member");
} else {
assert(entity->kind == ENTITY_COMPOUND_MEMBER);
if (symbol != NULL) {
entity_t *prev = find_compound_entry(compound, symbol);
if (prev != NULL) {
- errorf(&entity->base.source_position,
- "multiple declarations of symbol '%Y' (declared %P)",
- symbol, &prev->base.source_position);
+ source_position_t const *const ppos = &prev->base.source_position;
+ errorf(pos, "multiple declarations of symbol '%Y' (declared %P)", symbol, ppos);
}
}
type_t *orig_type = entity->declaration.type;
type_t *type = skip_typeref(orig_type);
if (is_type_function(type)) {
- errorf(&entity->base.source_position,
- "compound member '%Y' must not have function type '%T'",
- entity->base.symbol, orig_type);
+ errorf(pos, "'%N' must not have function type '%T'", entity, orig_type);
} else if (is_type_incomplete(type)) {
/* §6.7.2.1:16 flexible array member */
if (!is_type_array(type) ||
token.type != ';' ||
look_ahead(1)->type != '}') {
- errorf(&entity->base.source_position,
- "compound member '%Y' has incomplete type '%T'",
- entity->base.symbol, orig_type);
+ errorf(pos, "'%N' has incomplete type '%T'", entity, orig_type);
}
}
}
parse_expression_infix_function infix_parser;
};
-expression_parser_function_t expression_parsers[T_LAST_TOKEN];
+static expression_parser_function_t expression_parsers[T_LAST_TOKEN];
/**
* Prints an error message if an expression was expected but not read
entity->declaration.implicit = true;
entity->base.source_position = *source_position;
- if (current_scope != NULL) {
- bool strict_prototypes_old = warning.strict_prototypes;
- warning.strict_prototypes = false;
+ if (current_scope != NULL)
record_entity(entity, false);
- warning.strict_prototypes = strict_prototypes_old;
- }
return entity;
}
construct a hashmap here... */
entity_t *entity = scope->entities;
for ( ; entity != NULL; entity = entity->base.next) {
- if (entity->base.symbol == symbol && entity->base.namespc == namespc)
+ if (entity->base.symbol == symbol
+ && (namespace_tag_t)entity->base.namespc == namespc)
break;
}
default:
errorf(&pos, "'%Y' must be a namespace, class, struct or union (but is a %s)",
symbol, get_entity_kind_name(entity->kind));
- goto end_error;
+
+ /* skip further qualifications */
+ while (next_if(T_IDENTIFIER) && next_if(T_COLONCOLON)) {}
+
+ return create_error_entity(sym_anonymous, ENTITY_VARIABLE);
}
}
}
return entity;
-
-end_error:
- /* skip further qualifications */
- while (next_if(T_IDENTIFIER) && next_if(T_COLONCOLON)) {}
-
- return create_error_entity(sym_anonymous, ENTITY_VARIABLE);
}
static expression_t *parse_reference(void)
if (warning.init_self && entity == current_init_decl && !in_type_prop
&& entity->kind == ENTITY_VARIABLE) {
current_init_decl = NULL;
- warningf(&pos, "variable '%#T' is initialized by itself",
- entity->declaration.type, entity->base.symbol);
+ warningf(&pos, "variable '%#N' is initialized by itself", entity);
}
return expression;
/* do default promotion for other arguments */
for (; argument != NULL; argument = argument->next) {
- type_t *type = argument->expression->base.type;
- if (!is_type_object(skip_typeref(type))) {
+ type_t *argument_type = argument->expression->base.type;
+ if (!is_type_object(skip_typeref(argument_type))) {
errorf(&argument->expression->base.source_position,
"call argument '%E' must not be void", argument->expression);
}
- type = get_default_promoted_type(type);
+ argument_type = get_default_promoted_type(argument_type);
argument->expression
- = create_implicit_cast(argument->expression, type);
+ = create_implicit_cast(argument->expression, argument_type);
}
check_format(call);
expr = get_reference_address(expr);
if (expr != NULL) {
- warningf(&expr->base.source_position,
- "the address of '%Y' will always evaluate as 'true'",
- expr->reference.entity->base.symbol);
+ source_position_t const *const pos = &expr->base.source_position;
+ entity_t const *const ent = expr->reference.entity;
+ warningf(pos, "the address of '%N' will always evaluate as 'true'", ent);
}
}
}
result_type = pointer_type;
} else {
- if (is_type_valid(other_type)) {
- type_error_incompatible("while parsing conditional",
- &expression->base.source_position, true_type, false_type);
- }
- result_type = type_error_type;
+ goto types_incompatible;
}
} else {
+types_incompatible:
if (is_type_valid(true_type) && is_type_valid(false_type)) {
type_error_incompatible("while parsing conditional",
&conditional->base.source_position, true_type,
if (entity->declaration.storage_class == STORAGE_CLASS_REGISTER
&& !may_be_register) {
- errorf(&expression->base.source_position,
- "address of register %s '%Y' requested",
- get_entity_kind_name(entity->kind), entity->base.symbol);
+ source_position_t const *const pos = &expression->base.source_position;
+ errorf(pos, "address of register '%N' requested", entity);
}
if (entity->kind == ENTITY_VARIABLE) {
}
}
-static void warn_comparison_in_comparison(const expression_t *const expr)
-{
- if (expr->base.parenthesized)
- return;
- switch (expr->base.kind) {
- case EXPR_BINARY_LESS:
- case EXPR_BINARY_GREATER:
- case EXPR_BINARY_LESSEQUAL:
- case EXPR_BINARY_GREATEREQUAL:
- case EXPR_BINARY_NOTEQUAL:
- case EXPR_BINARY_EQUAL:
- warningf(&expr->base.source_position,
- "comparisons like 'x <= y < z' do not have their mathematical meaning");
- break;
- default:
- break;
- }
-}
-
static bool maybe_negative(expression_t const *const expr)
{
switch (is_constant_expression(expr)) {
}
}
-/**
- * Check the semantics of comparison expressions.
- *
- * @param expression The expression to check.
- */
-static void semantic_comparison(binary_expression_t *expression)
+static void warn_comparison(source_position_t const *const pos, expression_t const *const expr, expression_t const *const other)
{
- expression_t *left = expression->left;
- expression_t *right = expression->right;
-
if (warning.address) {
- warn_string_literal_address(left);
- warn_string_literal_address(right);
+ warn_string_literal_address(expr);
- expression_t const* const func_left = get_reference_address(left);
- if (func_left != NULL && is_null_pointer_constant(right)) {
- warningf(&expression->base.source_position,
- "the address of '%Y' will never be NULL",
- func_left->reference.entity->base.symbol);
+ expression_t const* const ref = get_reference_address(expr);
+ if (ref != NULL && is_null_pointer_constant(other)) {
+ entity_t const *const ent = ref->reference.entity;
+ warningf(pos, "the address of '%N' will never be NULL", ent);
}
+ }
- expression_t const* const func_right = get_reference_address(right);
- if (func_right != NULL && is_null_pointer_constant(right)) {
- warningf(&expression->base.source_position,
- "the address of '%Y' will never be NULL",
- func_right->reference.entity->base.symbol);
+ if (warning.parentheses && !expr->base.parenthesized) {
+ switch (expr->base.kind) {
+ case EXPR_BINARY_LESS:
+ case EXPR_BINARY_GREATER:
+ case EXPR_BINARY_LESSEQUAL:
+ case EXPR_BINARY_GREATEREQUAL:
+ case EXPR_BINARY_NOTEQUAL:
+ case EXPR_BINARY_EQUAL:
+ warningf(pos, "comparisons like 'x <= y < z' do not have their mathematical meaning");
+ break;
+ default:
+ break;
}
}
+}
- if (warning.parentheses) {
- warn_comparison_in_comparison(left);
- warn_comparison_in_comparison(right);
- }
+/**
+ * Check the semantics of comparison expressions.
+ *
+ * @param expression The expression to check.
+ */
+static void semantic_comparison(binary_expression_t *expression)
+{
+ source_position_t const *const pos = &expression->base.source_position;
+ expression_t *const left = expression->left;
+ expression_t *const right = expression->right;
+
+ warn_comparison(pos, left, right);
+ warn_comparison(pos, right, left);
type_t *orig_type_left = left->base.type;
type_t *orig_type_right = right->base.type;
/* TODO check whether constant value can be represented by other type */
if ((signed_left && maybe_negative(left)) ||
(signed_right && maybe_negative(right))) {
- warningf(&expression->base.source_position,
- "comparison between signed and unsigned");
+ warningf(pos, "comparison between signed and unsigned");
}
}
}
(expression->base.kind == EXPR_BINARY_EQUAL ||
expression->base.kind == EXPR_BINARY_NOTEQUAL) &&
is_type_float(arithmetic_type)) {
- warningf(&expression->base.source_position,
- "comparing floating point with == or != is unsafe");
+ warningf(pos, "comparing floating point with == or != is unsafe");
}
} else if (is_type_pointer(type_left) && is_type_pointer(type_right)) {
/* TODO check compatibility */
} else if (is_type_pointer(type_right)) {
expression->left = create_implicit_cast(left, type_right);
} else if (is_type_valid(type_left) && is_type_valid(type_right)) {
- type_error_incompatible("invalid operands in comparison",
- &expression->base.source_position,
- type_left, type_right);
+ type_error_incompatible("invalid operands in comparison", pos, type_left, type_right);
}
expression->base.type = c_mode & _CXX ? type_bool : type_int;
}
*/
source_position_t const* const pos = &statement->base.source_position;
if (label->statement != NULL) {
- errorf(pos, "duplicate label '%Y' (declared %P)", label->base.symbol, &label->base.source_position);
+ errorf(pos, "duplicate '%N' (declared %P)", (entity_t const*)label, &label->base.source_position);
} else {
label->base.source_position = *pos;
label->statement = statement;
break;
}
}
- if (! found) {
- warningf(&statement->base.source_position,
- "enumeration value '%Y' not handled in switch",
- entry->base.symbol);
+ if (!found) {
+ warningf(&statement->base.source_position, "'%N' not handled in switch", entry);
}
last_value = value;
}
symbol_t *symbol = token.symbol;
entity_t *entity = get_entity(symbol, NAMESPACE_LABEL);
if (entity != NULL && entity->base.parent_scope == current_scope) {
- errorf(HERE, "multiple definitions of '__label__ %Y' (previous definition %P)",
- symbol, &entity->base.source_position);
+ source_position_t const *const ppos = &entity->base.source_position;
+ errorf(HERE, "multiple definitions of '%N' (previous definition %P)", entity, ppos);
} else {
entity = allocate_entity_zero(ENTITY_LOCAL_LABEL, NAMESPACE_LABEL, symbol);
entity->base.parent_scope = current_scope;
declaration->storage_class != STORAGE_CLASS_STATIC)
continue;
- type_t *const type = declaration->type;
const char *s;
if (entity->kind == ENTITY_FUNCTION) {
/* inhibit warning for static inline functions */
s = "defined";
}
- warningf(&declaration->base.source_position, "'%#T' %s but not used",
- type, declaration->base.symbol, s);
+ warningf(&declaration->base.source_position, "'%#N' %s but not used", entity);
}
}
while (token.type != T_EOF && token.type != '}') {
#ifndef NDEBUG
- bool anchor_leak = false;
for (int i = 0; i < T_LAST_TOKEN; ++i) {
unsigned char count = token_anchor_set[i] - token_anchor_copy[i];
if (count != 0) {
/* the anchor set and its copy differs */
internal_errorf(HERE, "Leaked anchor token %k %d times", i, count);
- anchor_leak = true;
}
}
if (in_gcc_extension) {
/* an gcc extension scope was not closed */
internal_errorf(HERE, "Leaked __extension__");
- anchor_leak = true;
}
-
- if (anchor_leak)
- abort();
#endif
parse_external();
{
size_t n = ARR_LEN(incomplete_arrays);
for (size_t i = 0; i != n; ++i) {
- declaration_t *const decl = incomplete_arrays[i];
- type_t *const orig_type = decl->type;
- type_t *const type = skip_typeref(orig_type);
+ declaration_t *const decl = incomplete_arrays[i];
+ type_t *const type = skip_typeref(decl->type);
if (!is_type_incomplete(type))
continue;
if (warning.other) {
- warningf(&decl->base.source_position,
- "array '%#T' assumed to have one element",
- orig_type, decl->base.symbol);
+ source_position_t const *const pos = &decl->base.source_position;
+ warningf(pos, "array '%#N' assumed to have one element", (entity_t const*)decl);
}
type_t *const new_type = duplicate_type(type);