// This file is an input to the diagnostic_gen.py script, to generate
// documentation for compiler warning flags.

@category Type Conversions

-Wwidth-expand
An implicit conversion in an expression expands a type. This may be harmless,
but the warning provides a mechanism for discovering unintended conversions.
An explicit cast can be used to silence the warning.
Note that this warning is not issued for constant expressions;
see -Wconstant-conversion instead.
```
logic [1:0] a;
int b = a;
```

-Wwidth-trunc
An implicit conversion in an expression truncates a type. This conversion
potentially loses data. An explicit cast can be used to silence the warning.
Note that this warning is not issued for constant expressions;
see -Wconstant-conversion instead.
```
int a;
logic [1:0] b = a;
```

-Wport-width-expand
An implicit conversion in a port connection expression expands a type. This may
be harmless, but the warning provides a mechanism for discovering unintended conversions.
An explicit cast can be used to silence the warning.
```
module m(input int a); endmodule

module n;
    logic [1:0] a;
    m m1(.a(a));
endmodule
```

-Wport-width-trunc
An implicit conversion in a port connection expression truncates a type.
This conversion potentially loses data. An explicit cast can be used to silence the warning.
```
module m(input logic [1:0] a); endmodule

module n;
    int a;
    m m1(.a(a));
endmodule
```

-Wimplicit-conv
An implicit conversion in an expression converts between two unrelated types.
SystemVerilog allows this for all packed integral types but it often
indicates a mistake in the code.
```
module m;
    struct packed { logic a; int b; } foo;
    union packed { int a; int b; } bar;
    initial foo = bar;
endmodule
```

-Wconstant-conversion
A constant value is changed (truncated) by an implicit conversion.
```
module m;
    logic [9:0] a = 9000;
endmodule
```

-Wsign-conversion
An implicit conversion changes the signedness of an integer type
(from signed to unsigned or vice versa).
Note that this warning is not issued for constant expressions;
see -Wconstant-conversion instead.
```
module m;
    logic signed [31:0] a;
    logic [31:0] b;
    assign b = a;
endmodule
```

-Wfloat-bool-conv
A floating point value is implicitly converted to a boolean predicate (such as in an
if statement or loop condition). This is not necessarily wrong but can indicate
mistakes where you intended to compare the value to something.
```
module m;
    real r;
    initial if (r) begin end // Did you mean r != 0 or something else?
endmodule
```

-Wint-bool-conv
A multi-bit integer value is implicitly converted to a boolean predicate (such as in an
if statement or loop condition). This is not necessarily wrong but can indicate
mistakes where you intended to compare the value to something.
```
module m;
    int i;
    initial if (i + 2) begin end // Did you mean i + 2 != 0 or something else?
endmodule
```

-Wfloat-int-conv
A floating point value (real or shortreal) is implicitly converted to an integer.
Note that this warning is not issued for constant expressions;
see -Wconstant-conversion instead.
```
function automatic f(real r);
    int i = r;
endfunction
```

-Wint-float-conv
A integer value is implicitly converted to a floating point type (real or shortreal).
Note that this warning is not issued for constant expressions;
see -Wconstant-conversion instead.
```
function automatic f(int i);
    real r = i;
endfunction
```

-Wfloat-widen
A floating point value is implicitly converted to a wider floating point type.
Note that this warning is not issued for constant expressions;
see -Wconstant-conversion instead.
```
function automatic f(shortreal s);
    real r = s;
endfunction
```

-Wfloat-narrow
A floating point value is implicitly converted to a narrower floating point type.
Note that this warning is not issued for constant expressions;
see -Wconstant-conversion instead.
```
function automatic f(real r);
    shortreal s = r;
endfunction
```

-Warith-op-mismatch
An arithmetic operator has operands of different types -- one or both will be converted
before the operation is performed. This is not necessarily a problem but the warning
can be helpful if you prefer to be strict about disallowing implicit conversions.
```
module m;
    logic [7:0] a;
    struct packed { logic [7:0] x; } b;
    initial a += b;
endmodule
```

-Wbitwise-op-mismatch
A bitwise operator has operands of different types -- one or both will be converted
before the operation is performed. This is not necessarily a problem but the warning
can be helpful if you prefer to be strict about disallowing implicit conversions.
```
module m;
    logic [7:0] a;
    logic [11:1] b;
    initial a = a | b;
endmodule
```

-Wcomparison-mismatch
A comparison operator has operands of different types -- one or both will be converted
before the operation is performed. This is not necessarily a problem but the warning
can be helpful if you prefer to be strict about disallowing implicit conversions.
```
module m;
    logic [7:0] a;
    struct packed { logic [7:0] x; } b;
    initial begin
        if (a == b) begin
        end
    end
endmodule
```

-Wsign-compare
A comparison operator has operands of differing signs. The signed operand will be
treated as unsigned, which can lead to unexpected results.
```
module m;
    int a = -1;
    int unsigned b = 1;
    initial begin
        if (a < b) begin
        end
    end
endmodule
```

-Wpacked-array-conv
Indicates an implicit conversion between types with differing
packed array dimensions, even if their overall bit width is the same.
This will not warn for types with a single packed dimension; at least
one of the types must have multiple declared dimensions.
```
module m;
    logic [3:1][1:0] a;
    logic [5:0][1:0] b;
    initial b = a;
endmodule
```

-Wformat-real
A string formatting function was passed a real value for an integer format specifier,
which will force the value to round to an integer.
```
module m;
    initial $display("%d", 3.14);
endmodule
```

@category Port Connections

-Wunconnected-input-port
An instance input port was left unconnected and it has no default value.
```
module m(input int i);
endmodule

module n;
    m m1();
endmodule
```

-Wunconnected-output-port
An instance output port was left unconnected and it has no default value.
```
module m(output int o);
endmodule

module n;
    m m1();
endmodule
```

-Wunconnected-inout-port
An instance inout port was left unconnected.
```
module m(inout wire w);
endmodule

module n;
    m m1();
endmodule
```

-Wunconnected-unnamed-port
An unnamed instance port was left unconnected.
```
module m({a, b});
    input a, b;
endmodule

module n;
    m m1();
endmodule
```

-Wempty-input-connection
An instance input port was explicitly connected to nothing via `.port_name()` syntax.
This causes the port to receive the default value of its *type* (e.g. `'x` for `logic`),
not the default value expression declared on the port, if any.
If the intent is to use the port's default value expression, omit the connection entirely
or use a named connection with the default value explicitly.
```
module m(input logic a = 1, input logic b);
endmodule

module n;
    m m1(.a(), .b());   // a defaults to 'x, not 1; b also defaults to 'x
endmodule
```

-Wempty-output-connection
An instance output port was explicitly connected to nothing via `.port_name()` syntax.
The driven value from the module is silently discarded.
```
module m(output logic o);
    assign o = 1;
endmodule

module n;
    m m1(.o());   // driven value is discarded
endmodule
```

-Wempty-inout-connection
An instance inout port was explicitly connected to nothing via `.port_name()` syntax.
```
module m(inout wire w);
endmodule

module n;
    m m1(.w());   // inout left disconnected
endmodule
```

-Wudp-port-empty
A connection to a user-defined primitive instance is an empty expression.
While allowed, this is easily confused with a misplaced comma and is likely
not what you want.
```
primitive p1 (output a, input b);
    table 0:0; endtable
endprimitive

module m;
    logic a;
    p1 (a,);
endmodule
```

-Wnet-inconsistent
A connection (or part of a connection) between an external net and an internal net
port has inconsistent net types. The SystemVerilog LRM defines which combinations
of net types are inconsistent and should produce a warning; see section [23.3.3.7]
"Port connections with dissimilar net types (net and port collapsing)" for more detail.
```
module m (input .a({b, {c[1:0], d}}));
    wand b;
    wand [3:0] c;
    supply0 d;
endmodule

module top;
    wand a;
    wor b;
    trireg [1:0] c;
    m m1({a, b, c});
endmodule
```

-Wport-coercion
An input net port has been coerced to 'inout' direction because it is assigned
to in the instance body. Alternatively, an output net port has been coerced to
'inout' direction because it is assigned externally to the instance.
```
module m(input wire a, output b);
    assign a = 1;
endmodule

module n;
    wire b;
    m m1(1, b);
    assign b = 1;
endmodule
```

-Wineffective-sign
For a non-ANSI instance port or function body port declaration, the port I/O specifies a
signing keyword but the actual data type of the port does not permit that signing to take effect.
```
module m(a);
    input unsigned a;
    int a;
endmodule
```

