X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=parser.c;h=19e165e7eb5e1062106c5ecbfa7fe88e2798d8be;hb=8845feb009950d2c76a394660a5bd81a0be0f2a6;hp=57f83220db80be2fb7a5171620353dd9201291b3;hpb=cb6d7832f5f6bd1dbd827a8e03d51519b25f9560;p=cparser diff --git a/parser.c b/parser.c index 57f8322..19e165e 100644 --- a/parser.c +++ b/parser.c @@ -1,21 +1,6 @@ /* * This file is part of cparser. - * Copyright (C) 2007-2009 Matthias Braun - * - * This program 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 2 - * of the License, or (at your option) any later version. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. + * Copyright (C) 2012 Matthias Braun */ #include @@ -173,7 +158,8 @@ typedef enum declarator_flags_t { static entity_t *parse_declarator(const declaration_specifiers_t *specifiers, declarator_flags_t flags); -static void semantic_comparison(binary_expression_t *expression); +static void semantic_comparison(binary_expression_t *expression, + bool is_relational); #define STORAGE_CLASSES \ STORAGE_CLASSES_NO_EXTERN \ @@ -273,7 +259,9 @@ static void semantic_comparison(binary_expression_t *expression); case T_false: \ case T_sizeof: \ case T_throw: \ - case T_true: + case T_true: \ + case T___imag__: \ + case T___real__: /** * Returns the size of a statement node. @@ -843,13 +831,6 @@ static void label_pop_to(size_t new_top) stack_pop_to(&label_stack, new_top); } -static atomic_type_kind_t get_akind(const type_t *type) -{ - assert(type->kind == TYPE_ATOMIC || type->kind == TYPE_COMPLEX - || type->kind == TYPE_IMAGINARY || type->kind == TYPE_ENUM); - return type->atomic.akind; -} - /** * §6.3.1.1:2 Do integer promotion for a given type. * @@ -858,7 +839,8 @@ static atomic_type_kind_t get_akind(const type_t *type) */ static type_t *promote_integer(type_t *type) { - if (get_akind_rank(get_akind(type)) < get_akind_rank(ATOMIC_TYPE_INT)) + atomic_type_kind_t akind = get_arithmetic_akind(type); + if (get_akind_rank(akind) < get_akind_rank(ATOMIC_TYPE_INT)) type = type_int; return type; @@ -1447,6 +1429,8 @@ static void mark_vars_read(expression_t *const expr, entity_t *lhs_ent) case EXPR_UNARY_PREFIX_INCREMENT: case EXPR_UNARY_PREFIX_DECREMENT: case EXPR_UNARY_ASSUME: + case EXPR_UNARY_IMAG: + case EXPR_UNARY_REAL: unary: mark_vars_read(expr->unary.value, lhs_ent); return; @@ -1536,7 +1520,13 @@ static designator_t *parse_designation(void) designator->pos = *HERE; eat('['); add_anchor_token(']'); + add_anchor_token(T_DOTDOTDOT); designator->array_index = parse_constant_expression(); + if (accept(T_DOTDOTDOT)) { + designator->range_last = parse_constant_expression(); + errorf(&designator->pos, "range initializer not supported"); + } + rem_anchor_token(T_DOTDOTDOT); rem_anchor_token(']'); expect(']'); break; @@ -2861,11 +2851,19 @@ finish_specifiers: specifiers->attributes = parse_attributes(specifiers->attributes); if (type == NULL || (saw_error && type_specifiers != 0)) { + position_t const* const pos = &specifiers->pos; atomic_type_kind_t atomic_type; /* match valid basic types */ - switch (type_specifiers) { + switch (type_specifiers & ~(SPECIFIER_COMPLEX|SPECIFIER_IMAGINARY)) { case SPECIFIER_VOID: + if (type_specifiers & (SPECIFIER_COMPLEX|SPECIFIER_IMAGINARY)) { + if (type_specifiers & SPECIFIER_COMPLEX) + errorf(pos, "_Complex specifier is invalid for void"); + if (type_specifiers & SPECIFIER_IMAGINARY) + errorf(pos, "_Imaginary specifier is invalid for void"); + type_specifiers &= ~(SPECIFIER_COMPLEX|SPECIFIER_IMAGINARY); + } atomic_type = ATOMIC_TYPE_VOID; break; case SPECIFIER_WCHAR_T: @@ -2981,23 +2979,17 @@ warn_about_long_long: atomic_type = ATOMIC_TYPE_LONG_DOUBLE; break; case SPECIFIER_BOOL: + if (type_specifiers & (SPECIFIER_COMPLEX|SPECIFIER_IMAGINARY)) { + if (type_specifiers & SPECIFIER_COMPLEX) + errorf(pos, "_Complex specifier is invalid for _Bool"); + if (type_specifiers & SPECIFIER_IMAGINARY) + errorf(pos, "_Imaginary specifier is invalid for _Bool"); + type_specifiers &= ~(SPECIFIER_COMPLEX|SPECIFIER_IMAGINARY); + } atomic_type = ATOMIC_TYPE_BOOL; break; - case SPECIFIER_FLOAT | SPECIFIER_COMPLEX: - case SPECIFIER_FLOAT | SPECIFIER_IMAGINARY: - atomic_type = ATOMIC_TYPE_FLOAT; - break; - case SPECIFIER_DOUBLE | SPECIFIER_COMPLEX: - case SPECIFIER_DOUBLE | SPECIFIER_IMAGINARY: - atomic_type = ATOMIC_TYPE_DOUBLE; - break; - case SPECIFIER_LONG | SPECIFIER_DOUBLE | SPECIFIER_COMPLEX: - case SPECIFIER_LONG | SPECIFIER_DOUBLE | SPECIFIER_IMAGINARY: - atomic_type = ATOMIC_TYPE_LONG_DOUBLE; - break; default: { /* invalid specifier combination, give an error message */ - position_t const* const pos = &specifiers->pos; if (type_specifiers == 0) { if (!saw_error) { /* ISO/IEC 14882:1998(E) §C.1.5:4 */ @@ -3009,6 +3001,10 @@ warn_about_long_long: errorf(pos, "no type specifiers given in declaration"); } } + } else if (type_specifiers == SPECIFIER_COMPLEX) { + warningf(WARN_OTHER, pos, "_Complex requires a type specifier; assuming '_Complex double'"); + atomic_type = ATOMIC_TYPE_DOUBLE; + break; } else if ((type_specifiers & SPECIFIER_SIGNED) && (type_specifiers & SPECIFIER_UNSIGNED)) { errorf(pos, "signed and unsigned specifiers given"); @@ -4075,9 +4071,7 @@ warn_redundant_declaration: ; decl->attributes); if (has_new_attrs) { merge_in_attributes(decl, prev_decl->attributes); - } else if (!is_definition && - is_type_valid(prev_type) && - !pos->is_system_header) { + } else if (!is_definition && is_type_valid(prev_type)) { warningf(WARN_REDUNDANT_DECLS, pos, "redundant declaration for '%N' (declared %P)", entity, ppos); } } else if (current_function == NULL) { @@ -4130,10 +4124,11 @@ error_redeclaration: } } else if (entity->kind == ENTITY_VARIABLE) { if (current_scope == file_scope && - entity->declaration.storage_class == STORAGE_CLASS_NONE && - !entity->declaration.implicit) { + entity->declaration.storage_class == STORAGE_CLASS_NONE && + !entity->declaration.implicit) { warn_missing_declaration: - warningf(WARN_MISSING_DECLARATIONS, pos, "no previous declaration for '%#N'", entity); + if (is_type_valid(skip_typeref(entity->declaration.type))) + warningf(WARN_MISSING_DECLARATIONS, pos, "no previous declaration for '%#N'", entity); } } @@ -5391,6 +5386,7 @@ static expression_t *create_select(const position_t *pos, expression_t *addr, check_deprecated(pos, entry); expression_t *select = allocate_expression_zero(EXPR_SELECT); + select->base.pos = *pos; select->select.compound = addr; select->select.compound_entry = entry; @@ -5441,7 +5437,6 @@ static expression_t *find_create_select(const position_t *pos, continue; expression_t *sub_addr = create_select(pos, addr, qualifiers, iter); - sub_addr->base.pos = *pos; sub_addr->base.implicit = true; return find_create_select(pos, sub_addr, qualifiers, sub_compound, symbol); @@ -5686,18 +5681,32 @@ static void check_integer_suffix(expression_t *const expr, char const *const suf { unsigned spec = SPECIFIER_NONE; char const *c = suffix; - for (;;) { + while (*c != '\0') { specifiers_t add; - if (*c == 'L' || *c == 'l') { + switch (*c) { + case 'L': + case 'l': add = SPECIFIER_LONG; if (*c == c[1]) { add |= SPECIFIER_LONG_LONG; ++c; } - } else if (*c == 'U' || *c == 'u') { + break; + case 'u': + case 'U': add = SPECIFIER_UNSIGNED; - } else { break; + case 'i': + case 'I': + case 'j': + case 'J': + if (!GNU_MODE) + goto error; + add = SPECIFIER_COMPLEX; + break; + + default: + goto error; } ++c; if (spec & add) @@ -5707,7 +5716,7 @@ static void check_integer_suffix(expression_t *const expr, char const *const suf if (*c == '\0') { type_t *type; - switch (spec) { + switch (spec & ~SPECIFIER_COMPLEX) { case SPECIFIER_NONE: type = type_int; break; case SPECIFIER_LONG: type = type_long; break; case SPECIFIER_LONG | SPECIFIER_LONG_LONG: type = type_long_long; break; @@ -5719,6 +5728,10 @@ static void check_integer_suffix(expression_t *const expr, char const *const suf if (spec != SPECIFIER_NONE && spec != SPECIFIER_LONG) { warn_traditional_suffix(suffix); } + if (spec & SPECIFIER_COMPLEX) { + assert(type->kind == TYPE_ATOMIC); + type = make_complex_type(type->atomic.akind, TYPE_QUALIFIER_NONE); + } expr->base.type = type; /* Integer type depends on the size of the number and the size * representable by the types. The backend/codegeneration has to @@ -5733,16 +5746,32 @@ error: static void check_floatingpoint_suffix(expression_t *const expr, char const *const suffix) { type_t *type; - char const *c = suffix; + char const *c = suffix; + bool is_complex = false; +next: switch (*c) { case 'F': case 'f': type = type_float; ++c; break; case 'L': case 'l': type = type_long_double; ++c; break; + case 'i': + case 'I': + case 'j': + case 'J': + if (!GNU_MODE) + break; + is_complex = true; + ++c; + goto next; default: type = type_double; break; } if (*c == '\0') { + if (is_complex) { + assert(type->kind == TYPE_ATOMIC); + type = make_complex_type(type->atomic.akind, TYPE_QUALIFIER_NONE); + } + expr->base.type = type; if (suffix[0] != '\0') { warn_traditional_suffix(suffix); @@ -6147,7 +6176,8 @@ static bool semantic_cast(expression_t *cast) type_t const *src_type = skip_typeref(orig_type_right); position_t const *pos = &cast->base.pos; - /* §6.5.4 A (void) cast is explicitly permitted, more for documentation than for utility. */ + /* §6.5.4 A (void) cast is explicitly permitted, more for documentation + * than for utility. */ if (is_type_void(dst_type)) return true; @@ -6182,6 +6212,34 @@ static bool semantic_cast(expression_t *cast) return true; } +static void semantic_complex_extract(unary_expression_t *extract) +{ + type_t *orig_value_type = extract->value->base.type; + type_t *value_type = skip_typeref(orig_value_type); + if (!is_type_valid(value_type)) { + extract->base.type = type_error_type; + return; + } + + type_t *type = value_type; + if (!is_type_complex(type)) { + if (!is_type_arithmetic(type)) { + errorf(&extract->base.pos, + "%s requires an argument with complex or arithmetic type, got '%T'", + extract->base.kind == EXPR_UNARY_IMAG ? "__imag__" : "__real__", + orig_value_type); + extract->base.type = type_error_type; + return; + } + atomic_type_kind_t const akind = get_arithmetic_akind(type); + type = make_complex_type(akind, TYPE_QUALIFIER_NONE); + extract->value = create_implicit_cast(extract->value, type); + } + assert(type->kind == TYPE_COMPLEX); + type = make_atomic_type(type->atomic.akind, TYPE_QUALIFIER_NONE); + extract->base.type = type; +} + static expression_t *parse_compound_literal(position_t const *const pos, type_t *type) { @@ -6237,6 +6295,16 @@ static expression_t *parse_cast(void) return cast; } +static expression_t *parse_complex_extract_expression(expression_kind_t const kind) +{ + expression_t *extract = allocate_expression_zero(kind); + next_token(); + + extract->unary.value = parse_subexpression(PREC_CAST); + semantic_complex_extract(&extract->unary); + return extract; +} + /** * Parse a statement expression. */ @@ -6341,9 +6409,6 @@ static designator_t *parse_designator(void) designator->array_index = parse_expression(); rem_anchor_token(']'); expect(']'); - if (designator->array_index == NULL) { - return NULL; - } last_designator->next = designator; last_designator = designator; @@ -6510,7 +6575,7 @@ static expression_t *parse_builtin_constant(void) add_anchor_token(')'); expect('('); - expression->builtin_constant.value = parse_assignment_expression(); + expression->builtin_constant.value = parse_expression(); rem_anchor_token(')'); expect(')'); expression->base.type = type_int; @@ -6580,7 +6645,7 @@ static expression_t *parse_compare_builtin(void) &expression->base.pos, orig_type_left, orig_type_right); } } else { - semantic_comparison(&expression->binary); + semantic_comparison(&expression->binary, true); } return expression; @@ -6597,7 +6662,7 @@ static expression_t *parse_assume(void) add_anchor_token(')'); expect('('); - expression->unary.value = parse_assignment_expression(); + expression->unary.value = parse_expression(); rem_anchor_token(')'); expect(')'); @@ -6723,6 +6788,8 @@ static expression_t *parse_primary_expression(void) case '(': return parse_parenthesized_expression(); case T___noop: return parse_noop_expression(); + case T___imag__: return parse_complex_extract_expression(EXPR_UNARY_IMAG); + case T___real__: return parse_complex_extract_expression(EXPR_UNARY_REAL); /* Gracefully handle type names while parsing expressions. */ case T_COLONCOLON: @@ -7511,17 +7578,18 @@ static bool is_lvalue(const expression_t *expression) static void semantic_incdec(unary_expression_t *expression) { - type_t *const orig_type = expression->value->base.type; - type_t *const type = skip_typeref(orig_type); + type_t *orig_type = expression->value->base.type; + type_t *type = skip_typeref(orig_type); if (is_type_pointer(type)) { if (!check_pointer_arithmetic(&expression->base.pos, type, orig_type)) { return; } - } else if (!is_type_real(type) && is_type_valid(type)) { + } else if (!is_type_real(type) && + (!GNU_MODE || !is_type_complex(type)) && is_type_valid(type)) { /* TODO: improve error message */ errorf(&expression->base.pos, "operation needs an arithmetic or pointer type"); - return; + orig_type = type = type_error_type; } if (!is_lvalue(expression->value)) { /* TODO: improve error message */ @@ -7532,7 +7600,16 @@ static void semantic_incdec(unary_expression_t *expression) static void promote_unary_int_expr(unary_expression_t *const expr, type_t *const type) { - type_t *const res_type = promote_integer(type); + atomic_type_kind_t akind = get_arithmetic_akind(type); + type_t *res_type; + if (get_akind_rank(akind) < get_akind_rank(ATOMIC_TYPE_INT)) { + if (type->kind == TYPE_COMPLEX) + res_type = make_complex_type(ATOMIC_TYPE_INT, TYPE_QUALIFIER_NONE); + else + res_type = type_int; + } else { + res_type = type; + } expr->base.type = res_type; expr->value = create_implicit_cast(expr->value, res_type); } @@ -7572,14 +7649,18 @@ static void semantic_complement(unary_expression_t *expression) { type_t *const orig_type = expression->value->base.type; type_t *const type = skip_typeref(orig_type); - if (!is_type_integer(type)) { + if (!is_type_integer(type) && (!GNU_MODE || !is_type_complex(type))) { if (is_type_valid(type)) { errorf(&expression->base.pos, "operand of ~ must be of integer type"); } return; } - promote_unary_int_expr(expression, type); + if (is_type_integer(type)) { + promote_unary_int_expr(expression, type); + } else { + expression->base.type = orig_type; + } } static void semantic_dereference(unary_expression_t *expression) @@ -7701,67 +7782,78 @@ CREATE_UNARY_POSTFIX_EXPRESSION_PARSER(T_MINUSMINUS, EXPR_UNARY_POSTFIX_DECREMENT, semantic_incdec) -static type_t *semantic_arithmetic(type_t *type_left, type_t *type_right) +static atomic_type_kind_t semantic_arithmetic_(atomic_type_kind_t kind_left, + atomic_type_kind_t kind_right) { - /* TODO: handle complex + imaginary types */ - - type_left = get_unqualified_type(type_left); - type_right = get_unqualified_type(type_right); - /* §6.3.1.8 Usual arithmetic conversions */ - if (type_left == type_long_double || type_right == type_long_double) { - return type_long_double; - } else if (type_left == type_double || type_right == type_double) { - return type_double; - } else if (type_left == type_float || type_right == type_float) { - return type_float; - } - - type_left = promote_integer(type_left); - type_right = promote_integer(type_right); - - if (type_left == type_right) - return type_left; - - bool const signed_left = is_type_signed(type_left); - bool const signed_right = is_type_signed(type_right); - unsigned const rank_left = get_akind_rank(get_akind(type_left)); - unsigned const rank_right = get_akind_rank(get_akind(type_right)); - + if (kind_left == ATOMIC_TYPE_LONG_DOUBLE + || kind_right == ATOMIC_TYPE_LONG_DOUBLE) { + return ATOMIC_TYPE_LONG_DOUBLE; + } else if (kind_left == ATOMIC_TYPE_DOUBLE + || kind_right == ATOMIC_TYPE_DOUBLE) { + return ATOMIC_TYPE_DOUBLE; + } else if (kind_left == ATOMIC_TYPE_FLOAT + || kind_right == ATOMIC_TYPE_FLOAT) { + return ATOMIC_TYPE_FLOAT; + } + + unsigned rank_left = get_akind_rank(kind_left); + unsigned rank_right = get_akind_rank(kind_right); + unsigned const rank_int = get_akind_rank(ATOMIC_TYPE_INT); + if (rank_left < rank_int) { + kind_left = ATOMIC_TYPE_INT; + rank_left = rank_int; + } + if (rank_right < rank_int) { + kind_right = ATOMIC_TYPE_INT; + rank_right = rank_int; + } + if (kind_left == kind_right) + return kind_left; + + bool const signed_left = is_akind_signed(kind_left); + bool const signed_right = is_akind_signed(kind_right); if (signed_left == signed_right) - return rank_left >= rank_right ? type_left : type_right; + return rank_left >= rank_right ? kind_left : kind_right; unsigned s_rank; unsigned u_rank; - atomic_type_kind_t s_akind; - atomic_type_kind_t u_akind; - type_t *s_type; - type_t *u_type; + atomic_type_kind_t s_kind; + atomic_type_kind_t u_kind; if (signed_left) { - s_type = type_left; - u_type = type_right; + s_kind = kind_left; + s_rank = rank_left; + u_kind = kind_right; + u_rank = rank_right; } else { - s_type = type_right; - u_type = type_left; + s_kind = kind_right; + s_rank = rank_right; + u_kind = kind_left; + u_rank = rank_left; } - s_akind = get_akind(s_type); - u_akind = get_akind(u_type); - s_rank = get_akind_rank(s_akind); - u_rank = get_akind_rank(u_akind); - if (u_rank >= s_rank) - return u_type; - - if (get_atomic_type_size(s_akind) > get_atomic_type_size(u_akind)) - return s_type; + return u_kind; + if (get_atomic_type_size(s_kind) > get_atomic_type_size(u_kind)) + return s_kind; + + switch (s_kind) { + case ATOMIC_TYPE_INT: return ATOMIC_TYPE_UINT; + case ATOMIC_TYPE_LONG: return ATOMIC_TYPE_ULONG; + case ATOMIC_TYPE_LONGLONG: return ATOMIC_TYPE_ULONGLONG; + default: panic("invalid atomic type"); + } +} - switch (s_akind) { - case ATOMIC_TYPE_INT: return type_unsigned_int; - case ATOMIC_TYPE_LONG: return type_unsigned_long; - case ATOMIC_TYPE_LONGLONG: return type_unsigned_long_long; +static type_t *semantic_arithmetic(type_t *type_left, type_t *type_right) +{ + atomic_type_kind_t kind_left = get_arithmetic_akind(type_left); + atomic_type_kind_t kind_right = get_arithmetic_akind(type_right); + atomic_type_kind_t kind_res = semantic_arithmetic_(kind_left, kind_right); - default: panic("invalid atomic type"); + if (type_left->kind == TYPE_COMPLEX || type_right->kind == TYPE_COMPLEX) { + return make_complex_type(kind_res, TYPE_QUALIFIER_NONE); } + return make_atomic_type(kind_res, TYPE_QUALIFIER_NONE); } /** @@ -7799,7 +7891,8 @@ static void semantic_binexpr_integer(binary_expression_t *const expression) type_t *const type_left = skip_typeref(orig_type_left); type_t *const type_right = skip_typeref(orig_type_right); - if (!is_type_integer(type_left) || !is_type_integer(type_right)) { + if (!is_type_integer(type_left) || !is_type_integer(type_right) + || is_type_complex(type_left) || is_type_complex(type_right)) { if (is_type_valid(type_left) && is_type_valid(type_right)) { position_t const *const pos = &expression->base.pos; errorf(pos, "operands of binary expression must have integer types, but are '%T' and '%T'", orig_type_left, orig_type_right); @@ -8041,10 +8134,9 @@ static void warn_comparison(position_t const *const pos, expression_t const *con /** * Check the semantics of comparison expressions. - * - * @param expression The expression to check. */ -static void semantic_comparison(binary_expression_t *expression) +static void semantic_comparison(binary_expression_t *expression, + bool is_relational) { position_t const *const pos = &expression->base.pos; expression_t *const left = expression->left; @@ -8076,14 +8168,17 @@ static void semantic_comparison(binary_expression_t *expression) } } - expression->left = create_implicit_cast(left, arithmetic_type); - expression->right = create_implicit_cast(right, arithmetic_type); - expression->base.type = arithmetic_type; - if ((expression->base.kind == EXPR_BINARY_EQUAL || - expression->base.kind == EXPR_BINARY_NOTEQUAL) && - is_type_float(arithmetic_type)) { + expression->left = create_implicit_cast(left, arithmetic_type); + expression->right = create_implicit_cast(right, arithmetic_type); + expression->base.type = arithmetic_type; + if (!is_relational && is_type_float(arithmetic_type)) { warningf(WARN_FLOAT_EQUAL, pos, "comparing floating point with == or != is unsafe"); } + /* for relational ops we need real types, not just arithmetic */ + if (is_relational + && (!is_type_real(type_left) || !is_type_real(type_right))) { + type_error_incompatible("invalid operands for relational operator", pos, type_left, type_right); + } } else if (is_type_pointer(type_left) && is_type_pointer(type_right)) { /* TODO check compatibility */ } else if (is_type_pointer(type_left)) { @@ -8096,6 +8191,16 @@ static void semantic_comparison(binary_expression_t *expression) expression->base.type = c_mode & _CXX ? type_bool : type_int; } +static void semantic_relational(binary_expression_t *expression) +{ + semantic_comparison(expression, true); +} + +static void semantic_equality(binary_expression_t *expression) +{ + semantic_comparison(expression, false); +} + /** * Checks if a compound type has constant fields. */ @@ -8382,6 +8487,8 @@ static bool expression_has_effect(const expression_t *const expr) case EXPR_UNARY_NOT: return false; case EXPR_UNARY_DEREFERENCE: return false; case EXPR_UNARY_TAKE_ADDRESS: return false; + case EXPR_UNARY_REAL: return false; + case EXPR_UNARY_IMAG: return false; case EXPR_UNARY_POSTFIX_INCREMENT: return true; case EXPR_UNARY_POSTFIX_DECREMENT: return true; case EXPR_UNARY_PREFIX_INCREMENT: return true; @@ -8483,12 +8590,12 @@ CREATE_BINEXPR_PARSER('+', EXPR_BINARY_ADD, PR CREATE_BINEXPR_PARSER('-', EXPR_BINARY_SUB, PREC_MULTIPLICATIVE, semantic_sub) CREATE_BINEXPR_PARSER(T_LESSLESS, EXPR_BINARY_SHIFTLEFT, PREC_ADDITIVE, semantic_shift_op) CREATE_BINEXPR_PARSER(T_GREATERGREATER, EXPR_BINARY_SHIFTRIGHT, PREC_ADDITIVE, semantic_shift_op) -CREATE_BINEXPR_PARSER('<', EXPR_BINARY_LESS, PREC_SHIFT, semantic_comparison) -CREATE_BINEXPR_PARSER('>', EXPR_BINARY_GREATER, PREC_SHIFT, semantic_comparison) -CREATE_BINEXPR_PARSER(T_LESSEQUAL, EXPR_BINARY_LESSEQUAL, PREC_SHIFT, semantic_comparison) -CREATE_BINEXPR_PARSER(T_GREATEREQUAL, EXPR_BINARY_GREATEREQUAL, PREC_SHIFT, semantic_comparison) -CREATE_BINEXPR_PARSER(T_EXCLAMATIONMARKEQUAL, EXPR_BINARY_NOTEQUAL, PREC_RELATIONAL, semantic_comparison) -CREATE_BINEXPR_PARSER(T_EQUALEQUAL, EXPR_BINARY_EQUAL, PREC_RELATIONAL, semantic_comparison) +CREATE_BINEXPR_PARSER('<', EXPR_BINARY_LESS, PREC_SHIFT, semantic_relational) +CREATE_BINEXPR_PARSER('>', EXPR_BINARY_GREATER, PREC_SHIFT, semantic_relational) +CREATE_BINEXPR_PARSER(T_LESSEQUAL, EXPR_BINARY_LESSEQUAL, PREC_SHIFT, semantic_relational) +CREATE_BINEXPR_PARSER(T_GREATEREQUAL, EXPR_BINARY_GREATEREQUAL, PREC_SHIFT, semantic_relational) +CREATE_BINEXPR_PARSER(T_EXCLAMATIONMARKEQUAL, EXPR_BINARY_NOTEQUAL, PREC_RELATIONAL, semantic_equality) +CREATE_BINEXPR_PARSER(T_EQUALEQUAL, EXPR_BINARY_EQUAL, PREC_RELATIONAL, semantic_equality) CREATE_BINEXPR_PARSER('&', EXPR_BINARY_BITWISE_AND, PREC_EQUALITY, semantic_binexpr_integer) CREATE_BINEXPR_PARSER('^', EXPR_BINARY_BITWISE_XOR, PREC_AND, semantic_binexpr_integer) CREATE_BINEXPR_PARSER('|', EXPR_BINARY_BITWISE_OR, PREC_XOR, semantic_binexpr_integer) @@ -9172,7 +9279,7 @@ static statement_t *parse_switch(void) type_t * type = skip_typeref(expr->base.type); if (is_type_integer(type)) { type = promote_integer(type); - if (get_akind_rank(get_akind(type)) >= get_akind_rank(ATOMIC_TYPE_LONG)) { + if (get_akind_rank(get_arithmetic_akind(type)) >= get_akind_rank(ATOMIC_TYPE_LONG)) { warningf(WARN_TRADITIONAL, &expr->base.pos, "'%T' switch expression not converted to '%T' in ISO C", type, type_int);