[AssertionMethod] - Warning "expression is always true" for reference types

[Build 5.1.1757]


        class Foo
        {
            private Foo member;
            [AssertionMethod]
            static void AssertTrue([AssertionCondition(AssertionConditionType.IS_TRUE)] bool condition) {}

            public bool IsPositive()
            {
                int val = new Random().Next(-5, 5);
                AssertTrue(val > 0);
                //No warning
                if (val > 0)
                    member = new Foo();

                AssertTrue(member != null);
                //Warning: "Expression is always true"
                if (member != null)
                    return true;
                return false;
            }

        }

Am I missing something here, why do I get the warning on member != null ? What can I do to prevent it or is it a bug?
Thanks.
4 comments
Comment actions Permalink

The key point is that "member" is the field, so we cannot strictly control it's behavior.
With fields, we try to minimize false messages, since we are not 100% sure that field is not updated in background thread.

We can only strictly control local variables (once they are not touched in closure)

0
Comment actions Permalink

But according to what you're saying it's the first assertion method that should generate the warning, since you have control over local variables, not the second one which involves a member, right? And the first method asserts that it always be > 0, thus the if-case should always evaluate to true?

The point is that I use assertion methods for catching "should not happen case" in debug mode. But according to RS this if-guard is not needed since, I assume, RS treats the assert as a throwing method if condition is false (which does not match behavior of the > 0 if-case ?), thus the if-clause is not needed in debug mode.

But in release mode the assert isn't there and I might want to use the if-statement anyhow... So, should the solution for me be that I should remove the AssertionMethod attribute so RS won't think it's a terminating method?

*Edit: Hrm when using

System.Diagnostics.Debug.Assert(member != null);
instead of
AssertTrue(member != null);


The warning isn't showing. Thus there must be some bug with the [AssertionMethod] annotation right? It should behave the same as the System.Diagnostics.Debug.Assert ?
0
Comment actions Permalink

ReSharper Value Analyzsis doen't track "value > 0" and so on... It has only one of the four candidates:
  - value is null
  - value isnot null
  - value is true
  - value is false

Restricted to this, we've maintain time complexity of analyzer in reasonable range.

As for "Debug.Assert" behavior, I'll check it shortly...

0
Comment actions Permalink

Regarding warning for System.Diagnostics.Debug.Assert, it does show up as a warning as well if using default annotations. When one de-select default annotations the warning disappears (which I guess is the expected behavior).

Regarding the behavior for triggering warnings when using assertion methods, i submitted a feature request for this:
http://youtrack.jetbrains.net/issue/RSRP-199221 "Option so [AssertionMethod] logic is not affecting rest of RS code analysis.".

*Edit:  As for the request, it's easy to "fix" by using a custom assertion method, and one probably don't want to ignore all [AssertionMethod] attributes as suggested since e.g. http://youtrack.jetbrains.net/issue/RSRP-61079 is a typical scenario of when the "assertion" method is used in both debug and release builds.

0

Please sign in to leave a comment.