-Wnull-port
A non-ANSI module port list contains a port with no name and no connection.
This is almost always caused by an accidental extra comma in the port list
rather than an intentional empty port.
```
module m(a, , b);
    input a;
    input b;
endmodule
```

@category Case Statements

-Wcase-gen-dup
More than one case generate item was found to have the same value. The second
case block will never be selected.
```
module m;
    case (1)
        1: begin end
        1: begin end
    endcase
endmodule
```

-Wcase-gen-none
A case generate directive did not match any items and so no block was selected.
```
module m;
    case (1)
        0: begin end
    endcase
endmodule
```

-Wcase-type
The type of a case item expression does not match the type of the case condition
expression.
```
module m;
    enum {A, B} e;
    enum {C, D} f;
    initial begin
        case (e)
            C: ;
        endcase
    end
endmodule
```

-Wcase-default
A case statement is missing a 'default' label. This is not necessarily problematic,
but some coding standards mandate that all case statements include a 'default' so
this warning can be used to enforce that.
```
module m;
    enum {A, B} e;
    initial begin
        case (e)
            A, B: ;
        endcase
    end
endmodule
```

-Wcase-outside-range
A case item has a known value that makes it impossible to ever match
the case condition (or vice versa).
```
module m;
    logic [2:0] a;
    initial begin
        case (a)
            4'b1000: ;
        endcase
    end
endmodule
```

-Wcase-enum
A case statement with an enum type condition does not include items
that cover every enumerand. Note that this warning will not be
issued if there is a 'default' label.
```
module m;
    enum {A, B} e;
    initial begin
        case (e)
            A: ;
        endcase
    end
endmodule
```

-Wcase-enum-explicit
A case statement with an enum type condition does not include items
that cover every enumerand, regardless of whether there is a default
label or not.
```
module m;
    enum {A, B} e;
    initial begin
        case (e)
            A: ;
            default;
        endcase
    end
endmodule
```

-Wcase-dup
A case statement contains more than one item with the same value.
Case items are evaluated and selected in order and so the second
one will never be matched.
```
module m;
    int i;
    initial begin
        case (i)
            1, 2:;
            3, 1:;
            default;
        endcase
    end
endmodule
```

-Wcase-overlap
A wildcard case statement contains overlapping items, which can be confusing
since the overlapping value(s) will only ever match the first item in the list.
```
module m;
    logic [3:0] a;
    initial begin
        casez (a)
            4'b1011:;
            4'b101?:;
            default;
        endcase
    end
endmodule
```

-Wcase-unreachable
A wildcard case statement is unreachable because earlier items completely
cover all of its possible values.
```
module m;
    logic [2:0] a;
    initial begin
        casez (a)
            3'b10?:;
            3'b101:;
            default;
        endcase
    end
endmodule
```

-Wcase-not-wildcard
A normal case statement has items with integer literals that contain X or Z bits.
These bits don't count as wildcards, so the designer may have meant for this to
be a 'casex' or 'casez' statement instead.
```
module m;
    logic [2:0] a;
    initial begin
        case (a)
            3'b10?:;
        endcase
    end
endmodule
```

-Wcasez-with-x
A 'casez' statement has items with integer literals that contain X bits.
These bits don't count as wildcards, so the designer may have meant for this to
be a 'casex' statement instead.
```
module m;
    logic [2:0] a;
    initial begin
        casez (a)
            3'b10x:;
        endcase
    end
endmodule
```

-Wcase-too-complex
@options --max-case-analysis-steps=1024
Determining whether a list of wildcard case clauses fully cover the entire input space
is, in general, NP-complete, so there is a limit to prevent exponential explosion in
analysis time. In practice case statements written by humans will rarely, if ever,
exhibit this kind of behavior.
```
module m;
    logic [51:0] a;
    always_comb begin
        casex (a)
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx011111:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0111111:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01111111:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx011111111:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0111111111:;
            52'bxxxxxxxxxxxx1xxxxxxxxxxxxxxxxxxxxxxxxxxxx01111111x11:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx011111111111:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0111111111111:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01x11111111111:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx011111111111111:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0111111111111111:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01111111111111111:;
            52'bxxxxxxxxxxxxxxxxx0xxxxxxxxxxxxxxxx0111111111111x1111:;
            52'bxxxx1xxxxxxxxxxxxxxxxxxxxxxxxxxxx0111111111111111111:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01111111111111111111:;
            52'bxxxxxx1xxxxxxxxxxxxx1xxxxxx1xxx011111111111111111111:;
            52'bxxxxxxxxxxxx0xxxxxxxxxxxxxxxxx0111111111111111111111:;
        endcase
    end
endmodule
```

-Wcase-redundant-default
A case statement that is marked 'unique' or 'priority' has a default item.
Using 'unique' or 'priority' asserts that the case items fully cover all
possible inputs, so the default item should never be hit.
```
module m;
    logic [2:0] a;
    initial begin
        unique case (a)
            1:;
            2:;
            default; // Warning for default
        endcase
    end
endmodule
```

-Wcase-wildcard-2state
A wildcard case statement has a 2-state condition and 2-state items, so there
will never be unknown bits and therefore no wildcard matching will occur.
If expected, convert this to a normal 'case' statement to better express
the intent.
```
module m;
    bit [2:0] a;
    initial casex (a)
        3'd0:;
        3'd1:;
        default;
    endcase
endmodule
```

-Wcase-incomplete
A wildcard case statement is missing coverage of one or more possible inputs
and has no default case to handle them.
```
module m;
    logic [2:0] a;
    initial casez (a)
        3'b00?:;
        3'b1??:;
    endcase
endmodule
```

-Wcase-none
A case statement is statically known to not select any branch, because none of the
items match the known constant expression and there is no default label.
```
module m;
    always_comb begin
        case (1)
            2: begin end
            3: begin end
            4: begin end
        endcase
    end
endmodule
```

@category Constant Evaluation

-Wreal-underflow
Issued for real literals that are too small to be represented.
```
real r = 4.94066e-325;
```

-Wreal-overflow
Issued for real literals that are too large to be represented.
```
real r = 1.79769e+309;
```

-Wvector-overflow
Issued for vector literals that are larger than their specified number of bits.
```
logic [7:0] i = 7'd256;
```

-Wint-overflow
Issued for integer literals that overflow a 32-bit integer (31-bits plus sign).
```
int i = 2147483648;
```

-Welem-not-found
A constant function tried to access a nonexistent element of an associative array.
```
localparam int foo = func();
function int func;
    int i[string];
    return i["Hello"];
endfunction
```

-Wstatic-skipped
A constant function contains a static variable with an initializer. That initializer
will be skipped during constant evaluation, which could lead to unintuitive results.
```
localparam int foo = func();
function int func;
    static int i = 1;
    return i;
endfunction
```

-Wdynarray-index
A constant function tried to access a nonexistent element of a dynamic array.
```
localparam int foo = func();
function int func;
    automatic int i[] = new [2];
    return i[4];
endfunction
```

-Wdynarray-range
A constant function tried to access a nonexistent range of a dynamic array.
```
typedef int ret_type[2];
localparam ret_type foo = func();
function ret_type func;
    automatic int i[] = new [2];
    return i[6:7];
endfunction
```

-Wqueue-range
A constant function is accessing a queue with a reversed range, which
is defined to always yield an empty queue.
```
typedef int ret_type[$];
localparam ret_type foo = func();
function ret_type func;
    automatic int i[$] = {1, 2, 3};
    return i[2:0];
endfunction
```

-Wempty-queue
A constant function tried to pop an element from an empty queue.
```
localparam int foo = func();
function int func;
    automatic int i[$];
    return i.pop_back();
endfunction
```

-Wtask-ignored
A constant function contains a system task invocation which will
be skipped during constant evaluation. This could yield unintuitive results.
```
localparam string foo = func();
function string func;
    automatic string s;
    $swrite(s, "asdf %d", 3);
    return s;
endfunction
```

@category Misleading or Suspicious

-Wunknown-escape-code
Detects use of unknown character escape codes in string literals.
```
string s = "Hello World\q";
```

-Wempty-body
An empty statement body for a loop or conditional statement could be confusing or misleading.
If intended, move the semicolon to a separate line to suppress the warning.
```
module m;
    initial begin
        if (1); begin
        end
    end
endmodule
```

