diff --git a/frontends/p4/typeChecking/typeChecker.cpp b/frontends/p4/typeChecking/typeChecker.cpp index 876c5a9b80..5a420e1d7d 100644 --- a/frontends/p4/typeChecking/typeChecker.cpp +++ b/frontends/p4/typeChecking/typeChecker.cpp @@ -3862,10 +3862,19 @@ const IR::Node *TypeInference::postorder(IR::MethodCallExpression *expression) { return expression; } - if (mi->is() && constArgs) { - // extern functions with constant args are compile-time constants - setCompileTimeConstant(expression); - setCompileTimeConstant(getOriginal()); + if (const auto *ef = mi->to()) { + const IR::Type *baseReturnType = returnType; + if (const auto *sc = returnType->to()) + baseReturnType = sc->baseType; + const bool factoryOrStaticAssert = + baseReturnType->is() || ef->method->name == "static_assert"; + if (constArgs && factoryOrStaticAssert) { + // factory extern function calls (those that return extern objects) with constant + // args are compile-time constants. + // The result of a static_assert call is also a compile-time constant. + setCompileTimeConstant(expression); + setCompileTimeConstant(getOriginal()); + } } auto bi = mi->to(); diff --git a/testdata/p4_16_samples/issue4661_non_pure_extern_function_const_args.p4 b/testdata/p4_16_samples/issue4661_non_pure_extern_function_const_args.p4 new file mode 100644 index 0000000000..3863a9f07f --- /dev/null +++ b/testdata/p4_16_samples/issue4661_non_pure_extern_function_const_args.p4 @@ -0,0 +1,24 @@ +#include + +extern void foo(); +extern void bar(); +extern bit<8> baz(); +action a(){} +action b(){} +control c() { + table t { + actions = { a ; b; } + } + apply { + switch(baz()) { + 1 : { foo(); } + 4 : { bar(); } + } + t.apply(); + } +} + +control C(); +package top(C c); + +top(c()) main; diff --git a/testdata/p4_16_samples/issue4661_pure_extern_function_const_args.p4 b/testdata/p4_16_samples/issue4661_pure_extern_function_const_args.p4 new file mode 100644 index 0000000000..a39c23a3ec --- /dev/null +++ b/testdata/p4_16_samples/issue4661_pure_extern_function_const_args.p4 @@ -0,0 +1,24 @@ +#include + +extern void foo(); +extern void bar(); +@pure extern bit<8> baz(); +action a(){} +action b(){} +control c() { + table t { + actions = { a ; b; } + } + apply { + switch(baz()) { + 1 : { foo(); } + 4 : { bar(); } + } + t.apply(); + } +} + +control C(); +package top(C c); + +top(c()) main; diff --git a/testdata/p4_16_samples_outputs/issue4656_const_fold_generic_switch_label_expr.p4-stderr b/testdata/p4_16_samples_outputs/issue4656_const_fold_generic_switch_label_expr.p4-stderr index 72a9bd7b51..e69de29bb2 100644 --- a/testdata/p4_16_samples_outputs/issue4656_const_fold_generic_switch_label_expr.p4-stderr +++ b/testdata/p4_16_samples_outputs/issue4656_const_fold_generic_switch_label_expr.p4-stderr @@ -1,3 +0,0 @@ -issue4656_const_fold_generic_switch_label_expr.p4(13): [--Wwarn=mismatch] warning: baz(): constant expression in switch - switch(baz()) { - ^^^^^ diff --git a/testdata/p4_16_samples_outputs/issue4661_non_pure_extern_function_const_args-first.p4 b/testdata/p4_16_samples_outputs/issue4661_non_pure_extern_function_const_args-first.p4 new file mode 100644 index 0000000000..64c764fcc6 --- /dev/null +++ b/testdata/p4_16_samples_outputs/issue4661_non_pure_extern_function_const_args-first.p4 @@ -0,0 +1,34 @@ +#include + +extern void foo(); +extern void bar(); +extern bit<8> baz(); +action a() { +} +action b() { +} +control c() { + table t { + actions = { + a(); + b(); + @defaultonly NoAction(); + } + default_action = NoAction(); + } + apply { + switch (baz()) { + 8w1: { + foo(); + } + 8w4: { + bar(); + } + } + t.apply(); + } +} + +control C(); +package top(C c); +top(c()) main; diff --git a/testdata/p4_16_samples_outputs/issue4661_non_pure_extern_function_const_args-frontend.p4 b/testdata/p4_16_samples_outputs/issue4661_non_pure_extern_function_const_args-frontend.p4 new file mode 100644 index 0000000000..f7f9760cb6 --- /dev/null +++ b/testdata/p4_16_samples_outputs/issue4661_non_pure_extern_function_const_args-frontend.p4 @@ -0,0 +1,38 @@ +#include + +extern void foo(); +extern void bar(); +extern bit<8> baz(); +control c() { + @name("c.tmp") bit<8> tmp; + @name(".a") action a_0() { + } + @name(".b") action b_0() { + } + @noWarn("unused") @name(".NoAction") action NoAction_1() { + } + @name("c.t") table t_0 { + actions = { + a_0(); + b_0(); + @defaultonly NoAction_1(); + } + default_action = NoAction_1(); + } + apply { + tmp = baz(); + switch (tmp) { + 8w1: { + foo(); + } + 8w4: { + bar(); + } + } + t_0.apply(); + } +} + +control C(); +package top(C c); +top(c()) main; diff --git a/testdata/p4_16_samples_outputs/issue4661_non_pure_extern_function_const_args-midend.p4 b/testdata/p4_16_samples_outputs/issue4661_non_pure_extern_function_const_args-midend.p4 new file mode 100644 index 0000000000..386a146678 --- /dev/null +++ b/testdata/p4_16_samples_outputs/issue4661_non_pure_extern_function_const_args-midend.p4 @@ -0,0 +1,88 @@ +#include + +extern void foo(); +extern void bar(); +extern bit<8> baz(); +control c() { + @name("c.tmp") bit<8> tmp; + @name(".a") action a_0() { + } + @name(".b") action b_0() { + } + @noWarn("unused") @name(".NoAction") action NoAction_1() { + } + @name("c.t") table t_0 { + actions = { + a_0(); + b_0(); + @defaultonly NoAction_1(); + } + default_action = NoAction_1(); + } + @hidden action switch_0_case() { + } + @hidden action switch_0_case_0() { + } + @hidden action switch_0_case_1() { + } + @hidden table switch_0_table { + key = { + tmp: exact; + } + actions = { + switch_0_case(); + switch_0_case_0(); + switch_0_case_1(); + } + const default_action = switch_0_case_1(); + const entries = { + const 8w1 : switch_0_case(); + const 8w4 : switch_0_case_0(); + } + } + @hidden action issue4661_non_pure_extern_function_const_args14() { + foo(); + } + @hidden action issue4661_non_pure_extern_function_const_args15() { + bar(); + } + @hidden action act() { + tmp = baz(); + } + @hidden table tbl_act { + actions = { + act(); + } + const default_action = act(); + } + @hidden table tbl_issue4661_non_pure_extern_function_const_args14 { + actions = { + issue4661_non_pure_extern_function_const_args14(); + } + const default_action = issue4661_non_pure_extern_function_const_args14(); + } + @hidden table tbl_issue4661_non_pure_extern_function_const_args15 { + actions = { + issue4661_non_pure_extern_function_const_args15(); + } + const default_action = issue4661_non_pure_extern_function_const_args15(); + } + apply { + tbl_act.apply(); + switch (switch_0_table.apply().action_run) { + switch_0_case: { + tbl_issue4661_non_pure_extern_function_const_args14.apply(); + } + switch_0_case_0: { + tbl_issue4661_non_pure_extern_function_const_args15.apply(); + } + switch_0_case_1: { + } + } + t_0.apply(); + } +} + +control C(); +package top(C c); +top(c()) main; diff --git a/testdata/p4_16_samples_outputs/issue4661_non_pure_extern_function_const_args.p4 b/testdata/p4_16_samples_outputs/issue4661_non_pure_extern_function_const_args.p4 new file mode 100644 index 0000000000..1343b2fc19 --- /dev/null +++ b/testdata/p4_16_samples_outputs/issue4661_non_pure_extern_function_const_args.p4 @@ -0,0 +1,32 @@ +#include + +extern void foo(); +extern void bar(); +extern bit<8> baz(); +action a() { +} +action b() { +} +control c() { + table t { + actions = { + a; + b; + } + } + apply { + switch (baz()) { + 1: { + foo(); + } + 4: { + bar(); + } + } + t.apply(); + } +} + +control C(); +package top(C c); +top(c()) main; diff --git a/testdata/p4_16_samples_outputs/issue4661_non_pure_extern_function_const_args.p4-stderr b/testdata/p4_16_samples_outputs/issue4661_non_pure_extern_function_const_args.p4-stderr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testdata/p4_16_samples_outputs/issue4661_pure_extern_function_const_args-first.p4 b/testdata/p4_16_samples_outputs/issue4661_pure_extern_function_const_args-first.p4 new file mode 100644 index 0000000000..bcb1350467 --- /dev/null +++ b/testdata/p4_16_samples_outputs/issue4661_pure_extern_function_const_args-first.p4 @@ -0,0 +1,34 @@ +#include + +extern void foo(); +extern void bar(); +@pure extern bit<8> baz(); +action a() { +} +action b() { +} +control c() { + table t { + actions = { + a(); + b(); + @defaultonly NoAction(); + } + default_action = NoAction(); + } + apply { + switch (baz()) { + 8w1: { + foo(); + } + 8w4: { + bar(); + } + } + t.apply(); + } +} + +control C(); +package top(C c); +top(c()) main; diff --git a/testdata/p4_16_samples_outputs/issue4661_pure_extern_function_const_args-frontend.p4 b/testdata/p4_16_samples_outputs/issue4661_pure_extern_function_const_args-frontend.p4 new file mode 100644 index 0000000000..531c26a86a --- /dev/null +++ b/testdata/p4_16_samples_outputs/issue4661_pure_extern_function_const_args-frontend.p4 @@ -0,0 +1,38 @@ +#include + +extern void foo(); +extern void bar(); +@pure extern bit<8> baz(); +control c() { + @name("c.tmp") bit<8> tmp; + @name(".a") action a_0() { + } + @name(".b") action b_0() { + } + @noWarn("unused") @name(".NoAction") action NoAction_1() { + } + @name("c.t") table t_0 { + actions = { + a_0(); + b_0(); + @defaultonly NoAction_1(); + } + default_action = NoAction_1(); + } + apply { + tmp = baz(); + switch (tmp) { + 8w1: { + foo(); + } + 8w4: { + bar(); + } + } + t_0.apply(); + } +} + +control C(); +package top(C c); +top(c()) main; diff --git a/testdata/p4_16_samples_outputs/issue4661_pure_extern_function_const_args-midend.p4 b/testdata/p4_16_samples_outputs/issue4661_pure_extern_function_const_args-midend.p4 new file mode 100644 index 0000000000..4f080dde33 --- /dev/null +++ b/testdata/p4_16_samples_outputs/issue4661_pure_extern_function_const_args-midend.p4 @@ -0,0 +1,88 @@ +#include + +extern void foo(); +extern void bar(); +@pure extern bit<8> baz(); +control c() { + @name("c.tmp") bit<8> tmp; + @name(".a") action a_0() { + } + @name(".b") action b_0() { + } + @noWarn("unused") @name(".NoAction") action NoAction_1() { + } + @name("c.t") table t_0 { + actions = { + a_0(); + b_0(); + @defaultonly NoAction_1(); + } + default_action = NoAction_1(); + } + @hidden action switch_0_case() { + } + @hidden action switch_0_case_0() { + } + @hidden action switch_0_case_1() { + } + @hidden table switch_0_table { + key = { + tmp: exact; + } + actions = { + switch_0_case(); + switch_0_case_0(); + switch_0_case_1(); + } + const default_action = switch_0_case_1(); + const entries = { + const 8w1 : switch_0_case(); + const 8w4 : switch_0_case_0(); + } + } + @hidden action issue4661_pure_extern_function_const_args14() { + foo(); + } + @hidden action issue4661_pure_extern_function_const_args15() { + bar(); + } + @hidden action act() { + tmp = baz(); + } + @hidden table tbl_act { + actions = { + act(); + } + const default_action = act(); + } + @hidden table tbl_issue4661_pure_extern_function_const_args14 { + actions = { + issue4661_pure_extern_function_const_args14(); + } + const default_action = issue4661_pure_extern_function_const_args14(); + } + @hidden table tbl_issue4661_pure_extern_function_const_args15 { + actions = { + issue4661_pure_extern_function_const_args15(); + } + const default_action = issue4661_pure_extern_function_const_args15(); + } + apply { + tbl_act.apply(); + switch (switch_0_table.apply().action_run) { + switch_0_case: { + tbl_issue4661_pure_extern_function_const_args14.apply(); + } + switch_0_case_0: { + tbl_issue4661_pure_extern_function_const_args15.apply(); + } + switch_0_case_1: { + } + } + t_0.apply(); + } +} + +control C(); +package top(C c); +top(c()) main; diff --git a/testdata/p4_16_samples_outputs/issue4661_pure_extern_function_const_args.p4 b/testdata/p4_16_samples_outputs/issue4661_pure_extern_function_const_args.p4 new file mode 100644 index 0000000000..86fe060301 --- /dev/null +++ b/testdata/p4_16_samples_outputs/issue4661_pure_extern_function_const_args.p4 @@ -0,0 +1,32 @@ +#include + +extern void foo(); +extern void bar(); +@pure extern bit<8> baz(); +action a() { +} +action b() { +} +control c() { + table t { + actions = { + a; + b; + } + } + apply { + switch (baz()) { + 1: { + foo(); + } + 4: { + bar(); + } + } + t.apply(); + } +} + +control C(); +package top(C c); +top(c()) main; diff --git a/testdata/p4_16_samples_outputs/issue4661_pure_extern_function_const_args.p4-stderr b/testdata/p4_16_samples_outputs/issue4661_pure_extern_function_const_args.p4-stderr new file mode 100644 index 0000000000..e69de29bb2