Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash when the result of a MethodCallStatement is unused and resolves to a compile-time constant #4625

Closed
kfcripps opened this issue Apr 17, 2024 · 1 comment · Fixed by #4627
Labels
bug This behavior is unintended and should be fixed. core Topics concerning the core segments of the compiler (frontend, midend, parser)

Comments

@kfcripps
Copy link
Contributor

The following P4 program:

header h_t {
    bit<8> f;
}

control C() {
    action bar() {
        h_t h;
        h.minSizeInBits();
    }

    table t {
        actions = { bar; }
        default_action = bar;
    }

    apply {
        t.apply();
    }
}

control proto();
package top(proto p);

top(C()) main;

crashes with:

Compiler Bug: t.p4(8): visitor returned non-MethodCallExpression type: 8
        h.minSizeInBits();
        ^^^^^^^^^^^^^^^^^
@kfcripps kfcripps added bug This behavior is unintended and should be fixed. core Topics concerning the core segments of the compiler (frontend, midend, parser) labels Apr 17, 2024
@kfcripps
Copy link
Contributor Author

Seems like the TypeInference pass may transform an IR::MethodCallStatement's methodCall to an IR::Constant, but a methodCall must be an IR::MethodCallExpression.

        // Constant-fold constant expressions
        if (auto mem = expression->method->to<IR::Member>()) {
            auto type = typeMap->getType(mem->expr, true);
            if (((mem->member == IR::Type::minSizeInBits ||
                  mem->member == IR::Type::minSizeInBytes ||
                  mem->member == IR::Type::maxSizeInBits ||
                  mem->member == IR::Type::maxSizeInBytes)) &&
                !type->is<IR::Type_Extern>() && expression->typeArguments->size() == 0 &&
                expression->arguments->size() == 0) {
                auto max = mem->member.name.startsWith("max");
                int w = typeMap->widthBits(type, expression, max);
                LOG3("Folding " << mem << " to " << w);
                if (w < 0) return expression;
                if (mem->member.name.endsWith("Bytes")) w = ROUNDUP(w, 8);
                auto result = new IR::Constant(expression->srcInfo, w);
                auto tt = new IR::Type_Type(result->type);
                setType(result->type, tt);
                setType(result, result->type);
                setCompileTimeConstant(result);
                return result;
            }

github-merge-queue bot pushed a commit that referenced this issue Apr 19, 2024
…resolves to a compile-time constant. (#4627)

* Prune MethodCallStatements if child MethodCallExpression resolves to a compile-time constant.

* Apply clang formatting

* code cleanup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This behavior is unintended and should be fixed. core Topics concerning the core segments of the compiler (frontend, midend, parser)
Projects
None yet
1 participant