-Wdangling-else
A confusingly nested if/else statement lacks begin/end delimiters. The `else` clause
could be misread as belonging to a different `if` statement than it actually does.
Add begin/end blocks around the inner `if` statement to make the association clear.
```
module m(input a, b);
    initial begin
        if (a)
            if (b)
                $display("A");
            else
                $display("B");
    end
endmodule
```

-Wmisleading-indentation
A statement follows a loop or conditional statement that does not use `begin`/`end`, and that
statement is at the same indentation level as the body of the preceding construct. This is
misleading because it appears as if both statements are guarded by the loop or conditional,
when in fact only the first statement is.
```
module m;
    initial begin
        int x;
        if (x)
            x = 1;
            x = 2; // misleading: this is not guarded by the if
    end
endmodule
```

-Wcolon-plus
A range select contains `':+'` which is parsed as a simple range `[a : +b]` where the right
operand has unary plus applied. This is almost always a typo for the ascending part-select
operator `'+:'`, as in `[a +: b]`. Check whether the intent was an ascending range select and
rewrite accordingly.
```
module m;
    logic [7:0] v;
    logic [3:0] x;
    initial x = v[4:+4]; // probably meant v[4+:4]
endmodule
```

-Wdup-attr
A design element has more than one attribute of the same name.
Only the last one will apply.
```
module m;
    (* foo = 1, foo = 2 *)
    int i;
endmodule
```

-Wempty-member
An unnecessary semicolon is located in a non-procedural scope (such as a module body).
```
module m;
    ;
endmodule
```

-Wconstraint-missing
An implicit class constraint block has no external definition and so is useless.
```
class C;
    constraint c;
endclass
```

-Wignored-slice
A streaming operator with direction left-to-right provides a slice size, which
has no effect because only right-to-left streaming can use a slice size.
```
int a;
int b = {>> 4 {a}};
```

-Wnonblocking-final
A nonblocking assignment is used in a 'final' block, which will have no effect.
```
module m;
    int i;
    final begin
        i <= 1;
    end
endmodule
```

-Wevent-const
An event expression is a constant and so will never change.
```
module m;
    always @(1) begin
    end
endmodule
```

-Wempty-stmt
An extra semicolon in a procedural context implies an empty statement that does nothing.
```
module m;
    initial begin
        ;
    end
endmodule
```

-Wpointless-void-cast
A function call is cast to 'void' but it already returns void so the cast is pointless.
```
module m;
    function void foo; endfunction
    initial begin
        void'(foo());
    end
endmodule
```

-Wunused-result
A non-void function is invoked without inspecting its return value. Capture the result
or cast the call to 'void' to suppress the warning.
```
module m;
    function int foo; return 1; endfunction
    initial begin
        foo();
    end
endmodule
```

-Wdup-import
A given scope contains more than one import statement for the same package and name.
```
package p;
    int i;
endpackage

module m;
    import p::i;
    import p::i;
endmodule
```

-Wfinish-num
The $finish control task accepts a "finish number" of 0, 1, or 2 as its first argument.
The actual call to $finish in this case passed something other than one of those values.
```
module m;
    initial $finish("Hello");
endmodule
```

-Wmissing-format
A string formatting function has a lone '%%' at the end of the format string,
implying that the rest of the specifier is missing. If a literal '%%' is intended
in the output, use the standard '%%%' to achieve that.
```
module m;
    initial $display("Hello World %");
endmodule
```

-Wreversed-range
An open range with constant bounds is reversed (i.e. has a larger left-hand side compared to its right).
Such a range will behave as if it's empty and therefore never be selected.
```
class C;
    rand bit [4:0] a;
    constraint a_c {
        a dist { 16 :/ 1, [15:1] :/ 1};
    }
endclass
```

-Wduplicate-defparam
More than one defparam targets the same parameter. The LRM specifies that this is undefined
behavior. slang takes the value from the first defparam it sees and ignores the rest.
```
module m;
    parameter p = 1;
endmodule

module n;
    defparam m1.p = 3;
endmodule

module top;
    m m1();
    n n1();
    defparam m1.p = 2;
endmodule
```

-Wmultibit-edge
A timing control edge expression (posedge, negedge, etc) is wider than one bit,
which can indicate a mistake since only changes to the first bit will trigger the edge.
```
module m;
    int i;
    always @(posedge i) begin end
endmodule
```

-Wuseless-cast
An explicit cast converts an expression to the same type, so the cast does nothing.
```
module m;
    int i, j;
    assign i = int'(j);
endmodule
```

-Wunsigned-arith-shift
An arithmetic right shift of an unsigned integral type will always shift in zeros, which can be
confusing since typically this operator is used to shift in the value of the most significant bit.
If this is intended behavior use the logical right shift operator which does the same.
```
function bit[31:0] f1(int unsigned i);
    return i >>> 5;
endfunction
```

-Wsigned-logical-shift
A logical right shift of a signed integral type shifts in zeros regardless of the sign of the
operand, which may not be intended. If the value could be negative, consider using the arithmetic
right shift operator `>>>` which will shift in the sign bit instead.
```
function automatic int f1(int i);
    return i >> 5;
endfunction
```

-Wshift-count-overflow
The shift count is a constant that is greater than or equal to the bit width of the
left-hand operand. Shifting by this amount always produces zero (for left shifts or logical
right shifts) or all ones (for arithmetic right shifts of negative values), which is almost
certainly not the intended behavior.
```
module m;
    logic [2:0] v;
    logic [3:0] result;
    initial result = v << 4;
endmodule
```

-Wshift-count-negative
The shift count is a constant negative value. In SystemVerilog the shift amount is always
treated as an unsigned number, so a negative shift amount is interpreted as a very large
positive number, which will shift out all bits of the operand.
```
module m;
    int v;
    int result;
    initial result = v << -1;
endmodule
```

-Wdivide-by-zero
The right-hand side of a division or modulo operation is a compile-time constant with
value zero. Integer division by zero in SystemVerilog produces an X result, and floating
point division by zero produces infinity, both of which are almost certainly unintended.
```
module m;
    int result;
    initial result = 10 / 0;
endmodule
```

-Winc-dec-bit
An increment or decrement operator is applied to a 1-bit operand. The result always wraps around
and is likely not what was intended (e.g. incrementing a `bit` from 0 gives 1, but incrementing
from 1 wraps back to 0).
```
module m;
    bit b;
    initial b++;
endmodule
```

-Wstatic-init-value
A static variable's initializer expression refers to an uninitialized variable, a net, a port,
or a modport member, which won't have a value assigned by the time the initializer runs. The variable
therefore will always be initialized to the default value.
```
module m(input i);
    logic j = i;
endmodule
```

-Winit-self
A variable's initializer expression refers to the variable itself, which is uninitialized at
that point and will always read as the default value (i.e. `x` or zero). References in unevaluated
contexts (such as the argument to `$bits`) are not flagged.
```
module m;
    int i = i;
    int j = j + 1;
endmodule
```

-Wstatic-init-order
A static variable's initializer refers to another variable that does not have a defined order
of initialization relative to the first. This means that the initialization may or may not work
as expected depending on how the tool chooses to schedule the initializers.
```
package p;
    int i = 1;
endpackage

module m;
    import p::i;
    int j = i;
endmodule
```

-Wbitwise-rel-precedence
Identifies a bitwise operator used in a relational expression without parentheses,
which can indicate a mistake in the intended order of operations.
```
module m;
    int unsigned flags;
    initial begin
        if (flags & 'h1 == 'h1) begin end
    end
endmodule
```

-Warith-in-shift
Identifies an arithmetic operator used in a shift expression, which can
indicate a mistake in the intended order of operations.
```
module m;
    logic a;
    initial begin
        if (a << 1 + 1) begin end
    end
endmodule
```

-Wlogical-not-parentheses
Identifies a logical not operator used without parentheses around the operand,
followed by a comparison operator. This can indicate a mistake in the intended
order of operations.
```
module m;
    int a, b;
    initial begin
        if (!a < b) begin end
    end
endmodule
```

-Wbitwise-op-parentheses
Identifies a mix of bitwise operators with different levels of precedence without
any parentheses, which can indicate a mistake in the intended order of operations.
```
module m;
    logic a, b, c;
    initial begin
        if (a & b | c) begin end
    end
endmodule
```

-Wlogical-op-parentheses
Identifies a mix of logical operators with different levels of precedence without
any parentheses, which can indicate a mistake in the intended order of operations.
```
module m;
    logic a, b, c;
    initial begin
        if (a || b && c) begin end
    end
endmodule
```

