Exemplo n.º 1
0
Arquivo: stmt.c Projeto: unixaaa/LuxCC
void analyze_labeled_statement(ExecNode *s, int in_switch)
{
    /*
     * 6.8.1
     * #2 A case or default label shall appear only in a switch statement.
     * #3 Label names shall be unique within a function.
     */

    switch (s->kind.stmt) {
    case LabelStmt:
        /*
         * 6.8.1
         * #3 Label names shall be unique within a function.
         */
        if (!install_label_name(s->attr.str))
            ERROR(s, "duplicate label `%s'", s->attr.str);
        break;
    /*
     * 6.8.4.2
     * #3 The expression of each case label shall be an integer constant expression and no two
     * of the case constant expressions in the same switch statement shall have the same value
     * after conversion. There may be at most one default label in a switch statement.
     * (Any enclosed switch statement may have a default label or case constant
     * expressions with values that duplicate case constant expressions in the enclosing
     * switch statement).
     */
    case CaseStmt: {
        long long val;
        Token ty, cty;

        ++switch_case_counter[switch_nesting_level];

        if (!in_switch)
            ERROR(s, "case label not within a switch statement");

        if ((ty=get_type_category(&s->child[0]->type)) == TOK_ERROR)
            return;
        if (!is_integer(ty))
            ERROR_R(s->child[0], "case label expression has non-integer type");

        val = eval_const_expr(s->child[0], FALSE, TRUE);
        cty = switch_contr_expr_types[switch_nesting_level];
        if (cty!=TOK_LONG_LONG && cty!=TOK_UNSIGNED_LONG_LONG)
            val = (int)val;
        s->child[0]->attr.val = val;

        if (!install_switch_label(val, FALSE))
            ERROR(s, "duplicate case value `%ld'", s->child[0]->attr.val);
    }
        break;
    case DefaultStmt:
        if (!in_switch)
            ERROR_R(s, "default label not within a switch statement");

        if (!install_switch_label(0, TRUE))
            ERROR(s, "multiple default labels in one switch");
        break;
    }
}
Exemplo n.º 2
0
Arquivo: cpp.c Projeto: rui314/8cc-old
/*
 * Reads an constant expression for #if directive.  In preprocessor constant
 * expression, all undefined identifiers are replaced with 0.
 *
 * (C99 6.10.1 Conditional inclusion, paragraph 4)
 */
static int read_constant_expr(CppContext *ctx) {
    List *tokens = make_list();
    for (;;) {
        Token *tok = expand_one(ctx);
        if (!tok || tok->toktype == TOKTYPE_NEWLINE)
            break;
        if (tok->toktype == TOKTYPE_IDENT && !strcmp("defined", STRING_BODY(tok->val.str)))
            tok = read_defined(ctx);
        list_push(tokens, tok);
    }
    return eval_const_expr(ctx, tokens);
}