}
static initializer_t *parse_sub_initializer(type_t *type,
- expression_t *expression,
- type_t *expression_type);
+ expression_t *expression);
static initializer_t *parse_sub_initializer_elem(type_t *type)
{
if(token.type == '{') {
- return parse_sub_initializer(type, NULL, NULL);
+ return parse_sub_initializer(type, NULL);
}
- expression_t *expression = parse_assignment_expression();
- type_t *expression_type = skip_typeref(expression->base.datatype);
-
- return parse_sub_initializer(type, expression, expression_type);
+ expression_t *expression = parse_assignment_expression();
+ return parse_sub_initializer(type, expression);
}
static bool had_initializer_brace_warning;
}
static initializer_t *parse_sub_initializer(type_t *type,
- expression_t *expression,
- type_t *expression_type)
+ expression_t *expression)
{
if(is_type_scalar(type)) {
/* there might be extra {} hierarchies */
warningf(HERE, "braces around scalar initializer");
had_initializer_brace_warning = true;
}
- initializer_t *result = parse_sub_initializer(type, NULL, NULL);
+ initializer_t *result = parse_sub_initializer(type, NULL);
if(token.type == ',') {
next_token();
/* TODO: warn about excessive elements */
if(expression == NULL) {
sub = parse_sub_initializer_elem(element_type);
} else {
- sub = parse_sub_initializer(element_type, expression,
- expression_type);
+ sub = parse_sub_initializer(element_type, expression);
}
/* didn't match the subtypes -> try the parent type */
if(expression == NULL) {
sub = parse_sub_initializer_elem(first_type);
} else {
- sub = parse_sub_initializer(first_type, expression,expression_type);
+ sub = parse_sub_initializer(first_type, expression);
}
/* didn't match the subtypes -> try our parent type */
expect('}');
return result;
} else {
- result = parse_sub_initializer(type, NULL, NULL);
+ result = parse_sub_initializer(type, NULL);
}
return result;
return declaration;
}
+static bool is_sym_main(const symbol_t *const sym)
+{
+ return strcmp(sym->string, "main") == 0;
+}
+
static declaration_t *internal_record_declaration(
declaration_t *const declaration,
const bool is_function_definition)
case STORAGE_CLASS_EXTERN:
if (is_function_definition) {
if (warning.missing_prototypes &&
- prev_type->function.unspecified_parameters) {
+ prev_type->function.unspecified_parameters &&
+ !is_sym_main(symbol)) {
warningf(declaration->source_position, "no previous prototype for '%#T'", type, symbol);
}
} else if (new_storage_class == STORAGE_CLASS_NONE) {
}
} else if (is_function_definition &&
declaration->storage_class != STORAGE_CLASS_STATIC) {
- if (warning.missing_prototypes) {
+ if (warning.missing_prototypes && !is_sym_main(symbol)) {
warningf(declaration->source_position, "no previous prototype for '%#T'", type, symbol);
- } else if (warning.missing_declarations) {
+ } else if (warning.missing_declarations && !is_sym_main(symbol)) {
warningf(declaration->source_position, "no previous declaration for '%#T'", type, symbol);
}
+ } else if (warning.missing_declarations &&
+ declaration->storage_class != STORAGE_CLASS_STATIC &&
+ declaration->storage_class != STORAGE_CLASS_TYPEDEF) {
+ warningf(declaration->source_position, "no previous declaration for '%#T'", type, symbol);
}
assert(declaration->parent_context == NULL);
{
type_t *const orig_type = expression->value->base.datatype;
type_t *const type = skip_typeref(orig_type);
+ /* TODO !is_type_real && !is_type_pointer */
if(!is_type_arithmetic(type) && type->kind != TYPE_POINTER) {
if (is_type_valid(type)) {
/* TODO: improve error message */
case EXPR_BINARY_BITWISE_AND: return false;
case EXPR_BINARY_BITWISE_OR: return false;
case EXPR_BINARY_BITWISE_XOR: return false;
- case EXPR_BINARY_LOGICAL_AND: return false;
- case EXPR_BINARY_LOGICAL_OR: return false;
case EXPR_BINARY_SHIFTLEFT: return false;
case EXPR_BINARY_SHIFTRIGHT: return false;
case EXPR_BINARY_ASSIGN: return true;
case EXPR_BINARY_BITWISE_AND_ASSIGN: return true;
case EXPR_BINARY_BITWISE_XOR_ASSIGN: return true;
case EXPR_BINARY_BITWISE_OR_ASSIGN: return true;
+ case EXPR_BINARY_LOGICAL_AND:
+ case EXPR_BINARY_LOGICAL_OR:
case EXPR_BINARY_COMMA:
return expression_has_effect(expr->binary.right);
statement->body = parse_statement();
current_switch = rem;
+ if (warning.switch_default && find_default_label(statement) == NULL) {
+ warningf(statement->statement.source_position, "switch has no default case");
+ }
+
return (statement_t*) statement;
}
break;
case ';':
+ if (warning.empty_statement) {
+ warningf(HERE, "statement is empty");
+ }
next_token();
statement = NULL;
break;