verilog: impose limit on maximum expression width
authorZachary Snow <zach@zachjs.com>
Thu, 4 Mar 2021 20:08:16 +0000 (15:08 -0500)
committerZachary Snow <zach@zachjs.com>
Thu, 4 Mar 2021 20:20:52 +0000 (15:20 -0500)
Designs with unreasonably wide expressions would previously get stuck
allocating memory forever.

frontends/ast/genrtlil.cc
tests/verilog/absurd_width.ys [new file with mode: 0644]
tests/verilog/absurd_width_const.ys [new file with mode: 0644]

index d4299bf69c64b35a5b7cc93fdab9baad7035df7c..e0a52243054d7d76536b8b16f396de71089bfded 100644 (file)
@@ -1000,6 +1000,12 @@ void AstNode::detectSignWidth(int &width_hint, bool &sign_hint, bool *found_real
        if (found_real)
                *found_real = false;
        detectSignWidthWorker(width_hint, sign_hint, found_real);
+
+       constexpr int kWidthLimit = 1 << 24;
+       if (width_hint >= kWidthLimit)
+               log_file_error(filename, location.first_line,
+                       "Expression width %d exceeds implementation limit of %d!\n",
+                       width_hint, kWidthLimit);
 }
 
 static void check_unique_id(RTLIL::Module *module, RTLIL::IdString id,
diff --git a/tests/verilog/absurd_width.ys b/tests/verilog/absurd_width.ys
new file mode 100644 (file)
index 0000000..c0d2af4
--- /dev/null
@@ -0,0 +1,17 @@
+logger -expect error "Expression width 1073741824 exceeds implementation limit of 16777216!" 1
+read_verilog <<EOF
+module top(
+    input inp,
+    output out
+);
+    assign out =
+        {1024 {
+        {1024 {
+        {1024 {
+        inp
+        }}
+        }}
+        }}
+        ;
+endmodule
+EOF
diff --git a/tests/verilog/absurd_width_const.ys b/tests/verilog/absurd_width_const.ys
new file mode 100644 (file)
index 0000000..b7191fd
--- /dev/null
@@ -0,0 +1,16 @@
+logger -expect error "Expression width 1073741824 exceeds implementation limit of 16777216!" 1
+read_verilog <<EOF
+module top(
+    output out
+);
+    assign out =
+        {1024 {
+        {1024 {
+        {1024 {
+        1'b1
+        }}
+        }}
+        }}
+        ;
+endmodule
+EOF