-Wconditional-precedence
Identifies a conditional expression mixed with a binary expression in way that
suggests a different intended order of operations.
```
module m;
    logic a, b;
    initial begin
        if ((a + b ? 1 : 2) == 2) begin end
    end
endmodule
```

-Wconsecutive-comparison
Identifies a sequence of comparison operators that suggest an incorrect notion
of how the comparisons will be evaluated.
```
module m;
    logic a, b, c;
    initial begin
        if (a < b < c) begin end
    end
endmodule
```

-Wseq-no-match
Warns about a sequence expression that can never be matched.
```
module top(input clk);
    assert property (@(posedge clk) (1'b1 ##1 1'b0) intersect (1'b1[*0] ##2 1'b1));
endmodule
```

-Winferred-latch
A signal assigned in an always_comb procedure is not assigned on all control
paths and so infers a latch instead of combinatorial logic.
```
module m(input logic a, output logic b);
    always_comb begin
        if (a)
            b = 0;
    end
endmodule
```

-Winferred-comb
A signal assigned in an always_latch is assigned on all control paths and
so infers combinational logic instead of a latch.
```
module m(input logic a, output logic b);
    always_latch begin
        b = a;
    end
endmodule
```

-Wmissing-return
A non-void function has no return statements and does not
assign to its return value variable.
```
function int foo;
endfunction
```

-Wincomplete-return
A non-void function has return statements or assigns to its
return value variable but does not do so on all control paths
through the function.
```
function int foo(input a);
    if (a) begin
        return 1;
    end
endfunction
```

-Wfork-loop-var
A variable declared as a `for` or `foreach` loop variable is referenced inside a
fork-join_none or fork-join_any block. Since those block types allow the parent
thread to continue running before all spawned threads finish, the loop variable
may have advanced to a new value by the time a spawned thread reads it. All
iterations of the loop will typically end up sharing the final value of the
variable instead of the value at the time the thread was spawned.
\n\n
The fix is to capture the loop variable's value into a local automatic variable
declared at the start of the fork block, so that each spawned thread gets its
own copy of the value.
```
module m;
    task automatic do_something(int x); endtask

    initial begin
        // BAD: all threads will see the same final value of i
        for (int i = 0; i < 4; i++) begin
            fork
                do_something(i);
            join_none
        end

        // GOOD: capture current value into an automatic variable
        for (int i = 0; i < 4; i++) begin
            fork
                automatic int inst = i;
                do_something(inst);
            join_none
        end
    end
endmodule
```

-Wloop-var-modify
A `for` loop has a step expression that increments or decrements a variable, and
that same variable is also modified inside the loop body. This usually indicates
an unintentional double-step of the loop variable, which could cause incorrect
iteration counts, skipped values, or infinite loops.
```
module m;
    initial begin
        for (int i = 0; i < 10; i++) begin
            i++;
        end
    end
endmodule
```

-Wloop-cond-not-modified
None of the variables that appear in the condition (stop expression) of a `for`
loop are modified by either the loop's step expressions or its body. When no
condition variable can change, the loop will either run forever or never execute
at all (depending on the initial value of the variables).
\n\n
Note: the warning is suppressed when at least one condition variable is modified
elsewhere in the loop, because the condition can still change in that case (for
example, `i < j` where `i` is the counter and `j` is a fixed bound).
```
module m;
    int flag;

    initial begin
        // Neither 'i' nor 'flag' is changed by the step or body,
        // so this loop may run forever.
        for (int i = 0; i < flag; ) begin
        end
    end
endmodule
```

-Wvacuous-cover
A property used in a `cover` statement allows vacuous success,
which can cause confusing coverage results.
```
module m(input clk, a, b);
    cover property (@(posedge clk) a |-> b);
endmodule
```

-Wmulti-write
A variable is written more than once within a single expression, in a way
that has undefined sequencing semantics.
```
module m;
    int i;
    initial begin
        i = ++i + i++;
    end
endmodule
```

-Wread-write
A variable is both read and written within a single expression, in a way
that has undefined sequencing semantics.
```
module m;
    int i, j;
    initial begin
        j = i + ++i;
    end
endmodule
```

-Wshadow-value
A declaration of a value (net, variable, etc) shadows another value declaration with
the same name in an outer scope. This can lead to subtle bugs where the programmer
intends to reference the outer declaration but unintentionally references the
inner (shadowing) one instead.
```
int unitVar;

module m;
    int x;
    function automatic int f(int x);  // shadows m.x
        return x;
    endfunction

    initial begin
        int unitVar;  // shadows $unit::unitVar
        unitVar = 1;
    end
endmodule
```

-Wshadow-hierarchy
A declaration shadows another declaration with the same name in an outer scope, where either
declaration is a named element of the hierarchy (generate block, task, function, etc).
This can lead to subtle bugs where the programmer intends to reference the outer declaration
but unintentionally references the inner (shadowing) one instead.
```
module m;
    if (1) begin : gen
        initial begin : gen  // shadows m.gen
        end

        initial begin
            int gen;  // shadows m.gen.gen
        end
    end
endmodule
```

-Wshadow-property
A class property declaration shadows a property with the same name declared in a base class.
This can lead to subtle bugs where the programmer intends to reference the base class property
but unintentionally references the derived class property instead.
```
class Base;
    int x;
endclass

class Derived extends Base;
    int x;  // shadows Base::x
endclass
```

-Wrandomize-var-shadow
An identifier used inside a `randomize()` 'with' constraint block resolves to a member of
the class being randomized, but a variable with the same name also exists in an enclosing
scope. This is a frequent source of subtle bugs where the programmer intended to reference
the outer variable but unintentionally references the class member instead.
Use the `local::` prefix to explicitly reference the variable from the enclosing scope,
or the `this.` prefix to indicate the intention to use the class member.
```
class A;
    rand int x;
    rand int y;
endclass

class B;
    function void f();
        A a;
        int y = 5;
        // 'y' below refers to A::y, not the local 'y'.
        // Use 'local::y' to reference the local variable.
        a.randomize() with { x == y; };
    endfunction
endclass
```

-Wconstraint-func-cycle
When a `rand` (or `randc`) variable appears as an argument to a user-defined function call
inside a constraint expression, it gains a higher implicit solve priority than any `rand`
variable that appears as a non-argument in the same expression. A diagnostic is issued when
this implicit ordering produces a cycle across the constraint blocks of a class, since the
solver cannot satisfy a circular solve-before relationship.
\n\n
If possible, break the cycle by restructuring the constraints to avoid passing a `rand`
variable as a function argument while another variable in the same expression also contributes
an ordering back to it. Note that there may not actually be a cycle at runtime when the
constraints are evaluated if some of the constraints are disabled dynamically via a
call to `constraint_mode` or `rand_mode`.
```
class C;
    rand int x, y;
    function int F(int a); return a; endfunction
    function int G(int a); return a; endfunction
    // F(y) gives y higher priority than x (y must be solved before x).
    // G(x) gives x higher priority than y (x must be solved before y).
    // These two orderings form a cycle.
    constraint C1 { x <= F(y); }
    constraint C2 { y <= G(x); }
endclass
```

-Wconstraint-solve-cycle
An explicit `solve...before` directive, or a combination of such directives, creates a
circular solve ordering.
\n\n
Restructure the constraints to remove the circular ordering. Note that there may not
actually be a cycle at runtime if some of the constraints are disabled dynamically via a
call to `constraint_mode` or `rand_mode`.
```
class C;
    rand int x, y;
    // x must be solved before y, and y must be solved before x -- a cycle.
    constraint C1 { solve x before y; }
    constraint C2 { solve y before x; }
endclass
```

-Wbits-of-integer-constant
$bits applied to a parameter with a simple integer or scalar type always returns
the fixed width of that type, not a value derived from the parameter itself.
For example, `$bits(P)` where P is `parameter int` always returns 32.
The intention here is often to instead use the parameter directly, or use $clog2().
```
module m;
    parameter int max_value = 10;
    logic[$bits(max_value+1)-1:0] value;

    logic[$clog2(max_value+1)-1:0] value;
endmodule
```

-Wdynamic-cast-const
A dynamic `$cast` call has a statically known result — it will always succeed or always
fail regardless of any runtime state.
\n\n
If the cast always succeeds, you can replace it with a direct assignment or static cast instead.
If it always fails, the cast is useless and can be removed.
```
class A;
endclass

class B extends A;
endclass

class C;
endclass

module m;
    int i;
    real r;
    A a;
    B b;
    C c;

    initial begin
        $cast(a, b);            // always succeeds: B is a subtype of A
        if ($cast(i, r)) begin end  // always succeeds: non-class static conversion
        $cast(a, c);            // always fails: A and C are unrelated
    end
endmodule
```

