Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix S3236 FP: CallerArgumentExpressionAttribute should be overridable when using Nullable<> #9568

Open
rjgotten opened this issue Jul 30, 2024 · 1 comment
Labels
Area: C# C# rules related issues. Type: False Positive Rule IS triggered when it shouldn't be.

Comments

@rjgotten
Copy link

Description

S3236 is raised in cases where the user passes a caller expression explicitly, and the rule advises against doing this.
However, there are cases wrt the expanded set of 'throw helpers' introduced by Microsoft in later .NET versions where passing a caller expression name explicitly is exactly the right thing to do, such as when having to check for negative value on nullable numeric properties.

Cases like ArgumentOutOfRangeException.ThrowIfNegative when used with nullables must use some form of guarded access to the underlying value to pass to the throw helper, because Nullable<> does not implement the requisite interface and the throw helper is not overloaded to understand Nullable<INumberBase>.

But in this case, the actual parameter that should be reported as in error, should still be the actual nullable numeric property - and not whatever inbetween value is used.

Repro steps

public class Test
{
  private readonly int _amount;
  public int? Amount
  {
     get => _amount;
     init
     {
       if (value is int val)
         // The exception actually *SHOULD* be reported for 'value', not for 'val' or for 'value.Value'
         ArgumentOutOfRangeException.ThrowIfNegative(val, nameof(value));
         
       _amount = value;
     }
  }

Expected behavior

S3236 is not raised in situations that could be identified as explicitly passing the related parameter name to a throw helper.

Actual behavior

S3236 is raised in situations that could be identified as explicitly passing the related parameter name to a throw helper.

Known workarounds

None. Suppress the rule.

Related information

  • C#/VB.NET Plugins version -- whatever ships with SonarLint 8.1.0.95039
  • Visual Studio version -- 17.10.5
  • MSBuild / dotnet version -- dotnet SDK 8.0.303
  • SonarScanner for .NET version (if used) -- N/A
  • Operating System -- Windows 11
@sebastien-marichal
Copy link
Contributor

Hello @rjgotten,

This is indeed quite inconvenient; I confirm this to be a false positive.

I think it is difficult to decide whether it makes sense or not to override caller information arguments.
We would need to add a very specific exception for this scenario:

  • the argument is marked with CallerArgumentExpression attribute
  • the tested variable has been created from a Nullable<>

I am not sure if there could be scenarios where it would produce false negatives.

@sebastien-marichal sebastien-marichal changed the title Fix S3236 FP: Should not be raised where CallerArgumentExpressionAttribute logically SHOULD be passed explicitly Fix S3236 FP: CallerArgumentExpressionAttribute should be overridable when using Nullable<> Aug 5, 2024
@sebastien-marichal sebastien-marichal added Type: False Positive Rule IS triggered when it shouldn't be. Area: C# C# rules related issues. labels Aug 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: C# C# rules related issues. Type: False Positive Rule IS triggered when it shouldn't be.
Projects
None yet
Development

No branches or pull requests

2 participants