Skip to content

Commit

Permalink
SE - Nullable: Copy constraints to Value property (#6841)
Browse files Browse the repository at this point in the history
  • Loading branch information
pavel-mikula-sonarsource committed Mar 31, 2023
1 parent a994db8 commit 1b0e653
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,20 @@ internal sealed class PropertyReference : SimpleProcessor<IPropertyReferenceOper
protected override IPropertyReferenceOperationWrapper Convert(IOperation operation) =>
IPropertyReferenceOperationWrapper.FromOperation(operation);

protected override ProgramState Process(SymbolicContext context, IPropertyReferenceOperationWrapper propertyReference) =>
propertyReference.Instance.TrackedSymbol() is { } symbol
? context.SetSymbolConstraint(symbol, ObjectConstraint.NotNull)
: context.State;
protected override ProgramState Process(SymbolicContext context, IPropertyReferenceOperationWrapper propertyReference)
{
if (propertyReference.Instance.TrackedSymbol() is { } symbol)
{
var state = context.State.SetSymbolConstraint(symbol, ObjectConstraint.NotNull);
return propertyReference.Property.Name == "Value" && propertyReference.Instance.Type.IsNullableValueType() && context.State[symbol] is { } value
? state.SetOperationValue(context.Operation, value)
: state;
}
else
{
return context.State;
}
}
}

internal sealed class ArrayElementReference : SimpleProcessor<IArrayElementReferenceOperationWrapper>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* SonarAnalyzer for .NET
* Copyright (C) 2015-2023 SonarSource SA
* mailto: contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using SonarAnalyzer.SymbolicExecution.Constraints;
using SonarAnalyzer.UnitTest.TestFramework.SymbolicExecution;

namespace SonarAnalyzer.UnitTest.SymbolicExecution.Roslyn;

public partial class RoslynSymbolicExecutionTest
{
[TestMethod]
public void Nullable_Assignment_PropagatesConstrainsToValue()
{
const string code = """
bool? value = null;
Tag("Null", value);
value = true;
Tag("True", value);
""";
var validator = SETestContext.CreateCS(code).Validator;
validator.ValidateTag("Null", x => x.HasConstraint(ObjectConstraint.Null).Should().BeTrue());
validator.ValidateTag("True", x => x.HasConstraint(BoolConstraint.True).Should().BeTrue());
}

[TestMethod]
public void Nullable_Value_ReadsConstraintsFromInstance()
{
const string code = """
var value = arg.Value;
Tag("Unknown", value);
arg = true;
value = arg.Value;
Tag("True", value);
arg = false; // This will set additional constraint TestConstraint.First
value = arg.Value;
Tag("FalseFirst", value);
""";
var setter = new PreProcessTestCheck(OperationKind.Literal, x => x.Operation.Instance.ConstantValue.Value is false ? x.SetOperationConstraint(TestConstraint.First) : x.State);
var validator = SETestContext.CreateCS(code, ", bool? arg", setter).Validator;
validator.ValidateTag("Unknown", x => x.Should().BeNull());
validator.ValidateTag("True", x => x.HasConstraint(BoolConstraint.True).Should().BeTrue());
validator.ValidateTag("FalseFirst", x => x.HasConstraint(BoolConstraint.False).Should().BeTrue());
validator.ValidateTag("FalseFirst", x => x.HasConstraint(TestConstraint.First).Should().BeTrue());
}
}

0 comments on commit 1b0e653

Please sign in to comment.