Skip to content

Commit c3b7f4d

Browse files
committed
Typechecking 'for' statements
- condition in a 'for' must be bool Signed-off-by: Chris Dodd <cdodd@nvidia.com>
1 parent 11a710d commit c3b7f4d

7 files changed

Lines changed: 44 additions & 0 deletions

File tree

frontends/p4/typeChecking/readOnlyTypeInference.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ DEFINE_POSTORDER(IR::AssignmentStatement)
143143
DEFINE_POSTORDER(IR::OpAssignmentStatement)
144144
DEFINE_POSTORDER(IR::ShlAssign)
145145
DEFINE_POSTORDER(IR::ShrAssign)
146+
DEFINE_POSTORDER(IR::ForStatement)
146147
DEFINE_POSTORDER(IR::ForInStatement)
147148
DEFINE_POSTORDER(IR::ActionListElement)
148149
DEFINE_POSTORDER(IR::KeyElement)

frontends/p4/typeChecking/typeCheckStmt.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@ limitations under the License.
1818

1919
namespace P4 {
2020

21+
const IR::Node *TypeInferenceBase::postorder(const IR::ForStatement *stmt) {
22+
LOG3("TI Visiting " << dbp(getOriginal()));
23+
auto type = getType(stmt->condition);
24+
if (type == nullptr) return stmt;
25+
if (!type->is<IR::Type_Boolean>())
26+
typeError("Condition of %1% does not evaluate to a bool but %2%", stmt, type->toString());
27+
return stmt;
28+
}
29+
2130
const IR::Node *TypeInferenceBase::postorder(const IR::IfStatement *conditional) {
2231
LOG3("TI Visiting " << dbp(getOriginal()));
2332
auto type = getType(conditional->condition);

frontends/p4/typeChecking/typeChecker.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ class TypeInferenceBase : public virtual Visitor, public ResolutionContext {
326326
const IR::Node *postorder(const IR::ActionList *al);
327327

328328
const IR::Node *postorder(const IR::ReturnStatement *stat);
329+
const IR::Node *postorder(const IR::ForStatement *stat);
329330
const IR::Node *postorder(const IR::IfStatement *stat);
330331
const IR::Node *postorder(const IR::SwitchStatement *stat);
331332
const IR::Node *common_assign(const IR::BaseAssignmentStatement *stat, const IR::Type *);
@@ -474,6 +475,7 @@ class ReadOnlyTypeInference : public virtual Inspector, public TypeInferenceBase
474475
void postorder(const IR::ActionList *al) override;
475476

476477
void postorder(const IR::ReturnStatement *stat) override;
478+
void postorder(const IR::ForStatement *stat) override;
477479
void postorder(const IR::IfStatement *stat) override;
478480
void postorder(const IR::SwitchStatement *stat) override;
479481
void postorder(const IR::AssignmentStatement *stat) override;
@@ -613,6 +615,7 @@ class TypeInference : public virtual Transform, public TypeInferenceBase {
613615
const IR::Node *postorder(IR::ActionList *al) override;
614616

615617
const IR::Node *postorder(IR::ReturnStatement *stat) override;
618+
const IR::Node *postorder(IR::ForStatement *stat) override;
616619
const IR::Node *postorder(IR::IfStatement *stat) override;
617620
const IR::Node *postorder(IR::SwitchStatement *stat) override;
618621
const IR::Node *postorder(IR::AssignmentStatement *stat) override;

frontends/p4/typeChecking/typeInference.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ DEFINE_POSTORDER(IR::AssignmentStatement)
134134
DEFINE_POSTORDER(IR::OpAssignmentStatement)
135135
DEFINE_POSTORDER(IR::ShlAssign)
136136
DEFINE_POSTORDER(IR::ShrAssign)
137+
DEFINE_POSTORDER(IR::ForStatement)
137138
DEFINE_POSTORDER(IR::ForInStatement)
138139
DEFINE_POSTORDER(IR::ActionListElement)
139140
DEFINE_POSTORDER(IR::KeyElement)

testdata/p4_16_errors/loop4-err.p4

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2026 Nvidia Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
extern void fn(in bit<8> c);
8+
9+
control c() {
10+
apply {
11+
for (bit<8> a = 15; a; a -= 1) {
12+
fn(a);
13+
}
14+
}
15+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
extern void fn(in bit<8> c);
2+
control c() {
3+
apply {
4+
for (bit<8> a = 15; a; a -= 1) {
5+
fn(a);
6+
}
7+
}
8+
}
9+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
loop4-err.p4(9): [--Wwarn=unused] warning: control 'c' is unused
2+
control c() {
3+
^
4+
loop4-err.p4(11): [--Werror=type-error] error: Condition of ForStatement does not evaluate to a bool but bit<8>
5+
for (bit<8> a = 15; a; a -= 1) {
6+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

0 commit comments

Comments
 (0)