Skip to content

Commit abcee57

Browse files
authored
Remove unnecessary initialization of variables in generated code (dotnet#60748)
1 parent 24864a9 commit abcee57

File tree

2 files changed

+43
-31
lines changed

2 files changed

+43
-31
lines changed

src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/PInvokeStubCodeGenerator.cs

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,18 @@ public override (string managed, string native) GetIdentifiers(TypePositionInfo
217217

218218
public BlockSyntax GeneratePInvokeBody(string dllImportName)
219219
{
220+
bool invokeReturnsVoid = _retMarshaller.TypeInfo.ManagedType == SpecialTypeInfo.Void;
221+
222+
// Handle GuaranteedUnmarshal and Cleanup first since whether or not those stages produce statements affects multiple other stages.
223+
var guaranteedUnmarshalStatements = new List<StatementSyntax>();
224+
GenerateStatementsForStage(Stage.GuaranteedUnmarshal, guaranteedUnmarshalStatements);
225+
bool hasGuaranteedUnmarshalStatements = guaranteedUnmarshalStatements.Count > 0;
226+
227+
var cleanupStatements = new List<StatementSyntax>();
228+
GenerateStatementsForStage(Stage.Cleanup, cleanupStatements);
229+
230+
bool shouldInitializeVariables = hasGuaranteedUnmarshalStatements || cleanupStatements.Count > 0;
231+
220232
var setupStatements = new List<StatementSyntax>();
221233

222234
foreach (BoundGenerator marshaller in _paramMarshallers)
@@ -238,11 +250,9 @@ public BlockSyntax GeneratePInvokeBody(string dllImportName)
238250
}
239251

240252
// Declare variables for parameters
241-
AppendVariableDeclations(setupStatements, info, marshaller.Generator);
253+
AppendVariableDeclations(setupStatements, info, marshaller.Generator, initializeToDefault: shouldInitializeVariables);
242254
}
243255

244-
bool invokeReturnsVoid = _retMarshaller.TypeInfo.ManagedType == SpecialTypeInfo.Void;
245-
246256
// Stub return is not the same as invoke return
247257
if (!_stubReturnsVoid && !_retMarshaller.TypeInfo.IsManagedReturnPosition)
248258
{
@@ -252,47 +262,41 @@ public BlockSyntax GeneratePInvokeBody(string dllImportName)
252262
(TypePositionInfo stubRetTypeInfo, IMarshallingGenerator stubRetGenerator) = _paramMarshallers.Last();
253263

254264
// Declare variables for stub return value
255-
AppendVariableDeclations(setupStatements, stubRetTypeInfo, stubRetGenerator);
265+
AppendVariableDeclations(setupStatements, stubRetTypeInfo, stubRetGenerator, initializeToDefault: shouldInitializeVariables);
256266
}
257267

258268
if (!invokeReturnsVoid)
259269
{
260270
// Declare variables for invoke return value
261-
AppendVariableDeclations(setupStatements, _retMarshaller.TypeInfo, _retMarshaller.Generator);
271+
AppendVariableDeclations(setupStatements, _retMarshaller.TypeInfo, _retMarshaller.Generator, initializeToDefault: shouldInitializeVariables);
262272
}
263273

264-
// Do not manually handle SetLastError when generating forwarders.
265-
// We want the runtime to handle everything.
266274
if (_setLastError)
267275
{
268276
// Declare variable for last error
269-
setupStatements.Add(MarshallerHelpers.DeclareWithDefault(
277+
setupStatements.Add(MarshallerHelpers.Declare(
270278
PredefinedType(Token(SyntaxKind.IntKeyword)),
271-
LastErrorIdentifier));
279+
LastErrorIdentifier,
280+
initializeToDefault: false));
272281
}
273282

274-
var tryStatements = new List<StatementSyntax>();
275-
var guaranteedUnmarshalStatements = new List<StatementSyntax>();
276-
var cleanupStatements = new List<StatementSyntax>();
277-
InvocationExpressionSyntax invoke = InvocationExpression(IdentifierName(dllImportName));
278-
279-
// Handle GuaranteedUnmarshal first since that stage producing statements affects multiple other stages.
280-
GenerateStatementsForStage(Stage.GuaranteedUnmarshal, guaranteedUnmarshalStatements);
281-
if (guaranteedUnmarshalStatements.Count > 0)
283+
if (hasGuaranteedUnmarshalStatements)
282284
{
283-
setupStatements.Add(MarshallerHelpers.DeclareWithDefault(PredefinedType(Token(SyntaxKind.BoolKeyword)), InvokeSucceededIdentifier));
285+
setupStatements.Add(MarshallerHelpers.Declare(PredefinedType(Token(SyntaxKind.BoolKeyword)), InvokeSucceededIdentifier, initializeToDefault: true));
284286
}
285287

288+
var tryStatements = new List<StatementSyntax>();
289+
InvocationExpressionSyntax invoke = InvocationExpression(IdentifierName(dllImportName));
290+
286291
GenerateStatementsForStage(Stage.Setup, setupStatements);
287292
GenerateStatementsForStage(Stage.Marshal, tryStatements);
288293
GenerateStatementsForInvoke(tryStatements, invoke);
289294
GenerateStatementsForStage(Stage.KeepAlive, tryStatements);
290295
GenerateStatementsForStage(Stage.Unmarshal, tryStatements);
291-
GenerateStatementsForStage(Stage.Cleanup, cleanupStatements);
292296

293297
List<StatementSyntax> allStatements = setupStatements;
294298
List<StatementSyntax> finallyStatements = new List<StatementSyntax>();
295-
if (guaranteedUnmarshalStatements.Count > 0)
299+
if (hasGuaranteedUnmarshalStatements)
296300
{
297301
finallyStatements.Add(IfStatement(IdentifierName(InvokeSucceededIdentifier), Block(guaranteedUnmarshalStatements)));
298302
}
@@ -477,24 +481,26 @@ _retMarshaller.Generator is IAttributedReturnTypeMarshallingGenerator attributed
477481
);
478482
}
479483

