Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 16, 2025

This PR adds comprehensive tests to verify that the C# compiler correctly enforces unsafe context requirements when using pointer types in type parameters.

Background

An issue was reported suggesting that unsafe context might not be required for pointer types in type parameters. Investigation confirmed this is not a bug - the compiler correctly requires unsafe context and produces appropriate errors.

Tests Added

Four new tests in UnsafeTests.cs verify the correct behavior for both field and variable scenarios:

1. PointerTypeInTypeParameter_Field_RequiresUnsafeContext

Verifies that using a pointer type syntax in a type parameter for a field without an unsafe context produces the expected error:

class C<T>
{
    C<int*[]> field;  // Error: int* requires unsafe context
}

Expected error:

  • CS0214 (ERR_UnsafeNeeded): Pointers and fixed size buffers may only be used in an unsafe context

2. PointerTypeInTypeParameter_Field_UnsafeModifierRemovesUnsafeNeededError

Verifies that adding the unsafe modifier to the class removes the unsafe context error for fields:

unsafe class C<T>
{
    C<int*[]> field;  // No error: unsafe context is provided
}

Expected behavior:

  • No CS0214 error (unsafe context is provided by the class modifier)

3. PointerTypeInTypeParameter_Variable_RequiresUnsafeContext

Verifies that using a pointer type syntax in a type parameter for a local variable without an unsafe context produces the expected error:

class C<T>
{
    void M()
    {
        C<int*[]> c = null;  // Error: int* requires unsafe context
    }
}

Expected error:

  • CS0214 (ERR_UnsafeNeeded): Pointers and fixed size buffers may only be used in an unsafe context

4. PointerTypeInTypeParameter_Variable_UnsafeModifierRemovesUnsafeNeededError

Verifies that adding the unsafe modifier to the class removes the unsafe context error for local variables:

unsafe class C<T>
{
    void M()
    {
        C<int*[]> c = null;  // No error: unsafe context is provided
    }
}

Expected behavior:

  • No CS0214 error (unsafe context is provided by the class modifier)

Implementation Details

  • All tests use TestOptions.UnsafeReleaseDll to enable unsafe code compilation
  • Raw string literals (C# 11+) are used for cleaner test code
  • Tests include WorkItem attributes linking to issue Unsafe not required for pointer type in type parameter #44088
  • Tests follow existing patterns in UnsafeTests.cs
  • All 491 tests in the UnsafeTests class pass

Note: int*[] (array of pointers) is a valid type argument since arrays are managed types, but the pointer type syntax int* itself requires an unsafe context.

These tests document and verify the correct compiler behavior: the pointer type syntax requires an unsafe context in both field and variable scenarios, but arrays of pointers can be used as type arguments since arrays are managed types.

Fixes #44088

Original prompt

This section details on the original issue you should resolve

<issue_title>Unsafe not required for pointer type in type parameter</issue_title>
<issue_description>```cs
class C
{
C<int*[]> Field;
}


The compiler currently compiles this without complaint, lacking both `/unsafe` and an `unsafe` modifier on `C<T>`.</issue_description>

<agent_instructions>@copilot i do not repro this. Can you open a test that demonstrates that the right behavior is there and an error is given about `int*` not being allowed in a  non-unsafe context.  Add a WorkItem attribute on the test that links to this issue.  Use raw string literals for test contents.

Also have a test that shows if you add `unsafe` to the class that teh error goes away.

Both tests should have the compiler option passed to them that says unsafe code is allowed.  </agent_instructions>

## Comments on the Issue (you are @copilot in this section)

<comments>
</comments>

Fixes #44088


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copilot AI changed the title [WIP] Add tests for unsafe pointer type handling in generics Add tests verifying pointer types in type parameters require unsafe context Oct 16, 2025
{
void M()
{
C<int*> c = null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot this is not the right test. Specifically, we want to test C<int*[]>. In this case, an array of pointers is fine (sincce an array is a maanged type). But it's just the usage of hte pointer type that should or should not produce an error depending on the unsafe context we're in.

Fix this and hte the teest below.

Also, add appropriate [Workitem(...)] attributes to both tests. REmove superfluous explanatory comments on the methods.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit b9b5314. Changed tests to use C<int*[]> (array of pointers), added WorkItem attributes for issue #44088, and removed explanatory comments.

Copilot AI requested a review from CyrusNajmabadi October 16, 2025 21:00
Copilot finished work on behalf of CyrusNajmabadi October 16, 2025 21:00
@CyrusNajmabadi CyrusNajmabadi marked this pull request as ready for review October 16, 2025 21:02
@CyrusNajmabadi CyrusNajmabadi requested a review from a team as a code owner October 16, 2025 21:02
Copilot finished work on behalf of CyrusNajmabadi October 16, 2025 21:38
@CyrusNajmabadi
Copy link
Member

@dotnet/roslyn-compiler ptal.

{
void M()
{
C<int*[]> c = null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot, this doesn't look like the test from the issue - that one was for a field, this is a variable. I would keep this test though, just add the original one too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added field-based tests in commit d8c7f91. The original variable tests are now renamed with _Variable suffix, and new _Field tests match the original issue.

Copilot AI requested a review from jjonescz October 23, 2025 13:44
Copilot finished work on behalf of jjonescz October 23, 2025 13:44
@CyrusNajmabadi CyrusNajmabadi enabled auto-merge (squash) October 23, 2025 14:15
@CyrusNajmabadi CyrusNajmabadi merged commit 4997b3a into main Oct 23, 2025
23 of 24 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone Oct 23, 2025
@CyrusNajmabadi CyrusNajmabadi deleted the copilot/add-tests-for-pointer-type-safety branch October 23, 2025 16:18
333fred added a commit to 333fred/roslyn that referenced this pull request Oct 24, 2025
* upstream/main: (332 commits)
  Cache lambdas in analyzer driver (dotnet#80759)
  Add information for NuGet package version 4.14 (dotnet#80870)
  Add missing search keywords to VB Advanced options page
  Fix IDE0031 false positive when preprocessor directives are used in if statements (dotnet#80878)
  Use core compiler on netfx hosts with toolset package (dotnet#80631)
  Make string concat assert more precise (dotnet#80619)
  Extensions: address some diagnostic quality issues (dotnet#80827)
  Add note on traversal order for bound nodes (dotnet#80872)
  Ensure that locals at the top level of a constructor have the same safe-context as parameters (dotnet#80807)
  Fix handling of SymbolDisplayCompilerInternalOptions.UseArityForGenericTypes option for non-native symbol implementations (dotnet#80826)
  Update src/Analyzers/CSharp/Tests/UseCollectionInitializer/UseCollectionInitializerTests.cs
  Add IsValidContainingStatement check to prevent collection initializers in using declarations
  Add back old DocumentSpan constructor (dotnet#80864)
  Add tests verifying pointer types in type parameters require unsafe context (dotnet#80776)
  Add regression test for Interlocked.Exchange with nullable types (dotnet#80796)
  Add regression test for ParseAttributeArgumentList with invalid input (fixes dotnet#8699) (dotnet#80705)
  Add regression test for compiler crash with syntax error in indexer declaration (dotnet#80772)
  Add runtime NullReferenceException validation to foreach null iteration tests (dotnet#80839)
  Update MicrosoftBuildTasksCoreVersionForMetrics to 17.11.48 (dotnet#80812)
  Mark CS4009 error as a "build only" error. (dotnet#80698)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unsafe not required for pointer type in type parameter

3 participants