@category Compatibility

-Wdpi-spec
Old-style "DPI" specified subroutines are deprecated and not supported by slang.
Use the new-style "DPI-C" which has a well-defined standardized calling convention.
```
import "DPI" function void foo();
```

-Wexplicit-static
static variables declared locally to a procedural block that contain an initializer require
that the 'static' keyword be explicitly provided (and not just inferred from context) to
clarify that the initialization happens only once. Most tools don't enforce this rule,
so this is just a warning instead of an error.
```
module m;
    initial begin
        int i = 1;
    end
endmodule
```

-Wlifetime-prototype
Lifetime specifiers are not allowed on method prototype declarations but some
tools allow it as an extension.
```
class C;
    extern function automatic void foo;
endclass

function automatic void C::foo;
endfunction
```

-Wsplit-distweight-op
Some tools allow the dist weight operators to be split instead of a single token.
slang will issue this warning as an error by default but it can be downgraded for compatibility.
```
class c;
  rand int val;
  constraint cst_sum {
    val dist {1 :    = 10, 4 :   / 20};
  }
endclass
```

-Windex-oob
An out-of-bounds value was used to index an array. This is an error by default but can be downgraded to
a warning for compatibility with other tools.
```
logic [7:0] a;
logic b = a[9];
```

-Wrange-oob
An out-of-bounds range was used to select from an array. This is an error by default but can be downgraded to
a warning for compatibility with other tools.
```
logic [7:0] a;
logic [2:0] b = a[9:7];
```

-Wrange-width-oob
An indexed part-select has a width that is wider than the bounds of the array it is selecting. This is an error
by default but can be downgraded to a warning for compatibility with other tools.
```
logic [1:0] a;
int b;
logic [2:0] c = a[b+:3];
```

-Wduplicate-definition
A module has been defined using the same name as a previously defined module. This is an error
by default but can be downgraded to a warning for compatibility with other tools.
This applies to both top level modules as well as nested modules (but only duplicated nested modules within the same scope,
as it is OK to have modules with the same name in different scopes).
```
module a;
endmodule;

module a;
endmodule
```

-Wspecify-param
The LRM disallows using parameters inside of specify blocks. Most tools allow this with
a warning so slang makes it a warning as well.
```
module m(input [1:0] a, output [1:0] b);
    parameter p = 1;
    specify
        (a[p] => b[0]) = 1;
    endspecify
endmodule
```

-Wdup-timing-path
More than one specify timing path was given for a particular pair of input and output
terminals in a module.
```
module m(input a, output b);
    specify
        (a => b) = 1;
        (a => b) = 2;
    endspecify
endmodule
```

-Winvalid-pulsestyle
A `pulsestyle` or `showcancelled` declaration targets an output terminal that has
previously been used in a timing path declaration, which is not allowed according to the LRM.
```
module m(input a, output b);
    specify
        (a => b) = 1;
        pulsestyle_ondetect b;
    endspecify
endmodule
```

-Wnegative-timing-limit
A system timing check parameter that should be positive has a negative value.
```
module m(input a, b);
    specify
        $setup(posedge a, b, -1);
    endspecify
endmodule
```

-Wbad-procedural-force
According to the Verilog/SystemVerilog standard, it is illegal to procedurally force a
bit-select or range select of a variable (you can do that with a net, or with a plain
variable). It is an error by default, but can be turned into a warning, to support code
compatibility with commercial tools that accept this illegal code.
```
module m;
    reg [1:0]r;
    initial
        force r[0] = 1'b0;
endmodule
```

-Wimplicit-port-type-mismatch
An implicit named port connection is made between two inequivalent types. Unlike with a normal
port connection, where the type of the connection undergoes implicit conversion, the LRM specifies
that this case is an error. slang makes this an error by default but it can be turned into a warning,
to support code compatibility with commercial tools.
```
module m(logic p);
endmodule

module n;
    wire [3:0] p;
    m m1(.p);
endmodule
```

-Wdpi-pure-task
A DPI import task is marked 'pure', which is disallowed by SystemVerilog but can be
downgraded to a warning to support code compatibility with other tools.
```
import "DPI-C" pure task func(logic [3:0] a);
```

-Wspecify-condition-expr
State-dependent path conditions in specify blocks are restricted to a subset of expression
types and operators (see Table 30-1 in the LRM for the list of valid operators). This is an
error by default but can be downgraded to a warning for compatibility with other tools.
```
module m(input b, output c);
    wire integer a;
    specify
        if (a === 1 + 1) (b => c) = (0,0);
    endspecify
endmodule
```

-Wunknown-sys-name
An unknown system task or function is called. This is an error by default but can
be downgraded to allow analyzing code using special system names defined by other tools.
```
module m;
    always_comb begin
        if (!$somename) begin end
    end
endmodule
```

-Wunsized-concat
An unsized type is used in a concatenation. This is not allowed in SystemVerilog
but most tools allow it anyway as an extension.
```
longint i = {1, 2};
```

-Wenum-range
An enum member is specified as a range with values that are not integer literals.
The LRM does not allow other constant expressions to be used here.
```
localparam int i = 1;
typedef enum { A[i:3] } e_t;
```

-Wnested-solve-before
A `solve before` constraint is nested inside another constraint. This is not allowed in
SystemVerilog but can be downgraded to a warning for compatibility with other tools.
```
class A;
    int arr[3];
    rand int a, b;
    constraint C {
        foreach (arr[i]) solve a before b;
    }
endclass
```

-Wdynamic-non-procedural
A member or element of a dynamic type is accessed outside of a procedural context (such as in
a continuous assignment). This is not allowed in SystemVerilog but can be downgraded to a
warning for compatibility with other tools.
```
module m;
    int a[];
    assign i = a[3];
endmodule
```

-Wnonstandard-string-concat
String concatenation using the `+` operator is not part of the SystemVerilog standard but is
supported by some commercial tools. This warning is issued when `+` or `+=` is used to
concatenate strings.
```
module m;
    function automatic string foo();
        string a = "hello";
        a += " world";
        return a;
    endfunction
endmodule
```

-Wnested-comment
Nested block comments are not allowed in SystemVerilog but most tools ignore them and
just include them as part of the containing comment block. Note that the opening characters
are simply skipped, meaning the next closing comment sequence will end the containing block instead.
```
/* foo /* bar */
module m;
endmodule
```

-Wmixed-var-assigns
A mix of procedural and continuous assignments are applied to the same variable (or longest static
prefix of a variable). This is not allowed in SystemVerilog but can be downgraded to a warning for
compatibility with other tools.
```
module m;
    int i;
    assign i = 1;
    initial i = 2;
endmodule
```

-Wmultiple-cont-assigns
Multiple continuous assignments are applied to the same variable (or longest static
prefix of a variable). This is not allowed in SystemVerilog but can be downgraded to a warning for
compatibility with other tools.
```
module m;
    int i;
    assign i = 1;
    assign i = 2;
endmodule
```

-Wmultiple-always-assigns
Multiple always_comb/latch/ff blocks assign to the same variable (or longest static
prefix of a variable). This is not allowed in SystemVerilog but can be downgraded to a warning for
compatibility with other tools.
```
module m;
    int i;
    always_comb i = 1;
    always_comb i = 2;
endmodule
```

-Wmisplaced-trailing-separator
A trailing separator (comma or semicolon) was found in a list where it is not
allowed by the SystemVerilog standard. This is an error by default but can be
downgraded to a warning for compatibility with tools like Yosys.
```
module m(input a, output b,);
endmodule
```

-Wqualifiers-on-out-of-block
Out-of-block method definitions are not allowed to include qualifiers (such as the `static` keyword).
This is an error by default but can be downgraded to a warning for compatibility with other tools.
```
module memMod();
    class C;
        extern static function int f();
    endclass

    static function int C::f();
      f = 10;
    endfunction
endmodule
```

-Winitializer-required
A variable declared in a `for` loop initializer does not have an initializer expression. SystemVerilog
requires that such variables be initialized at the point of declaration.
This is an error by default but can be downgraded to a warning for compatibility with other tools.
```
module m;
    initial begin
        for (int i; i < 4; i++) begin
        end
    end
endmodule
```