480-
private void AppendVariableDeclations(List<StatementSyntax> statementsToUpdate, TypePositionInfo info, IMarshallingGenerator generator)
484+
private void AppendVariableDeclations(List<StatementSyntax> statementsToUpdate, TypePositionInfo info, IMarshallingGenerator generator, bool initializeToDefault)
481485
{
482486
(string managed, string native) = GetIdentifiers(info);
483487

484488
// Declare variable for return value
485489
if (info.IsManagedReturnPosition || info.IsNativeReturnPosition)
486490
{
487-
statementsToUpdate.Add(MarshallerHelpers.DeclareWithDefault(
491+
statementsToUpdate.Add(MarshallerHelpers.Declare(
488492
info.ManagedType.Syntax,
489-
managed));
493+
managed,
494+
false));
490495
}
491496

492497
// Declare variable with native type for parameter or return value
493498
if (generator.UsesNativeIdentifier(info, this))
494499
{
495-
statementsToUpdate.Add(MarshallerHelpers.DeclareWithDefault(
500+
statementsToUpdate.Add(MarshallerHelpers.Declare(
496501
generator.AsNativeType(info),
497-
native));
502+
native,
503+
initializeToDefault));
498504
}
499505
}
500506
}

src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallerHelpers.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,23 @@ public static ForStatementSyntax GetForLoop(string collectionIdentifier, string
5555
IdentifierName(indexerIdentifier))));
5656
}
5757

58-
public static LocalDeclarationStatementSyntax DeclareWithDefault(TypeSyntax typeSyntax, string identifier)
58+
public static LocalDeclarationStatementSyntax Declare(TypeSyntax typeSyntax, string identifier, bool initializeToDefault)
5959
{
60+
VariableDeclaratorSyntax decl = VariableDeclarator(identifier);
61+
if (initializeToDefault)
62+
{
63+
decl = decl.WithInitializer(
64+
EqualsValueClause(
65+
LiteralExpression(SyntaxKind.DefaultLiteralExpression)));
66+
}
67+
68+
// <type> <identifier>;
69+
// or
6070
// <type> <identifier> = default;
6171
return LocalDeclarationStatement(
6272
VariableDeclaration(
6373
typeSyntax,
64-
SingletonSeparatedList(
65-
VariableDeclarator(identifier)
66-
.WithInitializer(
67-
EqualsValueClause(
68-
LiteralExpression(SyntaxKind.DefaultLiteralExpression))))));
74+
SingletonSeparatedList(decl)));
6975
}
7076

7177
public static RefKind GetRefKindForByValueContentsKind(this ByValueContentsMarshalKind byValue)

0 commit comments

Comments
 (0)