-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
C#: Adding synthetic implicit ToString calls in binary- and string interpolation expressions. #18446
Merged
michaelnebel
merged 22 commits into
github:main
from
michaelnebel:csharp/implicittostring2
Jan 16, 2025
+446
−25
Merged
C#: Adding synthetic implicit ToString calls in binary- and string interpolation expressions. #18446
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
261b8db
C#: Add some implicit toString data flow test cases.
michaelnebel f905be4
C#: Add a RedundantToStringCall test case.
michaelnebel 908a3e3
C#: Make synthetic ToString calls in binary add expressions.
michaelnebel e9beeac
C#: Update test expected output.
michaelnebel 5f539c5
C#: Make synthetic ToString calls in string interpolation expressions.
michaelnebel 8bf67e3
C#: Update test expected output.
michaelnebel a4049b1
C#: Modify compiler generated strip logic to also take generated ToSt…
michaelnebel 6c6e58b
C#: Add PrintAst test to implicit ToString test.
michaelnebel 53c2f76
C#: Update AST printing to include generated cast (wrapping) expressi…
michaelnebel f239ab1
C#: Update PrintAst expected test output.
michaelnebel 20c2b2b
C#: Update other existing tests expected output.
michaelnebel cd7d2d4
C#: Add change note.
michaelnebel 6a31fd7
C#: Add ImplicitToString example in nullness tests.
michaelnebel e62846e
C#: Disregard compiler generated method calls as possible null derefe…
michaelnebel d40c1be
C#: Update expected testoutput for Nullness tests.
michaelnebel 77f9f4c
C#: Add implicit to string usage in constructor.
michaelnebel 2bff2d6
C#: Disregards compiler generated virtual calls as problematic virtua…
michaelnebel 024de5e
C#: Update virtual call in constructor expected test output.
michaelnebel ab70a94
C#: Add a summary model for PathString.ToString.
michaelnebel 6a406b2
C#: Do not insert a synthetic ToString call in interpolation expressi…
michaelnebel 0c5c2a3
C#: Add implicit to string test.
michaelnebel 3de5b22
C#: Update other existing tests expected output.
michaelnebel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitToString.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
using System.Linq; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
using Semmle.Extraction.CSharp.Util; | ||
using Semmle.Extraction.Kinds; | ||
|
||
|
||
namespace Semmle.Extraction.CSharp.Entities.Expressions | ||
{ | ||
internal sealed class ImplicitToString : Expression | ||
{ | ||
/// <summary> | ||
/// Gets the `ToString` method for the given type. | ||
/// </summary> | ||
private static IMethodSymbol? GetToStringMethod(ITypeSymbol? type) | ||
{ | ||
return type? | ||
.GetMembers() | ||
.OfType<IMethodSymbol>() | ||
.Where(method => | ||
method.GetName() == "ToString" && | ||
method.Parameters.Length == 0 | ||
) | ||
.FirstOrDefault(); | ||
} | ||
|
||
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)) | ||
{ | ||
Factory.Create(info.SetParent(this, -1)); | ||
|
||
var target = Method.Create(Context, toString); | ||
Context.TrapWriter.Writer.expr_call(this, target); | ||
} | ||
|
||
private static bool IsStringType(AnnotatedTypeSymbol? type) => | ||
type.HasValue && type.Value.Symbol?.SpecialType == SpecialType.System_String; | ||
|
||
/// <summary> | ||
/// Creates a new expression, adding a compiler generated `ToString` call if required. | ||
/// </summary> | ||
public static Expression Create(Context cx, ExpressionSyntax node, Expression parent, int child) | ||
{ | ||
var info = new ExpressionNodeInfo(cx, node, parent, child); | ||
return CreateFromNode(info.SetImplicitToString(IsStringType(parent.Type) && !IsStringType(info.Type))); | ||
} | ||
|
||
/// <summary> | ||
/// Wraps the resulting expression in a `ToString` call, if a suitable `ToString` method is available. | ||
/// </summary> | ||
public static Expression Wrap(ExpressionNodeInfo info) | ||
{ | ||
if (GetToStringMethod(info.Type?.Symbol) is IMethodSymbol toString) | ||
{ | ||
return new ImplicitToString(info, toString); | ||
} | ||
return Factory.Create(info); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
--- | ||
category: minorAnalysis | ||
--- | ||
* Added extractor support for extracting implicit `ToString` calls in binary `+` expressions and string interpolation expressions. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
extensions: | ||
- addsTo: | ||
pack: codeql/csharp-all | ||
extensible: summaryModel | ||
data: | ||
- ["Microsoft.AspNetCore.Http", "PathString", True, "ToString", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this include inherited members?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it doesn't.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should consider to support this as well - should be fairly easy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also good observation @hvitved !! 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think we should support that as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Follow up #18508