-Wpackage-import-in-class
A package import declaration was found inside a class body. This is not allowed by the SystemVerilog
LRM but is supported by some tools. In VCS compatibility mode this is a warning; otherwise it is an
error that can be downgraded to a warning.
```
package p;
  int x;
endpackage
class c;
  import p::*;
endclass
```

-Wmember-impl-not-found
A class has the declaration for a member method, but the implementation of that member method is not
found either in the class or as an out of body definition.
This is an error by default but can be downgraded to a warning for compatibility with other tools.
```
module m;
class c;
   extern function int f();
endclass

endmodule
```

-Wforeach-call-expr
The array expression in a foreach loop must be a hierarchical name, not a
function call or other arbitrary expression. This is not allowed by the
SystemVerilog LRM but is supported by some tools. In VCS compatibility mode
this is ignored; otherwise it is an error that can be downgraded to a warning.
```
module top;
    typedef int Arr[4];
    function automatic Arr get_arr(); endfunction
    initial begin
        foreach (get_arr()[i]) begin end
    end
endmodule
```

-Wnonstandard-inside
Using 'inside' without braces around the value list is non-standard, but some tools
allow it as an extension. Standard syntax requires braces around the range list.
```
module m;
    int x;
    int arr[3];
    int result = x inside arr;
endmodule
```

-Wnonstandard-hierarchical-cross
Hierarchical (dotted) references in cover cross items are not part of the
SystemVerilog standard but are supported by some commercial tools.
The implicit coverpoint created from the reference will be named by replacing
dots with underscores (e.g. `status.mpp` becomes `status_mpp`).
```
module m;
    struct packed {
        logic [1:0] mpp;
        logic [1:0] mode;
    } status;

    covergroup cg;
        cross status.mpp, status.mode;
    endgroup
endmodule
```

-Wnonstandard-bare-assoc-pattern
The LRM requires associative array literals to use the apostrophe prefix before the
opening brace, but some tools allow omitting it (like with normal concatenation syntax) as well.
```
module m;
   string s[int];
   function void f();
       s = {0: "sv1", 1: "sv2"};
   endfunction
endmodule
```

-Wnonstandard-constraint-block
The LRM only permits a braced constraint block (`constraint_set`) as the body of a
`foreach`, `if`, or `else` constraint expression. Using one directly as a top-level
`constraint_block_item` is non-standard. This pattern commonly arises when a macro passes
a constraint block including its outer braces as an argument. Some tools accept it anyway,
so the error can be downgraded for compatibility.
```
class my_vseq;
    rand int x;
    constraint c { { x inside {0, 1}; } }
endclass
```

-Wliteral-leading-underscore
Vector literals are not allowed to have leading underscores in their digits but some
tools allow them anyway, so the error can be downgraded for compatibility.
```
module m;
    logic [7:0] a = 8'h_ff;
endmodule
```

-Wref-arg-automatic
`ref` arguments are only allowed to be used in `automatic` subroutines, but some tools
allow them with `static` subroutines anyway, so the error can be downgraded for compatibility.
Note that tasks and functions are static by default if otherwise unmarked; it is preferable
to mark them `automatic` rather than disable this error.
```
function void foo(ref int i);
endfunction
```

-Wstring-int-concat
String concatenations can only accept `string` typed operands and string literals.
Some tools allow integer operands as well, implicitly converting them to strings,
so this error can be downgraded for compatibility.
```
module m;
    string s;
    int i;
    initial begin
        s = {s, i};
    end
endmodule
```

-Wrange-select-reversed
The ordering of a range select (ascending or descending) does not match the direction of
the dimensions of the type being selected. Most tools error on this, but some allow it
so the error can be downgraded for compatibility.
```
module m;
    logic [63:0] a;
    int b;
    initial begin
        b = a[3:7];
    end
endmodule
```

-Wformat-empty-arg
An empty argument (produced by a trailing or stray comma) was passed to a string
formatting function in a position where the format string expects a value. Some tools
accept this and substitute a blank, so the diagnostic is a suppressible warning.
```
module m;
    string s;
    int x = 5;
    initial s = $sformatf("value=%0d", );
endmodule
```

-Wformat-too-many-args
More arguments were provided to a string formatting function than the format string
consumed. Some tools accept this and silently ignore the extra arguments, so the
diagnostic is a suppressible warning.
```
module m;
    string s;
    int x = 5;
    initial s = $sformatf("value=%0d", x, x);
endmodule
```

-Wclockvar-target-assign
The LRM explicitly prohibits writing to a variable with a continuous assignment when
it is associated with an output clockvar. Some tools accept this construct with a warning,
so the error can be downgraded for compatibility.
```
module m(input clk);
    int j;
    assign j = 1;
    clocking cb @(posedge clk);
        output j;
    endclocking
endmodule
```

-Wcross-ident-in-binsof
The LRM defines `bins_expression` as either a `variable_identifier` or a
`cover_point_identifier` with an optional `bin_identifier`; a cross identifier is not a
valid `bins_expression` argument to `binsof()`. Some tools accept it anyway, so the error
can be downgraded for compatibility.
```
module m;
    logic clk, a, b;
    covergroup cg @(posedge clk);
        cp_a : coverpoint a { bins zero = {0}; bins one = {1}; }
        cp_b : coverpoint b { bins zero = {0}; bins one = {1}; }
        cp_cross : cross cp_a, cp_b;
        cp_nested : cross cp_cross, cp_b {
            bins c = binsof(cp_cross);
        }
    endgroup
    cg cg_inst = new();
endmodule
```

-Wref-arg-in-fork-join
The LRM prohibits referencing a 'ref' argument inside a fork-join_any or
fork-join_none block. Some tools allow this anyway, so the error can be
downgraded for compatibility.
```
task automatic run(ref bit flag);
  fork
    begin
      wait(flag == 1);
    end
  join_any
endtask
```

-Wcannot-index-scalar
The LRM does not define a bit-select on a scalar (single-bit) type. Some tools
allow this as an extension, treating the result as the scalar's element type,
so the error can be downgraded for compatibility.
```
module m;
  bit flag;
  int i = 0;
  initial if (flag[i]) $display("set");
endmodule
```

-Wundefined-param-override
The LRM does not define the behavior when a named parameter override refers to a
parameter that does not exist in the instantiated module. Some vendor tools
issue only a warning and silently ignore the override, so the error can be
downgraded for compatibility.
```
module bot(input clk);
  parameter TYPE = 0;
endmodule

module top;
  bot #(.TYPE(1), .WIDTH(1)) b(clk);  // WIDTH does not exist in bot
endmodule
```

-Wvirtual-arg-name-mismatch
The LRM requires virtual method overrides to use identical argument names to
their superclass declaration. Some tools issue only a warning for this mismatch,
so the error can be downgraded for compatibility.
```
class Base;
  virtual task run(int count);
  endtask
endclass
class Derived extends Base;
  virtual task run(int n);  // 'n' != 'count'
  endtask
endclass
```

-Wredefinition
The LRM requires every identifier in a scope to have a unique definition.
Some tools issue only a warning when a name is declared more than once in the
same scope, so the error can be downgraded for compatibility.
```
module m;
  int i;
  int i;  // duplicate declaration
endmodule
```

-Wredefinition-different-type
The LRM requires every identifier in a scope to have a unique definition.
Some tools issue only a warning when a name is re-declared with a different type
in the same scope, so the error can be downgraded for compatibility.
```
module m;
  int i;
  bit [3:0] i;  // redeclared with a different type
endmodule
```

-Wstring-in-constraint
The LRM does not permit string sub-expressions in constraint expressions.
Some tools accept string equality comparisons inside constraint if-conditions as an extension.
 The error can be downgraded for compatibility.
```
class RegField;
  rand logic [7:0] value;
  string name_str;
  function string get_name(); return name_str; endfunction
  constraint c_by_name {
    if (get_name() == "special") value inside {[1:10]};
  }
endclass
```

@category Macros

-Wignored-macro-paste
Points out macro concatenation tokens that aren't actually concatenating anything due
to whitespace on either side, or tokens that can't be concatenated in the first place.
```
`define FOO(a) a `` +
int foo;
int bar = `FOO(foo) foo;
```

-Wredef-macro
Issued for redefining a macro name with a different body.
```
`define FOO 1
`define FOO 2
```

