Skip to content

Commit

Permalink
S3247: Add repro for #223 (#8259)
Browse files Browse the repository at this point in the history
  • Loading branch information
antonioaversa authored Oct 27, 2023
1 parent b0d5c07 commit c0ca608
Show file tree
Hide file tree
Showing 2 changed files with 197 additions and 60 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,150 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using Person = (string name, string surname);

class MyClass
class WithAliasAnyType
{
void AliasType(Person person)
void ValidCases(Person person)
{
var a = (Person)person; // FN
_ = (Person)person; // Compliant: not a duplicated cast
}

void InvalidCases(object obj)
{
if (obj is Person) // FN: Person is alias for a struct
{
_ = (Person)obj;
}

if (obj is (string, string)) // FN: (string, string) and Person are equivalent
{
_ = (Person)obj;
}

if (obj is Person) // FN: Person and (string, string) are equivalent
{
_ = ((string, string))obj;
}

if (obj is Person) // FN: Person and (string ..., string) are equivalent
{
_ = ((string differentName1, string))obj;
}

if (obj is Person) // FN: Person and (string, string ...) are equivalent
{
_ = ((string, string differentName2))obj;
}

if (obj is (string differentName1, string)) // FN: (string ..., string) and Person are equivalent
{
_ = (Person)obj;
}

if (obj is (string, string differentName2)) // FN: (string, string ...) and Person are equivalent
{
_ = (Person)obj;
}
}
}

// https://github.com/SonarSource/sonar-dotnet/issues/223
class Repro_223
{
void NumericTypes(object obj)
{
if (obj is int) // FN
{
_ = (int)obj;
}

if (obj is double) // FN
{
_ = (double)obj;
}

if (obj is ushort) // FN
{
_ = (ushort)obj;
}
}

void NullableValueTypes(object obj)
{
if (obj is int?) // FN
{
_ = (int?)obj;
}

if (obj is byte?) // FN
{
_ = (byte?)obj;
}
}

void UsingLanguageKeywordAndFrameworkName(object obj)
{
if (obj is Nullable<int>) // FN
{
_ = (int?)obj;
}

if (obj is int?) // FN
{
_ = (Nullable<int>)obj;
}

if (obj is IntPtr) // FN
{
_ = (nint)obj;
}

if (obj is nint) // FN
{
_ = (IntPtr)obj;
}

if (obj is System.UIntPtr) // FN
{
_ = (nuint)obj;
}
}

void Enums(object obj)
{
if (obj is AnEnum) // Noncompliant
{
_ = (AnEnum)obj; // Secondary
}

if (obj is AnEnum?) // FN
{
_ = (AnEnum?)obj;
}
}

void UserDefinedStructs(object obj)
{
if (obj is AStruct) // FN
{
_ = (AStruct)obj;
}

if (obj is ARecordStruct) // FN
{
_ = (ARecordStruct)obj;
}

if (obj is AReadonlyRefStruct) // FN
{
_ = (AStruct)obj;
}
}

enum AnEnum { Value1, Value2 }
struct AStruct { }
record struct ARecordStruct { }
readonly ref struct AReadonlyRefStruct { }
}


Original file line number Diff line number Diff line change
@@ -1,87 +1,84 @@
using System;
using System.Collections.Generic;

namespace Tests.Diagnostics
class Fruit { }

class Program
{
class Fruit { }
private object someField;

class Program
public void Foo(Object x)
{
private object someField;

public void Foo(Object x)
if (x is Fruit) // Noncompliant
{
if (x is Fruit) // Noncompliant
{
var f1 = (Fruit)x;
// ^^^^^^^^ Secondary
var f2 = (Fruit)x;
// ^^^^^^^^ Secondary
}
var f1 = (Fruit)x;
// ^^^^^^^^ Secondary
var f2 = (Fruit)x;
// ^^^^^^^^ Secondary
}

var f = x as Fruit;
if (x != null) // Compliant
{
var f = x as Fruit;
if (x != null) // Compliant
{

}
}
}

public void Bar(object x)
public void Bar(object x)
{
if (!(x is Fruit))
{
if (!(x is Fruit))
{
var f1 = (Fruit)x; // Compliant - but will throw
}
else
{
var f2 = (Fruit)x; // Compliant - should be non compliant
}

var f1 = (Fruit)x; // Compliant - but will throw
}
else
{
var f2 = (Fruit)x; // Compliant - should be non compliant
}

}

public void FooBar(object x)
public void FooBar(object x)
{
if (x is int)
{
if (x is int)
{
var res = (int)x; // Compliant because we are casting to a ValueType
}
var res = (int)x; // Compliant because we are casting to a ValueType
}
}

// See https://github.com/SonarSource/sonar-dotnet/issues/2314
public void TakeIdentifierIntoAccount(object x)
// See https://github.com/SonarSource/sonar-dotnet/issues/2314
public void TakeIdentifierIntoAccount(object x)
{
if (x is Fruit)
{
if (x is Fruit)
{
var f = new Fruit();
var c = (Fruit)f;
}
var f = new Fruit();
var c = (Fruit)f;
}

if (someField is Fruit) // Noncompliant
{
var fruit = (Fruit)this.someField;
// ^^^^^^^^^^^^^^^^^^^^^ Secondary
}
if (someField is Fruit) // Noncompliant
{
var fruit = (Fruit)this.someField;
// ^^^^^^^^^^^^^^^^^^^^^ Secondary
}
}

public void UnknownFoo(object x)
public void UnknownFoo(object x)
{
if (x is Car) // Compliant because we ignore what the type is // Error [CS0246]
{
if (x is Car) // Compliant because we ignore what the type is // Error [CS0246]
{
var c = (Car)x; // Error [CS0246]
}
var c = (Car)x; // Error [CS0246]
}
}
}

public class Bar<T> { }
public class Bar<T> { }

public class Foo<T>
public class Foo<T>
{
public void Process(object message)
{
public void Process(object message)
if (message is Bar<T>/*comment*/) // Noncompliant
{
if (message is Bar<T>/*comment*/) // Noncompliant
{
var sub = (Bar<T>/**/) message; // Secondary
}
var sub = (Bar<T>/**/) message; // Secondary
}
}
}

0 comments on commit c0ca608

Please sign in to comment.