Skip to content

Commit

Permalink
Do not print confusing warning when a parser state contains an assign…
Browse files Browse the repository at this point in the history
…ment to an l-value slice (p4lang#4948)

* Do not print confusing warning when a parser state contains an assignment to an l-value slice

Signed-off-by: Kyle Cripps <[email protected]>

* Add additional test case

Signed-off-by: Kyle Cripps <[email protected]>

* rename test

Signed-off-by: Kyle Cripps <[email protected]>

* Add assertion for AbstractSlice

Signed-off-by: Kyle Cripps <[email protected]>

---------

Signed-off-by: Kyle Cripps <[email protected]>
  • Loading branch information
kfcripps authored Oct 12, 2024
1 parent 9d1f746 commit 88a4ae8
Show file tree
Hide file tree
Showing 23 changed files with 289 additions and 3 deletions.
13 changes: 10 additions & 3 deletions midend/interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -741,9 +741,16 @@ void ExpressionEvaluator::postorder(const IR::Operation_Ternary *expression) {
auto e1i = e1->to<ScalarValue>();
auto e2i = e2->to<ScalarValue>();
if (e0i->isUninitialized()) {
auto result = new SymbolicStaticError(expression->e0, "Uninitialized");
set(expression, result);
return;
// This cannot be an uninitialized read if 'expression' is the LHS of
// an assignment to a sliced l-value.
if (!evaluatingLeftValue) {
auto result = new SymbolicStaticError(expression->e0, "Uninitialized");
set(expression, result);
return;
} else {
BUG_CHECK(expression->is<IR::AbstractSlice>(), "%1%: Expected AbstractSlice.",
expression);
}
} else if (e1i->isUninitialized()) {
auto result = new SymbolicStaticError(expression->e1, "Uninitialized");
set(expression, result);
Expand Down
12 changes: 12 additions & 0 deletions testdata/p4_16_samples/parser-unroll-uninitialized-slice-read.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <core.p4>

parser p(packet_in packet, out bit<8> f, out bit<4> g) {
state start {
g = f[3:0];
transition accept;
}
}

parser simple(packet_in packet, out bit<8> f, out bit<4> g);
package top(simple e);
top(p()) main;
16 changes: 16 additions & 0 deletions testdata/p4_16_samples/parser-unroll-uninitialized-slice-write.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <core.p4>

struct S {
bit<8> f;
}

parser p(packet_in packet, out S s) {
state start {
s.f[3:0] = 2;
transition accept;
}
}

parser simple(packet_in packet, out S s);
package top(simple e);
top(p()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <core.p4>

parser p(packet_in packet, out bit<8> f, out bit<4> g) {
state start {
g = f[3:0];
transition accept;
}
}

parser simple(packet_in packet, out bit<8> f, out bit<4> g);
package top(simple e);
top(p()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <core.p4>

parser p(packet_in packet, out bit<8> f, out bit<4> g) {
state start {
g = f[3:0];
transition accept;
}
}

parser simple(packet_in packet, out bit<8> f, out bit<4> g);
package top(simple e);
top(p()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <core.p4>

parser p(packet_in packet, out bit<8> f, out bit<4> g) {
state start {
g = f[3:0];
transition accept;
}
}

parser simple(packet_in packet, out bit<8> f, out bit<4> g);
package top(simple e);
top(p()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <core.p4>

parser p(packet_in packet, out bit<8> f, out bit<4> g) {
state start {
g = f[3:0];
transition accept;
}
}

parser simple(packet_in packet, out bit<8> f, out bit<4> g);
package top(simple e);
top(p()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
parser-unroll-uninitialized-slice-read.p4(5): [--Wwarn=uninitialized_use] warning: f may be uninitialized
g = f[3:0];
^
parser-unroll-uninitialized-slice-read.p4(3): [--Wwarn=uninitialized_out_param] warning: out parameter 'f' may be uninitialized when 'p' terminates
parser p(packet_in packet, out bit<8> f, out bit<4> g) {
^
parser-unroll-uninitialized-slice-read.p4(3)
parser p(packet_in packet, out bit<8> f, out bit<4> g) {
^
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <core.p4>

struct S {
bit<8> f;
}

parser p(packet_in packet, out S s) {
state start {
s.f[3:0] = 4w2;
transition accept;
}
}

parser simple(packet_in packet, out S s);
package top(simple e);
top(p()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <core.p4>

struct S {
bit<8> f;
}

parser p(packet_in packet, out S s) {
state start {
s.f[3:0] = 4w2;
transition accept;
}
}

parser simple(packet_in packet, out S s);
package top(simple e);
top(p()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <core.p4>

struct S {
bit<8> f;
}

parser p(packet_in packet, out S s) {
state start {
s.f[3:0] = 4w2;
transition accept;
}
}

parser simple(packet_in packet, out S s);
package top(simple e);
top(p()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <core.p4>

struct S {
bit<8> f;
}

parser p(packet_in packet, out S s) {
state start {
s.f[3:0] = 2;
transition accept;
}
}

parser simple(packet_in packet, out S s);
package top(simple e);
top(p()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
parser-unroll-uninitialized-slice-write.p4(9): [--Wwarn=uninitialized_use] warning: s.f may be uninitialized
s.f[3:0] = 2;
^^^
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <core.p4>

parser p(packet_in packet, out bit<8> f, out bit<4> g) {
state start {
g = f[3:0];
transition accept;
}
}

parser simple(packet_in packet, out bit<8> f, out bit<4> g);
package top(simple e);
top(p()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <core.p4>

parser p(packet_in packet, out bit<8> f, out bit<4> g) {
state start {
g = f[3:0];
transition accept;
}
}

parser simple(packet_in packet, out bit<8> f, out bit<4> g);
package top(simple e);
top(p()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <core.p4>

parser p(packet_in packet, out bit<8> f, out bit<4> g) {
state start {
g = f[3:0];
transition accept;
}
}

parser simple(packet_in packet, out bit<8> f, out bit<4> g);
package top(simple e);
top(p()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <core.p4>

parser p(packet_in packet, out bit<8> f, out bit<4> g) {
state start {
g = f[3:0];
transition accept;
}
}

parser simple(packet_in packet, out bit<8> f, out bit<4> g);
package top(simple e);
top(p()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
parser-unroll-uninitialized-slice-read.p4(5): [--Wwarn=uninitialized_use] warning: f may be uninitialized
g = f[3:0];
^
parser-unroll-uninitialized-slice-read.p4(3): [--Wwarn=uninitialized_out_param] warning: out parameter 'f' may be uninitialized when 'p' terminates
parser p(packet_in packet, out bit<8> f, out bit<4> g) {
^
parser-unroll-uninitialized-slice-read.p4(3)
parser p(packet_in packet, out bit<8> f, out bit<4> g) {
^
parser-unroll-uninitialized-slice-read.p4(5): [--Wwarn=ignore-prop] warning: Result of 'g = f[3:0]' is not defined: Error: Uninitialized
g = f[3:0];
^
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <core.p4>

struct S {
bit<8> f;
}

parser p(packet_in packet, out S s) {
state start {
s.f[3:0] = 4w2;
transition accept;
}
}

parser simple(packet_in packet, out S s);
package top(simple e);
top(p()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <core.p4>

struct S {
bit<8> f;
}

parser p(packet_in packet, out S s) {
state start {
s.f[3:0] = 4w2;
transition accept;
}
}

parser simple(packet_in packet, out S s);
package top(simple e);
top(p()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <core.p4>

struct S {
bit<8> f;
}

parser p(packet_in packet, out S s) {
state start {
s.f[3:0] = 4w2;
transition accept;
}
}

parser simple(packet_in packet, out S s);
package top(simple e);
top(p()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <core.p4>

struct S {
bit<8> f;
}

parser p(packet_in packet, out S s) {
state start {
s.f[3:0] = 2;
transition accept;
}
}

parser simple(packet_in packet, out S s);
package top(simple e);
top(p()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
parser-unroll-uninitialized-slice-write.p4(9): [--Wwarn=uninitialized_use] warning: s.f may be uninitialized
s.f[3:0] = 2;
^^^

0 comments on commit 88a4ae8

Please sign in to comment.