-Wheader-guard
Issued when a source file starts with an `ifndef that looks like a header guard
but the immediately following `define uses a different macro name, possibly due
to a typo or copy-paste error.
```
`ifndef MY_HEADER_H
`define MY_OTHER_HEADER_H
// ...
`endif
```

@category Pragmas

-Wunknown-pragma
Issued for an unknown pragma directive.
```
`pragma foo
```

-Wextra-pragma-args
Issued for a pragma directive that specifies more arguments than expected.
```
`pragma resetall extraarg
```

-Wexpected-diag-arg
Issued for a pragma diagnostic directive that is missing an argument.
```
`pragma diagnostic
```

-Wunknown-diag-arg
Issued for an unknown argument given to a pragma diagnostic directive.
```
`pragma diagnostic pushh
```

-Wpragma-diag-level
Issued for a malformed diagnostic pragma. A severity code was expected
where the given location is indicated.
```
`pragma diagnostic foo=3'd3
```

-Wexpected-protect-keyword
A `pragma protect directive is missing the protect keyword to set.
```
`pragma protect
```

-Wunknown-protect-keyword
A `pragma protect directive specified an unknown keyword.
```
`pragma protect foobar
```

-Wexpected-protect-arg
An invalid argument is passed to a `pragma protect keyword expecting a string value.
```
`pragma protect author=3
```

-Wnested-protect-begin
Nested `pragma protect begin directives were found, which is disallowed.
```
`pragma protect begin
`pragma protect begin
```

-Wextra-protect-end
An unpair `pragma protect end or end_protected was found in the source text.
```
`pragma protect end
```

-Wprotect-arglist
A `pragma protect keyword expected a list of key=value options but did not receive them.
```
`pragma protect encoding=3
```

-Wunknown-protect-encoding
The specified encoding name in a `pragma protect encoding directive is not known or supported.
slang will try to work with the encoded data as though it were raw, which may or may not parse
correctly depending on how the actual encoding functions.
```
`pragma protect encoding=(enctype="foobar")
```

-Wunknown-protect-option
An unknown key=value option was passed to a `pragma protect keyword.
```
`pragma protect encoding=(enctype="base64", foo="bar")
```

-Winvalid-pragma-number
A `pragma protect option expected a valid 32-bit integer value but received something else instead.
```
`pragma protect encoding=(enctype="base64", line_length="hello")
```

-Winvalid-pragma-viewport
A `pragma protect viewport directive was given invalid options. All such directives must be of
the form (object = &lt;string>, access = &lt;string>)
```
`pragma protect viewport=(not_object = "hello")
```

-Wprotect-encoding-bytes
An encoded block in a protected envelope differed in size from what was specified in
a prior encoding pragma directive.
```
`pragma protect begin_protected
`pragma protect encoding=(enctype="base64", bytes=6), data_public_key
asdfas==
`pragma protect end_protected
```

-Winvalid-encoding-byte
A character in an encoded protected envelope is invalid for the kind of encoding specified.
The rest of the protected envelope will be skipped by searching for an end pragma.
```
`pragma protect begin_protected
`pragma protect encoding=(enctype="base64"), data_block
asdf()0123
`pragma protect end_protected
```

-Wraw-protect-eof
A "raw" encoded protected envelope did not terminate before the end of the source file.
```
`pragma protect encoding=(enctype="raw"), data_block
asdfasdf
```

-Wprotected-envelope
Any use of a pragma protect region in the source will trigger this warning, as slang is
unable to actually decrypt the contents of that region (it is assumed that no IP vendor
would be willing to share decryption keys with an open source tool anyway). The text will
be decoded and skipped in its entirety, which may or may not result in a valid design.
```
`pragma protect begin_protected
`pragma protect encoding=(enctype="raw"), data_block
asdfasdf
`pragma protect end_protected
```

@category Pedantic

-Wnonstandard-escape-code
Detects use of '\\\%' in string literals. This is not a real escape code
but other tools silently allow it anyway.
```
string s = "Hello World\%";
```

-Wnonstandard-generate
Indicates a standalone generate block (begin / end pair) without a corresponding
generate loop or condition. This was allowed in older Verilog standards but
is no longer allowed in SystemVerilog.
```
module m;
    begin : gen_block
        int i = 1;
    end
endmodule
```

-Wempty-pattern
Issued for empty assignment pattern literals, which are not allowed by
SystemVerilog but are supported by some tools.
```
int foo[] = '{};
```

-Wnonstandard-foreach
foreach loops are not allowed to have multidimensional brackets when declaring
loop variables, but most tools allow it as an extension.
```
module top;
    int array[8][8];
    initial begin
        foreach (array[i]) begin
            foreach (array[i][j]) begin
                array[i][j] = i * j;
            end
        end
    end
endmodule
```

-Wnonstandard-dist
'dist' constraint items are technically not allowed to be surrounded by parentheses according
to the language grammar, but most tools allow it as an extension.
```
class C;
    rand bit a;
    rand bit [3:0] b;
    constraint cmd_c {
        a -> (b dist { 0 := 1, [1:15] := 1});
    }
endclass
```

-Wimplicit-net-port
A net port that elides its net type occurs in a context where `default_nettype is set to 'none'.
This technically should be an error but it makes the use of 'none' as a default nettype very
annoying and most tools just default to a wire in this case.
```
`default_nettype none

module m(input i);
endmodule
```

-Wudp-coverage
A user-defined primitive is edge sensitive but does not provide an output value
for all possible edges of all inputs. This is not necessarily wrong; the default
output value when given unspecified input combinations is 'x', but the LRM mentions
this constraint in section 29.6 so this warning can be used if you wish to be pedantic.
Additionally, it can be useful for checking for missed transitions when developing and
simulating the behavioral model of industrial cells, which are commonly implemented as
Verilog primitives.
```
primitive d_edge_ff (q, clock, data);
    output q; reg q;
    input clock, data;
    table
        // clock data q q+
        // obtain output on rising edge of clock
        (01) 0 : ? : 0 ;
        (01) 1 : ? : 1 ;
        (0?) 1 : 1 : 1 ;
        (0?) 0 : 0 : 0 ;
        // ignore negative edge of clock
        (?0) ? : ? : - ;
        // missed clock edge (1x) specification
        // missed edge specifications for data signal
    endtable
endprimitive
```

-Wformat-multibit-strength
Formatting multibit nets with the %%v specifier is not allowed in SystemVerilog
but most tools allow it anyway as an extension.
```
module m;
    wire [3:0] w;
    initial $display("%v", w);
endmodule
```

-Wnonstandard-sys-func
Indicates a call to a nonstandard system function. Currently this only applies
to the $psprintf function, which is a synonym for $sformatf.
```
module m;
    initial $psprintf("%d", 42);
endmodule
```

-Wisunbounded-param-arg
The SystemVerilog LRM 1800-2023 requires that the argument to the $isunbounded system
function be a parameter name. This seems needlessly restrictive and conflicts with the
wording in prior versions so this is implemented as a pedantic warning only.
```
localparam p = $isunbounded(1 + 1);
```

-Wnonstandard-randomize
An argument to a scoped randomize call (`std::randomize`) contains accesses rather than simple variables.
```
module m;
    int x[2];
    struct { int y; } s;

    function automatic void test;
        std::randomize(x[0]);
        std::randomize(s.y);
    endfunction
endmodule
```

@category Unused Items

-Wunused-def
A module, interface, or program definition is unused in the design.
\n\n
A definition with name '_' will never warn. Attributes `(* unused *)` or `(* maybe_unused *)`
may be applied to suppress this warning for a particular definition.
```
module m #(parameter int i);
endmodule

module top;
endmodule
```

-Wunused-net
A net is declared but never used.
\n\n
A net with name '_' will never warn. Attributes `(* unused *)` or `(* maybe_unused *)`
may be applied to suppress this warning for a particular net.
```
module m;
    wire w;
endmodule
```

-Wunused-implicit-net
An implicitly created net is not referenced elsewhere in the design.
This is often a typo in the name and not intentional.
\n\n
A net with name '_' will never warn.
```
module m(output x);
    assign x = 1;
endmodule

module n;
    logic typo;
    m m1(typa);
endmodule
```

-Wunused-variable
A variable is declared but never used.
\n\n
A variable with name '_' will never warn. Attributes `(* unused *)` or `(* maybe_unused *)`
may be applied to suppress this warning for a particular variable.
```
module m;
    int i;
endmodule
```

-Wundriven-net
A net is used but never has a value driven.
\n\n
A net with name '_' will never warn. Attributes `(* unused *)` or `(* maybe_unused *)`
may be applied to suppress this warning for a particular net.
```
module m(output x);
    wire w;
    assign x = w;
