Skip to content

Commit cfde3c1

Browse files
Add regression tests for whitespace parameter names in LLVM IR generation and fix LlvmIrFunction constructor
Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com>
1 parent 0240be1 commit cfde3c1

File tree

2 files changed

+81
-1
lines changed

2 files changed

+81
-1
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using Microsoft.Build.Utilities;
5+
using NUnit.Framework;
6+
using Xamarin.Android.Tasks.LLVMIR;
7+
using Xamarin.Android.Tools;
8+
9+
namespace Xamarin.Android.Build.Tests.Tasks
10+
{
11+
[TestFixture]
12+
public class LlvmIrGeneratorTests
13+
{
14+
/// <summary>
15+
/// Regression test for https://github.com/dotnet/android/issues/10086
16+
///
17+
/// When a managed method parameter has a whitespace-only name, the LLVM IR
18+
/// generator would produce invalid IR like:
19+
/// define void @test(ptr noundef % )
20+
///
21+
/// The fix ensures whitespace-only names are normalized to null before
22+
/// creating LlvmIrFunctionParameter instances, so that LlvmIrFunction
23+
/// assigns them valid numeric names (e.g., %0, %1).
24+
/// </summary>
25+
[Test]
26+
[TestCase (null, Description = "Null parameter name")]
27+
[TestCase ("", Description = "Empty parameter name")]
28+
[TestCase (" ", Description = "Space-only parameter name")]
29+
[TestCase (" ", Description = "Multiple spaces parameter name")]
30+
[TestCase ("\t", Description = "Tab-only parameter name")]
31+
public void FunctionParameterWithInvalidName_GetsNumericName (string? paramName)
32+
{
33+
var parameters = new List<LlvmIrFunctionParameter> {
34+
new LlvmIrFunctionParameter (typeof (IntPtr), "env"),
35+
new LlvmIrFunctionParameter (typeof (IntPtr), "klass"),
36+
new LlvmIrFunctionParameter (typeof (IntPtr), paramName),
37+
};
38+
39+
var func = new LlvmIrFunction ("test_function", typeof (void), parameters);
40+
41+
// The third parameter should have been assigned a numeric name
42+
var thirdParam = func.Signature.Parameters[2];
43+
Assert.IsNotNull (thirdParam.Name, "Parameter name should not be null after LlvmIrFunction construction");
44+
Assert.IsNotEmpty (thirdParam.Name, "Parameter name should not be empty after LlvmIrFunction construction");
45+
Assert.That (thirdParam.Name.Trim (), Is.Not.Empty, "Parameter name should not be whitespace-only after LlvmIrFunction construction");
46+
}
47+
48+
/// <summary>
49+
/// Verifies that the LLVM IR generator produces valid function signatures
50+
/// when parameters have valid names, including numeric names assigned to
51+
/// previously unnamed parameters.
52+
/// </summary>
53+
[Test]
54+
public void GeneratedIR_FunctionWithUnnamedParameter_ProducesValidOutput ()
55+
{
56+
var parameters = new List<LlvmIrFunctionParameter> {
57+
new LlvmIrFunctionParameter (typeof (IntPtr), "env"),
58+
new LlvmIrFunctionParameter (typeof (IntPtr), "klass"),
59+
new LlvmIrFunctionParameter (typeof (IntPtr), null), // unnamed parameter
60+
};
61+
62+
var func = new LlvmIrFunction ("test_function", typeof (void), parameters);
63+
64+
var log = new TaskLoggingHelper (new MockBuildEngine (TestContext.Out, [], [], []), "test");
65+
var module = new LlvmIrModule (new LlvmIrTypeCache (), log);
66+
func.Body.Ret (typeof (void));
67+
module.Add (func);
68+
module.AfterConstruction ();
69+
70+
var generator = LlvmIrGenerator.Create (AndroidTargetArch.Arm64, "test.ll");
71+
using var writer = new StringWriter ();
72+
generator.Generate (writer, module);
73+
74+
string output = writer.ToString ();
75+
// The output should contain valid parameter declarations - no "% " pattern
76+
Assert.That (output, Does.Not.Contain ("% "), "Generated LLVM IR should not contain whitespace-only parameter names");
77+
Assert.That (output, Does.Contain ("@test_function"), "Generated LLVM IR should contain the function name");
78+
}
79+
}
80+
}

src/Xamarin.Android.Build.Tasks/Utilities/LlvmIrGenerator/LlvmIrFunction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ public LlvmIrFunction (LlvmIrFunctionSignature signature, LlvmIrFunctionAttribut
442442
continue;
443443
}
444444

445-
if (!String.IsNullOrEmpty (parameter.Name)) {
445+
if (!String.IsNullOrWhiteSpace (parameter.Name)) {
446446
continue;
447447
}
448448

0 commit comments

Comments
 (0)