Skip to content

Commit ef034bc

Browse files
authored
Merge pull request github#18508 from michaelnebel/csharp/implicitinheritedtostring
C#: Also syntheize calls to inherited `ToString`.
2 parents 75a80f2 + bae29ae commit ef034bc

File tree

5 files changed

+27
-8
lines changed

5 files changed

+27
-8
lines changed

csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitToString.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,21 @@ internal sealed class ImplicitToString : Expression
1414
/// </summary>
1515
private static IMethodSymbol? GetToStringMethod(ITypeSymbol? type)
1616
{
17-
return type?
17+
if (type is null)
18+
{
19+
return null;
20+
}
21+
22+
var toString = type
1823
.GetMembers()
1924
.OfType<IMethodSymbol>()
2025
.Where(method =>
2126
method.GetName() == "ToString" &&
2227
method.Parameters.Length == 0
2328
)
2429
.FirstOrDefault();
30+
31+
return toString ?? GetToStringMethod(type.BaseType);
2532
}
2633

2734
private ImplicitToString(ExpressionNodeInfo info, IMethodSymbol toString) : base(new ExpressionInfo(info.Context, AnnotatedTypeSymbol.CreateNotAnnotated(toString.ReturnType), info.Location, ExprKind.METHOD_INVOCATION, info.Parent, info.Child, isCompilerGenerated: true, info.ExprValue))

csharp/ql/test/library-tests/implicittostring/implicitToString.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ public override string ToString()
1010
}
1111
}
1212

13+
public class Container2 : Container { }
14+
15+
public class Container3 { }
16+
1317
public class FormattableContainer : IFormattable
1418
{
1519
public string ToString(string format, IFormatProvider formatProvider)
@@ -40,5 +44,11 @@ public void M()
4044
y = "Hello" + formattableContainer; // Implicit call to ToString().
4145
y = $"Hello {formattableContainer}"; // Implicit call to ToString(string, IFormatProvider). We don't handle this.
4246
y = $"Hello {formattableContainer:D}"; // Implicit call to ToString(string, IFormatProvider). We don't handle this.
47+
48+
var container2 = new Container2();
49+
y = "Hello" + container2; // Implicit Container.ToString call.
50+
51+
var container3 = new Container3();
52+
y = "Hello" + container3; // Implicit Object.ToString call.
4353
}
4454
}
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
| implicitToString.cs:31:27:31:35 | call to method ToString |
2-
| implicitToString.cs:33:22:33:30 | call to method ToString |
3-
| implicitToString.cs:35:22:35:30 | call to method ToString |
4-
| implicitToString.cs:40:23:40:42 | call to method ToString |
1+
| implicitToString.cs:35:27:35:35 | call to method ToString | Container |
2+
| implicitToString.cs:37:22:37:30 | call to method ToString | Container |
3+
| implicitToString.cs:39:22:39:30 | call to method ToString | Container |
4+
| implicitToString.cs:44:23:44:42 | call to method ToString | FormattableContainer |
5+
| implicitToString.cs:49:23:49:32 | call to method ToString | Container |
6+
| implicitToString.cs:52:23:52:32 | call to method ToString | Object |

csharp/ql/test/library-tests/implicittostring/implicitToString.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ import csharp
22

33
from MethodCall c
44
where c.isImplicit()
5-
select c
5+
select c, c.getTarget().getDeclaringType().toString()

csharp/ql/test/query-tests/Nullness/Implications.expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -908,8 +908,8 @@
908908
| D.cs:253:13:253:14 | access to local variable o2 | null | D.cs:249:18:249:38 | ... ? ... : ... | null |
909909
| D.cs:266:13:266:27 | ... is ... | true | D.cs:266:13:266:17 | access to local variable other | non-null |
910910
| D.cs:310:21:310:26 | ... + ... | non-null | D.cs:310:21:310:22 | "" | non-null |
911-
| D.cs:310:21:310:26 | ... + ... | non-null | D.cs:310:26:310:26 | access to parameter a | non-null |
912-
| D.cs:310:21:310:26 | ... + ... | null | D.cs:310:26:310:26 | access to parameter a | null |
911+
| D.cs:310:21:310:26 | ... + ... | non-null | D.cs:310:26:310:26 | call to method ToString | non-null |
912+
| D.cs:310:21:310:26 | ... + ... | null | D.cs:310:26:310:26 | call to method ToString | null |
913913
| D.cs:312:17:312:23 | !... | false | D.cs:312:18:312:23 | access to local variable s_null | true |
914914
| D.cs:312:17:312:23 | !... | true | D.cs:312:18:312:23 | access to local variable s_null | false |
915915
| D.cs:318:16:318:62 | ... && ... | true | D.cs:318:16:318:36 | ... == ... | true |

0 commit comments

Comments
 (0)