endmodule
```

-Wunassigned-variable
A variable is used but never has a value assigned.
\n\n
A variable with name '_' will never warn. Attributes `(* unused *)` or `(* maybe_unused *)`
may be applied to suppress this warning for a particular variable.
```
module m;
    int i;
    int j = i;
endmodule
```

-Wunused-but-set-net
A net has a value driven but that value is never used.
\n\n
A net with name '_' will never warn. Attributes `(* unused *)` or `(* maybe_unused *)`
may be applied to suppress this warning for a particular net.
```
module m;
    wire x;
    assign x = 1;
endmodule
```

-Wunused-but-set-variable
A variable has a value assigned but that value is never used.
\n\n
A variable with name '_' will never warn. Attributes `(* unused *)` or `(* maybe_unused *)`
may be applied to suppress this warning for a particular variable.
```
module m;
    int i;
    initial i = 42;
endmodule
```

-Wunused-port
An input port signal is never used internally to the module.
\n\n
A port with name '_' will never warn. Attributes `(* unused *)` or `(* maybe_unused *)`
may be applied to suppress this warning for a particular port.
```
module m(input x);
endmodule
```

-Wundriven-port
An output port signal is never given a value.
\n\n
A port with name '_' will never warn. Attributes `(* unused *)` or `(* maybe_unused *)`
may be applied to suppress this warning for a particular port.
```
module m(output x);
endmodule
```

-Wunused-but-set-port
A port has a value assigned but that value is never used. This only applies to 'inout' ports.
The assumption is that if the port doesn't need to be read, the direction should be changed
to 'output' instead.
\n\n
A port with name '_' will never warn. Attributes `(* unused *)` or `(* maybe_unused *)`
may be applied to suppress this warning for a particular port.
```
module m(inout x);
    assign x = 1;
endmodule
```

-Wunused-argument
A task or function formal argument is not used in its body.
\n\n
An argument with name '_' will never warn. Attributes `(* unused *)` or `(* maybe_unused *)`
may be applied to suppress this warning for a particular argument.
```
function foo(int x);
endfunction
```

-Wunused-parameter
A parameter's value is never used.
\n\n
A parameter with name '_' will never warn. Attributes `(* unused *)` or `(* maybe_unused *)`
may be applied to suppress this warning for a particular parameter.
```
module m #(parameter p = 1);
endmodule
```

-Wunused-type-parameter
A type parameter is never used.
\n\n
A parameter with name '_' will never warn. Attributes `(* unused *)` or `(* maybe_unused *)`
may be applied to suppress this warning for a particular parameter.
```
module m #(parameter type t = int);
endmodule
```

-Wunused-typedef
A typedef is never used.
\n\n
A typedef with name '_' will never warn. Attributes `(* unused *)` or `(* maybe_unused *)`
may be applied to suppress this warning for a particular typedef.
```
module m;
    typedef struct { int a; } foo_t;
endmodule
```

-Wunused-genvar
A genvar is never used.
\n\n
A genvar with name '_' will never warn. Attributes `(* unused *)` or `(* maybe_unused *)`
may be applied to suppress this warning for a particular genvar.
```
module m;
    genvar g;
endmodule
```

-Wunused-assertion-decl
An assertion declaration (sequence, property, or let) is never used.
\n\n
A declaration with name '_' will never warn. Attributes `(* unused *)` or `(* maybe_unused *)`
may be applied to suppress this warning for a particular declaration.
```
module m;
    sequence s;
        1;
    endsequence
endmodule
```

-Wunused-import
A package import directive is never used.
```
package p;
    int a;
endpackage

module m;
    import p::a;
endmodule
```

-Wunused-wildcard-import
A wildcard package import directive is never used.
```
package p;
    int a;
endpackage

module m;
    import p::*;
endmodule
```

-Wunused-class-property
A class property is declared but never used.
```
class C;
    int i;
endclass
```

-Wunused-but-set-property
A class property has a value assigned but that value is never used.
```
class C;
    int i;

    function void foo;
        i = 42;
    endfunction
endclass
```

-Wunassigned-property
A class property is used but never has a value assigned.
```
class C;
    int i;

    function void foo;
        int j = i;
    endfunction
endclass
```

-Wunused-local-class-property
A 'local' (i.e. private) class property is declared but never used.
```
class C;
    local int i;
endclass
```

-Wunused-but-set-local-property
A 'local' (i.e. private) class property has a value assigned but that value is never used.
```
class C;
    local int i;

    function void foo;
        i = 42;
    endfunction
endclass
```

-Wunassigned-local-property
A 'local' (i.e. private) class property is used but never has a value assigned.
```
class C;
    local int i;

    function void foo;
        int j = i;
    endfunction
endclass
```

-Wunused-subroutine
A task or function is declared but never called.
```
function foo;
endfunction
```

-Wunused-dpi-import
A DPI import is declared but never called.
```
import "DPI-C" function void dpi_func(int i);
```

-Wunused-class-method
A class method is declared but never called.
```
class C;
    function void foo;
    endfunction
endclass
```

-Wunused-local-class-method
A 'local' (i.e. private) class method is declared but never called.
```
class C;
    local function void foo;
    endfunction
endclass
```

-Wunused-constructor
A class constructor is declared but never called.
```
class C;
    function new;
    endfunction
endclass
```

-Wunused-package-var
A variable declared in a package is never used.
```
package p;
    int i;
endpackage
```

-Wunused-package-typedef
A typedef declared in a package is never used.
```
package p;
    typedef int I;
endpackage
```

-Wunused-package-parameter
A parameter declared in a package is never used.
```
package p;
    parameter p = 1;
endpackage
```

-Wunused-package-type-parameter
A type parameter declared in a package is never used.
```
package p;
    parameter type p = int;
endpackage
```

-Wunused-package-assertion-decl
An assertion declaration (sequence, property, or let) declared in a package is never used.
```
package p;
    sequence s;
        1;
    endsequence
endpackage
```

-Wunused-package-subroutine
A task or function declared in a package is never used.
```
package p;
    function void foo;
    endfunction
endpackage
```

@category Libraries and Configurations

-Wunknown-library
A configuration library list references an unknown library.
@options --top=cfg
```
config cfg;
    design d;
    default liblist foo;
endconfig

module d;
endmodule
```

-Wdup-config-rule
More than one rule in a configuration targets the same cell or instance. They can't both
be used, so slang takes the first one and ignores all others.
@options --top=cfg
```
module d;
endmodule

config cfg;
    design d;
    instance d.foo use bar;
    instance d.foo use baz;
endconfig
```

-Wunused-config-cell
A configuration cell rule is unused, which may mean that there's a typo in the target name.
@options --top=cfg
```
config cfg;
    design top;
    cell foo liblist l;
endconfig

module top;
endmodule
```

-Wunused-config-instance
A configuration instance rule is unused, which means that target path does not exist in the design.
@options --top=cfg
```
config cfg;
    design top;
    instance top.foo liblist l;
endconfig

module top;
endmodule
```

@category Miscellaneous

-Wwarning-task
A $warning elaboration task was encountered. Its message is printed by this diagnostic.
```
$warning("Hello World!");
```

-Wmissing-top
No valid top-level modules exist in the design. No top has been instantiated.
```
module m #(parameter int i);
endmodule
```

-Wunnamed-generate
A generate block has no user-provided name. This is perfectly valid in SystemVerilog
but many coding standards dictate that generate blocks alwayscbe given a name so this
warning can be used to enforce that.
```
module a;
    parameter L = 0;
    if (L) begin
    end else begin
    end
endmodule

module top;
    for (genvar i = 0; i < 8; i++) begin
        a a_inst();
    end
endmodule
```

-Wnewline-eof
A source file does not end with a newline character. Many coding standards and
editors require files to end with a newline, and some tools may behave
unexpectedly when processing files that do not.
```
module m; endmodule
```

-Wupward-name
An upward hierarchical name reference was found. Upward name references traverse upward
through the instance hierarchy to find the starting scope for the path, which can make
code harder to understand and port since the name can resolve to different things depending
on where its containing module is instantiated in the hierarchy.
```
module child;
    // 'parent' is resolved by walking upward from child's scope
    int x = parent.value;
endmodule

module parent;
    int value = 42;
    child c1();
endmodule
```

-Wunknown-warning-option
<ignored>

-Winvalid-source-encoding
<ignored>
