From cc6809cf36deb518592e0bf252dc65f9154718e8 Mon Sep 17 00:00:00 2001 From: Rikki Gibson Date: Fri, 28 Jul 2023 12:11:29 -0700 Subject: [PATCH 1/9] WIP --- .../Portable/FlowAnalysis/DefiniteAssignment.cs | 4 ++++ .../Test/Semantic/Semantics/RefFieldTests.cs | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.cs index 587caa072d918..4c6ee90b6f8a6 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.cs @@ -1497,6 +1497,10 @@ private Symbol UseNonFieldSymbolUnsafely(BoundExpression expression) protected void Assign(BoundNode node, BoundExpression value, bool isRef = false, bool read = true) { + if (!isRef && node is BoundFieldAccess { FieldSymbol.RefKind: not RefKind.None } fieldAccess) + { + CheckAssigned(fieldAccess, node.Syntax); + } AssignImpl(node, value, written: true, isRef: isRef, read: read); } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs index 47516736aa3e7..931eb1c7eb5d5 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs @@ -29532,5 +29532,21 @@ static ref int Local2(ref int x2, int y2) // } Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(27, 2)); } + + [Fact] + public void AutoDefault() + { + var comp = CreateCompilation(""" + ref struct RS + { + ref int ri; + public RS() => ri = 0; + } + """, + options: TestOptions.DebugDll.WithSpecificDiagnosticOptions(ReportStructInitializationWarnings), + targetFramework: TargetFramework.NetCoreApp); + + comp.VerifyDiagnostics(); + } } } From 7c1ece73aafc99bc74e8b5d7861b49309e5a807c Mon Sep 17 00:00:00 2001 From: Rikki Gibson Date: Fri, 28 Jul 2023 14:02:50 -0700 Subject: [PATCH 2/9] Fix auto-default behavior for ref fields and give a warning when uninitialized ref-field is assigned instead of ref-assigned --- .../CSharp/Portable/CSharpResources.resx | 6 +++ .../CSharp/Portable/Errors/ErrorCode.cs | 2 + .../CSharp/Portable/Errors/ErrorFacts.cs | 2 + .../FlowAnalysis/DefiniteAssignment.cs | 10 ++++- .../Generated/ErrorFacts.Generated.cs | 1 + .../Portable/xlf/CSharpResources.cs.xlf | 10 +++++ .../Portable/xlf/CSharpResources.de.xlf | 10 +++++ .../Portable/xlf/CSharpResources.es.xlf | 10 +++++ .../Portable/xlf/CSharpResources.fr.xlf | 10 +++++ .../Portable/xlf/CSharpResources.it.xlf | 10 +++++ .../Portable/xlf/CSharpResources.ja.xlf | 10 +++++ .../Portable/xlf/CSharpResources.ko.xlf | 10 +++++ .../Portable/xlf/CSharpResources.pl.xlf | 10 +++++ .../Portable/xlf/CSharpResources.pt-BR.xlf | 10 +++++ .../Portable/xlf/CSharpResources.ru.xlf | 10 +++++ .../Portable/xlf/CSharpResources.tr.xlf | 10 +++++ .../Portable/xlf/CSharpResources.zh-Hans.xlf | 10 +++++ .../Portable/xlf/CSharpResources.zh-Hant.xlf | 10 +++++ .../Test/Semantic/Semantics/RefFieldTests.cs | 42 ++++++++++++++++--- .../Test/Syntax/Diagnostics/DiagnosticTest.cs | 1 + 20 files changed, 188 insertions(+), 6 deletions(-) diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 84910f20b927e..d8ebed7c17b7f 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -7778,4 +7778,10 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ Reference kind modifier of parameter doesn't match the corresponding parameter in target. + + 'ref' field '{0}' should be ref-assigned before use. + + + 'ref' field should be ref-assigned before use. + \ No newline at end of file diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index 762cd342bd694..df7ff1882ed7d 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -2265,6 +2265,8 @@ internal enum ErrorCode ERR_OutAttrOnRefReadonlyParam = 9199, WRN_RefReadonlyParameterDefaultValue = 9200, + WRN_UseDefViolationRefField = 9210, + #endregion // Note: you will need to do the following after adding warnings: diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs index 2faf048702d08..7356e588f2f29 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs @@ -549,6 +549,7 @@ internal static int GetWarningLevel(ErrorCode code) case ErrorCode.WRN_HidingDifferentRefness: case ErrorCode.WRN_TargetDifferentRefness: case ErrorCode.WRN_RefReadonlyParameterDefaultValue: + case ErrorCode.WRN_UseDefViolationRefField: return 1; default: return 0; @@ -2394,6 +2395,7 @@ internal static bool IsBuildOnlyDiagnostic(ErrorCode code) case ErrorCode.WRN_TargetDifferentRefness: case ErrorCode.ERR_OutAttrOnRefReadonlyParam: case ErrorCode.WRN_RefReadonlyParameterDefaultValue: + case ErrorCode.WRN_UseDefViolationRefField: return false; default: // NOTE: All error codes must be explicitly handled in this switch statement diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.cs index 4c6ee90b6f8a6..84e2d71c2ec84 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.cs @@ -1324,7 +1324,15 @@ void addDiagnosticForStructField(int fieldSlot, FieldSymbol fieldSymbol) // should we handle nested fields here? https://github.com/dotnet/roslyn/issues/59890 AddImplicitlyInitializedField((FieldSymbol)fieldIdentifier.Symbol); - if (compilation.IsFeatureEnabled(MessageID.IDS_FeatureAutoDefaultStructs)) + if (fieldSymbol.RefKind != RefKind.None) + { + // it should be impossible for 'hasAssociatedProperty' to be true but don't want to rule it out in error scenarios. + Diagnostics.Add( + ErrorCode.WRN_UseDefViolationRefField, + node.Location, + symbolName); + } + else if (compilation.IsFeatureEnabled(MessageID.IDS_FeatureAutoDefaultStructs)) { Diagnostics.Add( hasAssociatedProperty ? ErrorCode.WRN_UseDefViolationPropertySupportedVersion : ErrorCode.WRN_UseDefViolationFieldSupportedVersion, diff --git a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs index a04c7696425a2..cacaecb4c540c 100644 --- a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs @@ -332,6 +332,7 @@ public static bool IsWarning(ErrorCode code) case ErrorCode.WRN_HidingDifferentRefness: case ErrorCode.WRN_TargetDifferentRefness: case ErrorCode.WRN_RefReadonlyParameterDefaultValue: + case ErrorCode.WRN_UseDefViolationRefField: return true; default: return false; diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index 026eb46d6338c..9b2bb03c7a9a7 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -4982,6 +4982,16 @@ Použily se pravděpodobně nepřiřazené automaticky implementované vlastnosti + + 'ref' field '{0}' should be ref-assigned before use. + 'ref' field '{0}' should be ref-assigned before use. + + + + 'ref' field should be ref-assigned before use. + 'ref' field should be ref-assigned before use. + + The 'this' object is read before all of its fields have been assigned, causing preceding implicit assignments of 'default' to non-explicitly assigned fields. Objekt this se přečte před přiřazením všech jeho polí, což způsobí, že předchozí implicitní přiřazení default k ne explicitně přiřazeným polím. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index a67617ea3a23e..445c2518ec562 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -4982,6 +4982,16 @@ Verwenden einer möglicherweise nicht zugewiesenen, automatisch implementierten Eigenschaft + + 'ref' field '{0}' should be ref-assigned before use. + 'ref' field '{0}' should be ref-assigned before use. + + + + 'ref' field should be ref-assigned before use. + 'ref' field should be ref-assigned before use. + + The 'this' object is read before all of its fields have been assigned, causing preceding implicit assignments of 'default' to non-explicitly assigned fields. Das „this“-Objekt wird gelesen, bevor alle zugehörigen Felder zugewiesen wurden, was zu vorherigen impliziten Zuweisungen von "default" zu nicht explizit zugewiesenen Feldern führt. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index 2054c6ecfd02c..7376f4e3b2a2d 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -4982,6 +4982,16 @@ Uso de una propiedad implementada automáticamente posiblemente sin asignar + + 'ref' field '{0}' should be ref-assigned before use. + 'ref' field '{0}' should be ref-assigned before use. + + + + 'ref' field should be ref-assigned before use. + 'ref' field should be ref-assigned before use. + + The 'this' object is read before all of its fields have been assigned, causing preceding implicit assignments of 'default' to non-explicitly assigned fields. El objeto "this" se lee antes de que se hayan asignado todos sus campos, lo que provoca las asignaciones implícitas anteriores de "default" a los campos asignados de forma no explícita. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index 43894215bec20..d0ad9dbc019d3 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -4982,6 +4982,16 @@ Utilisation d'une propriété implémentée automatiquement éventuellement non assignée + + 'ref' field '{0}' should be ref-assigned before use. + 'ref' field '{0}' should be ref-assigned before use. + + + + 'ref' field should be ref-assigned before use. + 'ref' field should be ref-assigned before use. + + The 'this' object is read before all of its fields have been assigned, causing preceding implicit assignments of 'default' to non-explicitly assigned fields. L’objet « this » est lu avant que tous ses champs aient été affectés, ce qui entraîne les affectations implicites précédentes de 'default' aux champs non explicitement attribués. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index 2d471b652d7ce..14097a0a6b8a8 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -4982,6 +4982,16 @@ target:module Compila un modulo che può essere aggiunto ad altro Uso della proprietà implementata automaticamente probabilmente non assegnata + + 'ref' field '{0}' should be ref-assigned before use. + 'ref' field '{0}' should be ref-assigned before use. + + + + 'ref' field should be ref-assigned before use. + 'ref' field should be ref-assigned before use. + + The 'this' object is read before all of its fields have been assigned, causing preceding implicit assignments of 'default' to non-explicitly assigned fields. L'oggetto 'this' viene letto prima che tutti i relativi campi siano stati assegnati, determinando le assegnazioni implicite precedenti di 'default' ai campi non esplicitamente assegnati. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index f3194b7843ce2..f8e7be973c06b 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -4982,6 +4982,16 @@ 割り当てられていない可能性のある自動実装プロパティの使用 + + 'ref' field '{0}' should be ref-assigned before use. + 'ref' field '{0}' should be ref-assigned before use. + + + + 'ref' field should be ref-assigned before use. + 'ref' field should be ref-assigned before use. + + The 'this' object is read before all of its fields have been assigned, causing preceding implicit assignments of 'default' to non-explicitly assigned fields. 'this' オブジェクトは、すべてのフィールドが割り当てられる前に読み取られます。これにより、明示的に割り当てられていないフィールドに対する 'default' の暗黙的な割り当てが先行しています。 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index de1ef080488f6..88585bf66fcfb 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -4982,6 +4982,16 @@ 할당되지 않은 자동 구현 속성을 사용하고 있는 것 같음 + + 'ref' field '{0}' should be ref-assigned before use. + 'ref' field '{0}' should be ref-assigned before use. + + + + 'ref' field should be ref-assigned before use. + 'ref' field should be ref-assigned before use. + + The 'this' object is read before all of its fields have been assigned, causing preceding implicit assignments of 'default' to non-explicitly assigned fields. 'this' 개체는 모든 필드가 할당되기 전에 읽혀서 명시적으로 할당되지 않은 필드에 'default'의 암시적 할당이 선행되도록 합니다. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index c5ce771ac6ffd..9699463ccc3bf 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -4982,6 +4982,16 @@ Użycie prawdopodobnie nieprzypisanej automatycznie implementowanej właściwości + + 'ref' field '{0}' should be ref-assigned before use. + 'ref' field '{0}' should be ref-assigned before use. + + + + 'ref' field should be ref-assigned before use. + 'ref' field should be ref-assigned before use. + + The 'this' object is read before all of its fields have been assigned, causing preceding implicit assignments of 'default' to non-explicitly assigned fields. Obiekt „this” jest odczytywany przed przypisaniem wszystkich jego pól, co powoduje, że wcześniejsze niejawne przypisania wartości „default” są przypisywane do pól nieprzypisanych jawnie. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index 0c660e3afabf5..14a21ac15b04d 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -4982,6 +4982,16 @@ Uso de propriedade autoimplementada possivelmente não atribuída + + 'ref' field '{0}' should be ref-assigned before use. + 'ref' field '{0}' should be ref-assigned before use. + + + + 'ref' field should be ref-assigned before use. + 'ref' field should be ref-assigned before use. + + The 'this' object is read before all of its fields have been assigned, causing preceding implicit assignments of 'default' to non-explicitly assigned fields. O objeto 'this' é lido antes que todos os seus campos tenham sido atribuídos, causando atribuições anteriores implícitas de campos 'default' a campos não explicitamente atribuídos. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index c0892467d07eb..a51ecb84896f7 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -4982,6 +4982,16 @@ Использование автоматически реализованного свойства, которому, возможно, не присвоено значение + + 'ref' field '{0}' should be ref-assigned before use. + 'ref' field '{0}' should be ref-assigned before use. + + + + 'ref' field should be ref-assigned before use. + 'ref' field should be ref-assigned before use. + + The 'this' object is read before all of its fields have been assigned, causing preceding implicit assignments of 'default' to non-explicitly assigned fields. Объект "this" прочитывается до назначения всех его полей, что приводит к неявному назначению "default" полям, которые не назначены явным образом. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 64dba5c612765..136f7232d0dfb 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -4982,6 +4982,16 @@ Atanmamış olabilecek otomatik uygulanmış özelliğin kullanımı + + 'ref' field '{0}' should be ref-assigned before use. + 'ref' field '{0}' should be ref-assigned before use. + + + + 'ref' field should be ref-assigned before use. + 'ref' field should be ref-assigned before use. + + The 'this' object is read before all of its fields have been assigned, causing preceding implicit assignments of 'default' to non-explicitly assigned fields. 'this' nesnesi, tüm alanları atanmadan önce okunur ve bu da açıkça atanmamış alanlara yönelik 'default' öğesinin önceki örtük atamaları ile sonuçlanır. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index d7cb93e15b189..628323f398eaa 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -4982,6 +4982,16 @@ 使用可能未赋值的自动实现的属性 + + 'ref' field '{0}' should be ref-assigned before use. + 'ref' field '{0}' should be ref-assigned before use. + + + + 'ref' field should be ref-assigned before use. + 'ref' field should be ref-assigned before use. + + The 'this' object is read before all of its fields have been assigned, causing preceding implicit assignments of 'default' to non-explicitly assigned fields. 分配“this”对象的所有字段之前读取该对象,从而导致对未显式分配的字段进行前面的隐式分配“default”。 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index d592580b92122..c12646777ac11 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -4982,6 +4982,16 @@ strument:TestCoverage 產生檢測要收集 使用可能未指派的自動實作屬性 + + 'ref' field '{0}' should be ref-assigned before use. + 'ref' field '{0}' should be ref-assigned before use. + + + + 'ref' field should be ref-assigned before use. + 'ref' field should be ref-assigned before use. + + The 'this' object is read before all of its fields have been assigned, causing preceding implicit assignments of 'default' to non-explicitly assigned fields. 在指派 'this' 物件的所有欄位之前,會先讀取該物件,導致先前對未明確指派的欄位進行隱含的 'default' 指派。 diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs index 931eb1c7eb5d5..448504045bf40 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs @@ -29534,19 +29534,51 @@ static ref int Local2(ref int x2, int y2) } [Fact] - public void AutoDefault() + public void RefField_Assignment_AutoDefault() { - var comp = CreateCompilation(""" + var verifier = CompileAndVerify(""" + using System; + + try + { + new RS(); + } + catch (NullReferenceException) + { + Console.Write(1); + } + ref struct RS { ref int ri; public RS() => ri = 0; } """, - options: TestOptions.DebugDll.WithSpecificDiagnosticOptions(ReportStructInitializationWarnings), - targetFramework: TargetFramework.NetCoreApp); + options: TestOptions.DebugExe.WithSpecificDiagnosticOptions(ReportStructInitializationWarnings), + verify: Verification.Skipped, + targetFramework: TargetFramework.NetCoreApp, + expectedOutput: "1"); - comp.VerifyDiagnostics(); + verifier.VerifyDiagnostics( + // (15,20): warning CS9210: 'ref' field 'ri' should be ref-assigned before use. + // public RS() => ri = 0; + Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "ri").WithArguments("ri").WithLocation(15, 20)); + + verifier.VerifyIL("RS..ctor", """ + { + // Code size 17 (0x11) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: conv.u + IL_0003: stfld "ref int RS.ri" + IL_0008: ldarg.0 + IL_0009: ldfld "ref int RS.ri" + IL_000e: ldc.i4.0 + IL_000f: stind.i4 + IL_0010: ret + } + """); } } } diff --git a/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs b/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs index 42c028ee87337..42b5bb823b379 100644 --- a/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs +++ b/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs @@ -425,6 +425,7 @@ public void WarningLevel_2() case ErrorCode.WRN_RefReturnOnlyParameter: case ErrorCode.WRN_RefReturnOnlyParameter2: case ErrorCode.WRN_RefAssignValEscapeWider: + case ErrorCode.WRN_UseDefViolationRefField: Assert.Equal(1, ErrorFacts.GetWarningLevel(errorCode)); break; case ErrorCode.WRN_InvalidVersionFormat: From 19150bb43f12d050c3bdf147e56d5f1d04ee6ab4 Mon Sep 17 00:00:00 2001 From: Rikki Gibson Date: Fri, 28 Jul 2023 15:26:22 -0700 Subject: [PATCH 3/9] more --- .../FlowAnalysis/DefiniteAssignment.cs | 13 +- .../Test/Semantic/Semantics/RefFieldTests.cs | 136 +++++++++++++++++- 2 files changed, 137 insertions(+), 12 deletions(-) diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.cs index 84e2d71c2ec84..cad7d7ca681c4 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.cs @@ -1326,11 +1326,14 @@ void addDiagnosticForStructField(int fieldSlot, FieldSymbol fieldSymbol) if (fieldSymbol.RefKind != RefKind.None) { - // it should be impossible for 'hasAssociatedProperty' to be true but don't want to rule it out in error scenarios. - Diagnostics.Add( - ErrorCode.WRN_UseDefViolationRefField, - node.Location, - symbolName); + // 'hasAssociatedProperty' is only true here in error scenarios where we don't need to report this as a cascading diagnostic + if (!hasAssociatedProperty) + { + Diagnostics.Add( + ErrorCode.WRN_UseDefViolationRefField, + node.Location, + symbolName); + } } else if (compilation.IsFeatureEnabled(MessageID.IDS_FeatureAutoDefaultStructs)) { diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs index 448504045bf40..bf45735bb24e9 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs @@ -5211,7 +5211,10 @@ class Program static ref T F2(ref R r) => ref r.F0(); }"; var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); - comp.VerifyEmitDiagnostics(); + comp.VerifyEmitDiagnostics( + // (4,25): warning CS9210: 'ref' field '_t' should be ref-assigned before use. + // public R(ref T t) { _t = t; } + Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "_t").WithArguments("_t").WithLocation(4, 25)); } [Fact] @@ -5446,8 +5449,6 @@ static void F(ref T t) [Fact] public void DefiniteAssignment_02() { - // Should we report a warning when assigning a value rather than a ref in the - // constructor, because a NullReferenceException will be thrown at runtime? var source = @"ref struct S { @@ -5458,7 +5459,10 @@ public S(ref T t) } }"; var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); - comp.VerifyEmitDiagnostics(); + comp.VerifyEmitDiagnostics( + // (6,9): warning CS9210: 'ref' field 'F' should be ref-assigned before use. + // F = t; + Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "F").WithArguments("F").WithLocation(6, 9)); } [Fact] @@ -5565,7 +5569,10 @@ object P static ref readonly T GetRefReadonly() => throw null; }"; var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70); - comp.VerifyEmitDiagnostics(); + comp.VerifyEmitDiagnostics( + // 0.cs(7,9): warning CS9210: 'ref' field 'F' should be ref-assigned before use. + // F = tValue; + Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "F").WithArguments("F").WithLocation(7, 9)); } [Fact] @@ -5601,6 +5608,9 @@ object P // (7,9): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable // F = tValue; // 1 Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(7, 9), + // (7,9): warning CS9210: 'ref' field 'F' should be ref-assigned before use. + // F = tValue; // 1 + Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "F").WithArguments("F").WithLocation(7, 9), // (8,9): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable // F = tRef; // 2 Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(8, 9), @@ -5650,7 +5660,10 @@ object P static ref readonly T GetRefReadonly() => throw null; }"; var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70); - comp.VerifyEmitDiagnostics(); + comp.VerifyEmitDiagnostics( + // 0.cs(7,9): warning CS9210: 'ref' field 'F' should be ref-assigned before use. + // F = tValue; + Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "F").WithArguments("F").WithLocation(7, 9)); } [Fact] @@ -5686,6 +5699,9 @@ object P // (7,9): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable // F = tValue; // 1 Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(7, 9), + // (7,9): warning CS9210: 'ref' field 'F' should be ref-assigned before use. + // F = tValue; // 1 + Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "F").WithArguments("F").WithLocation(7, 9), // (8,9): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable // F = tRef; // 2 Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(8, 9), @@ -29534,7 +29550,7 @@ static ref int Local2(ref int x2, int y2) } [Fact] - public void RefField_Assignment_AutoDefault() + public void RefField_Assignment_AutoDefault_01() { var verifier = CompileAndVerify(""" using System; @@ -29580,5 +29596,111 @@ .maxstack 2 } """); } + + [Fact] + public void RefField_Assignment_AutoDefault_02() + { + var verifier = CompileAndVerify(""" + using System; + + try + { + new RS(); + } + catch (NullReferenceException) + { + Console.Write(1); + } + + ref struct RS + { + ref int ri; + public RS() + { + int local = ri; + } + } + """, + options: TestOptions.DebugExe.WithSpecificDiagnosticOptions(ReportStructInitializationWarnings), + verify: Verification.Skipped, + targetFramework: TargetFramework.NetCoreApp, + expectedOutput: "1"); + + // TODO2: why are we getting an 'unassigned this' as well as 'use def violation' diagnostic + verifier.VerifyDiagnostics( + // (14,13): warning CS0649: Field 'RS.ri' is never assigned to, and will always have its default value 0 + // ref int ri; + Diagnostic(ErrorCode.WRN_UnassignedInternalField, "ri").WithArguments("RS.ri", "0").WithLocation(14, 13), + // (15,12): warning CS9022: Control is returned to caller before field 'RS.ri' is explicitly assigned, causing a preceding implicit assignment of 'default'. + // public RS() + Diagnostic(ErrorCode.WRN_UnassignedThisSupportedVersion, "RS").WithArguments("RS.ri").WithLocation(15, 12), + // (17,21): warning CS9210: 'ref' field 'ri' should be ref-assigned before use. + // int local = ri; // 1 + Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "ri").WithArguments("ri").WithLocation(17, 21)); + + verifier.VerifyIL("RS..ctor", """ + { + // Code size 18 (0x12) + .maxstack 2 + .locals init (int V_0) //local + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: conv.u + IL_0004: stfld "ref int RS.ri" + IL_0009: ldarg.0 + IL_000a: ldfld "ref int RS.ri" + IL_000f: ldind.i4 + IL_0010: stloc.0 + IL_0011: ret + } + """); + } + + [Fact] + public void RefField_Assignment_AutoDefault_03() + { + var verifier = CompileAndVerify(""" + using System; + + new RS(); + Console.Write(1); + + ref struct RS + { + ref int ri; + public RS() + { + ref int local = ref ri; // 1 + } + } + """, + options: TestOptions.DebugExe.WithSpecificDiagnosticOptions(ReportStructInitializationWarnings), + verify: Verification.Skipped, + targetFramework: TargetFramework.NetCoreApp, + expectedOutput: "1"); + + verifier.VerifyDiagnostics( + // (11,29): warning CS9210: 'ref' field 'ri' should be ref-assigned before use. + // ref int local = ref ri; // 1 + Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "ri").WithArguments("ri").WithLocation(11, 29)); + + verifier.VerifyIL("RS..ctor", """ + { + // Code size 17 (0x11) + .maxstack 2 + .locals init (int& V_0) //local + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: conv.u + IL_0004: stfld "ref int RS.ri" + IL_0009: ldarg.0 + IL_000a: ldfld "ref int RS.ri" + IL_000f: stloc.0 + IL_0010: ret + } + """); + } } } From aceef50b70b53bd03e319a58364bc261f085ff2f Mon Sep 17 00:00:00 2001 From: Rikki Gibson Date: Mon, 31 Jul 2023 10:14:10 -0700 Subject: [PATCH 4/9] Update test baseline --- .../CSharp/Test/Semantic/Semantics/InterpolationTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs index 6bd834237d887..3985714df1afd 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs @@ -15489,7 +15489,7 @@ static R M() readonly ref struct R { private readonly ref int _i; - public R(ref int i) { _i = i; } + public R(ref int i) { _i = ref i; } public R F([InterpolatedStringHandlerArgument("")] CustomHandler handler) => this; } From 72ae722d464d2f516320a032c4853fffd8ecbc7d Mon Sep 17 00:00:00 2001 From: Rikki Gibson Date: Mon, 31 Jul 2023 14:32:33 -0700 Subject: [PATCH 5/9] remove TODO --- src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs index bf45735bb24e9..67705505afd6f 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs @@ -29626,7 +29626,6 @@ public RS() targetFramework: TargetFramework.NetCoreApp, expectedOutput: "1"); - // TODO2: why are we getting an 'unassigned this' as well as 'use def violation' diagnostic verifier.VerifyDiagnostics( // (14,13): warning CS0649: Field 'RS.ri' is never assigned to, and will always have its default value 0 // ref int ri; From 981cc01741a7c70a05a39834f11755cfe82b7c3b Mon Sep 17 00:00:00 2001 From: Rikki Gibson Date: Mon, 31 Jul 2023 15:19:20 -0700 Subject: [PATCH 6/9] More testing --- .../CSharp/Portable/CSharpResources.resx | 4 +- .../CSharp/Portable/Errors/ErrorCode.cs | 3 +- .../Portable/xlf/CSharpResources.cs.xlf | 8 +- .../Portable/xlf/CSharpResources.de.xlf | 8 +- .../Portable/xlf/CSharpResources.es.xlf | 8 +- .../Portable/xlf/CSharpResources.fr.xlf | 8 +- .../Portable/xlf/CSharpResources.it.xlf | 8 +- .../Portable/xlf/CSharpResources.ja.xlf | 8 +- .../Portable/xlf/CSharpResources.ko.xlf | 8 +- .../Portable/xlf/CSharpResources.pl.xlf | 8 +- .../Portable/xlf/CSharpResources.pt-BR.xlf | 8 +- .../Portable/xlf/CSharpResources.ru.xlf | 8 +- .../Portable/xlf/CSharpResources.tr.xlf | 8 +- .../Portable/xlf/CSharpResources.zh-Hans.xlf | 8 +- .../Portable/xlf/CSharpResources.zh-Hant.xlf | 8 +- .../Test/Semantic/Semantics/RefFieldTests.cs | 77 ++++++++++++++++--- 16 files changed, 121 insertions(+), 67 deletions(-) diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 70ed21a151a6f..01609dec4e62a 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -7785,9 +7785,9 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ Reference kind modifier of parameter doesn't match the corresponding parameter in target. - 'ref' field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. - 'ref' field should be ref-assigned before use. + ref field should be ref-assigned before use. \ No newline at end of file diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index fead74070393d..81bc977d01572 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -2265,8 +2265,7 @@ internal enum ErrorCode WRN_TargetDifferentRefness = 9198, ERR_OutAttrOnRefReadonlyParam = 9199, WRN_RefReadonlyParameterDefaultValue = 9200, - - WRN_UseDefViolationRefField = 9210, + WRN_UseDefViolationRefField = 9201, #endregion diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index 42bc4a5ca974c..1055956485b90 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -4993,13 +4993,13 @@ - 'ref' field '{0}' should be ref-assigned before use. - 'ref' field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. - 'ref' field should be ref-assigned before use. - 'ref' field should be ref-assigned before use. + ref field should be ref-assigned before use. + ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index 6441f79d4c677..eadb249b470ab 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -4993,13 +4993,13 @@ - 'ref' field '{0}' should be ref-assigned before use. - 'ref' field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. - 'ref' field should be ref-assigned before use. - 'ref' field should be ref-assigned before use. + ref field should be ref-assigned before use. + ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index d5bda161c1030..f0f40073c4fb8 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -4993,13 +4993,13 @@ - 'ref' field '{0}' should be ref-assigned before use. - 'ref' field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. - 'ref' field should be ref-assigned before use. - 'ref' field should be ref-assigned before use. + ref field should be ref-assigned before use. + ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index 4029b61906b5b..575c18867b4e0 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -4993,13 +4993,13 @@ - 'ref' field '{0}' should be ref-assigned before use. - 'ref' field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. - 'ref' field should be ref-assigned before use. - 'ref' field should be ref-assigned before use. + ref field should be ref-assigned before use. + ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index cb80538441343..b15f898bb69c5 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -4993,13 +4993,13 @@ target:module Compila un modulo che può essere aggiunto ad altro - 'ref' field '{0}' should be ref-assigned before use. - 'ref' field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. - 'ref' field should be ref-assigned before use. - 'ref' field should be ref-assigned before use. + ref field should be ref-assigned before use. + ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index 55682af2c6f47..a64e85fd68f11 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -4993,13 +4993,13 @@ - 'ref' field '{0}' should be ref-assigned before use. - 'ref' field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. - 'ref' field should be ref-assigned before use. - 'ref' field should be ref-assigned before use. + ref field should be ref-assigned before use. + ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index 9a6bb6fce8c9e..35895ea33480f 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -4993,13 +4993,13 @@ - 'ref' field '{0}' should be ref-assigned before use. - 'ref' field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. - 'ref' field should be ref-assigned before use. - 'ref' field should be ref-assigned before use. + ref field should be ref-assigned before use. + ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 6036e5af7e4ad..33c3a4fa147d5 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -4993,13 +4993,13 @@ - 'ref' field '{0}' should be ref-assigned before use. - 'ref' field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. - 'ref' field should be ref-assigned before use. - 'ref' field should be ref-assigned before use. + ref field should be ref-assigned before use. + ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index 19ad61cb38429..12303a2736e3f 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -4993,13 +4993,13 @@ - 'ref' field '{0}' should be ref-assigned before use. - 'ref' field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. - 'ref' field should be ref-assigned before use. - 'ref' field should be ref-assigned before use. + ref field should be ref-assigned before use. + ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index 68b00ae8cec3c..6b4139144fb4d 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -4993,13 +4993,13 @@ - 'ref' field '{0}' should be ref-assigned before use. - 'ref' field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. - 'ref' field should be ref-assigned before use. - 'ref' field should be ref-assigned before use. + ref field should be ref-assigned before use. + ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 6fc86fd43c315..ec9f85d4cb26b 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -4993,13 +4993,13 @@ - 'ref' field '{0}' should be ref-assigned before use. - 'ref' field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. - 'ref' field should be ref-assigned before use. - 'ref' field should be ref-assigned before use. + ref field should be ref-assigned before use. + ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index a1b95dc92082b..aff896a4be37b 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -4993,13 +4993,13 @@ - 'ref' field '{0}' should be ref-assigned before use. - 'ref' field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. - 'ref' field should be ref-assigned before use. - 'ref' field should be ref-assigned before use. + ref field should be ref-assigned before use. + ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index 4f21474e985ca..e4da1a386d141 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -4993,13 +4993,13 @@ strument:TestCoverage 產生檢測要收集 - 'ref' field '{0}' should be ref-assigned before use. - 'ref' field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. + ref field '{0}' should be ref-assigned before use. - 'ref' field should be ref-assigned before use. - 'ref' field should be ref-assigned before use. + ref field should be ref-assigned before use. + ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs index 67705505afd6f..102c1d37a1d4d 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs @@ -5212,7 +5212,7 @@ class Program }"; var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); comp.VerifyEmitDiagnostics( - // (4,25): warning CS9210: 'ref' field '_t' should be ref-assigned before use. + // (4,25): warning CS9201: 'ref' field '_t' should be ref-assigned before use. // public R(ref T t) { _t = t; } Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "_t").WithArguments("_t").WithLocation(4, 25)); } @@ -5460,7 +5460,7 @@ public S(ref T t) }"; var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); comp.VerifyEmitDiagnostics( - // (6,9): warning CS9210: 'ref' field 'F' should be ref-assigned before use. + // (6,9): warning CS9201: 'ref' field 'F' should be ref-assigned before use. // F = t; Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "F").WithArguments("F").WithLocation(6, 9)); } @@ -5570,7 +5570,7 @@ object P }"; var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70); comp.VerifyEmitDiagnostics( - // 0.cs(7,9): warning CS9210: 'ref' field 'F' should be ref-assigned before use. + // 0.cs(7,9): warning CS9201: 'ref' field 'F' should be ref-assigned before use. // F = tValue; Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "F").WithArguments("F").WithLocation(7, 9)); } @@ -5608,7 +5608,7 @@ object P // (7,9): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable // F = tValue; // 1 Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(7, 9), - // (7,9): warning CS9210: 'ref' field 'F' should be ref-assigned before use. + // (7,9): warning CS9201: 'ref' field 'F' should be ref-assigned before use. // F = tValue; // 1 Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "F").WithArguments("F").WithLocation(7, 9), // (8,9): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable @@ -5661,7 +5661,7 @@ object P }"; var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70); comp.VerifyEmitDiagnostics( - // 0.cs(7,9): warning CS9210: 'ref' field 'F' should be ref-assigned before use. + // 0.cs(7,9): warning CS9201: 'ref' field 'F' should be ref-assigned before use. // F = tValue; Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "F").WithArguments("F").WithLocation(7, 9)); } @@ -5699,7 +5699,7 @@ object P // (7,9): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable // F = tValue; // 1 Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(7, 9), - // (7,9): warning CS9210: 'ref' field 'F' should be ref-assigned before use. + // (7,9): warning CS9201: 'ref' field 'F' should be ref-assigned before use. // F = tValue; // 1 Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "F").WithArguments("F").WithLocation(7, 9), // (8,9): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable @@ -29576,7 +29576,7 @@ ref struct RS expectedOutput: "1"); verifier.VerifyDiagnostics( - // (15,20): warning CS9210: 'ref' field 'ri' should be ref-assigned before use. + // (15,20): warning CS9201: 'ref' field 'ri' should be ref-assigned before use. // public RS() => ri = 0; Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "ri").WithArguments("ri").WithLocation(15, 20)); @@ -29633,7 +29633,7 @@ public RS() // (15,12): warning CS9022: Control is returned to caller before field 'RS.ri' is explicitly assigned, causing a preceding implicit assignment of 'default'. // public RS() Diagnostic(ErrorCode.WRN_UnassignedThisSupportedVersion, "RS").WithArguments("RS.ri").WithLocation(15, 12), - // (17,21): warning CS9210: 'ref' field 'ri' should be ref-assigned before use. + // (17,21): warning CS9201: 'ref' field 'ri' should be ref-assigned before use. // int local = ri; // 1 Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "ri").WithArguments("ri").WithLocation(17, 21)); @@ -29665,6 +29665,15 @@ public void RefField_Assignment_AutoDefault_03() new RS(); Console.Write(1); + try + { + new RS(ignored: true); + } + catch + { + Console.Write(2); + } + ref struct RS { ref int ri; @@ -29672,17 +29681,26 @@ public RS() { ref int local = ref ri; // 1 } + + public RS(bool ignored) + { + ref int local = ref ri; // 2 + Console.Write(local); + } } """, options: TestOptions.DebugExe.WithSpecificDiagnosticOptions(ReportStructInitializationWarnings), verify: Verification.Skipped, targetFramework: TargetFramework.NetCoreApp, - expectedOutput: "1"); + expectedOutput: "12"); verifier.VerifyDiagnostics( - // (11,29): warning CS9210: 'ref' field 'ri' should be ref-assigned before use. + // (20,29): warning CS9201: ref field 'ri' should be ref-assigned before use. // ref int local = ref ri; // 1 - Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "ri").WithArguments("ri").WithLocation(11, 29)); + Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "ri").WithArguments("ri").WithLocation(20, 29), + // (25,29): warning CS9201: ref field 'ri' should be ref-assigned before use. + // ref int local = ref ri; // 2 + Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "ri").WithArguments("ri").WithLocation(25, 29)); verifier.VerifyIL("RS..ctor", """ { @@ -29701,5 +29719,42 @@ .locals init (int& V_0) //local } """); } + + [Fact] + public void RefField_Assignment_AutoDefault_04() + { + var verifier = CompileAndVerify(""" + using System; + + var i = 1; + var rs = new RS(ref i); + + i = 2; + rs = new RS(ref i, ignored: true); + + ref struct RS + { + ref int ri; + + public RS(ref int ri) + { + this.ri = ref ri; + Console.Write(this.ri); + } + + public RS(ref int ri, bool ignored) + { + this = default(RS) with { ri = ref ri }; + Console.Write(this.ri); + } + } + """, + options: TestOptions.DebugExe.WithSpecificDiagnosticOptions(ReportStructInitializationWarnings), + verify: Verification.Skipped, + targetFramework: TargetFramework.NetCoreApp, + expectedOutput: "12"); + + verifier.VerifyDiagnostics(); + } } } From 26b90b682cff100768d8fc8429eba19880e2989c Mon Sep 17 00:00:00 2001 From: Rikki Gibson Date: Mon, 31 Jul 2023 15:48:40 -0700 Subject: [PATCH 7/9] Add data flow tests --- .../Emit2/FlowAnalysis/RegionAnalysisTests.cs | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/Compilers/CSharp/Test/Emit2/FlowAnalysis/RegionAnalysisTests.cs b/src/Compilers/CSharp/Test/Emit2/FlowAnalysis/RegionAnalysisTests.cs index ef7278c45caac..5c5751aa4f4f8 100644 --- a/src/Compilers/CSharp/Test/Emit2/FlowAnalysis/RegionAnalysisTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/FlowAnalysis/RegionAnalysisTests.cs @@ -14096,5 +14096,53 @@ static void M(" + refModifier + @"Buffer22 x) Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside)); Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside)); } + + [Fact] + public void RefField_Assignment() + { + var comp = CreateCompilation(""" + ref struct RS + { + ref int ri; + public RS() => ri = 0; + } + """, + targetFramework: TargetFramework.NetCoreApp); + comp.VerifyEmitDiagnostics( + // (4,20): warning CS9201: ref field 'ri' should be ref-assigned before use. + // public RS() => ri = 0; + Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "ri").WithArguments("ri").WithLocation(4, 20)); + + var tree = comp.CommonSyntaxTrees[0]; + var model = comp.GetSemanticModel(tree); + var assignment = tree.GetRoot().DescendantNodes().OfType().Single(); + + var flowAnalysis = model.AnalyzeDataFlow(assignment); + Assert.Equal("this", GetSymbolNamesJoined(flowAnalysis.ReadInside)); + Assert.Equal("this", GetSymbolNamesJoined(flowAnalysis.WrittenInside)); + } + + [Fact] + public void RefField_RefAssignment() + { + var comp = CreateCompilation(""" + ref struct RS + { + ref int ri; + public unsafe RS() => ri = ref *default(int*); + } + """, + targetFramework: TargetFramework.NetCoreApp, + options: TestOptions.UnsafeDebugDll); + comp.VerifyEmitDiagnostics(); + + var tree = comp.CommonSyntaxTrees[0]; + var model = comp.GetSemanticModel(tree); + var assignment = tree.GetRoot().DescendantNodes().OfType().Single(); + + var flowAnalysis = model.AnalyzeDataFlow(assignment); + Assert.Null(GetSymbolNamesJoined(flowAnalysis.ReadInside)); + Assert.Equal("this", GetSymbolNamesJoined(flowAnalysis.WrittenInside)); + } } } From c90bb9a61a8e2e90710efeb5cdd34ea795e6a41c Mon Sep 17 00:00:00 2001 From: Rikki Gibson Date: Tue, 1 Aug 2023 10:11:29 -0700 Subject: [PATCH 8/9] Address feedback --- .../CSharp/Portable/CSharpResources.resx | 4 +- .../Portable/xlf/CSharpResources.cs.xlf | 8 ++-- .../Portable/xlf/CSharpResources.de.xlf | 8 ++-- .../Portable/xlf/CSharpResources.es.xlf | 8 ++-- .../Portable/xlf/CSharpResources.fr.xlf | 8 ++-- .../Portable/xlf/CSharpResources.it.xlf | 8 ++-- .../Portable/xlf/CSharpResources.ja.xlf | 8 ++-- .../Portable/xlf/CSharpResources.ko.xlf | 8 ++-- .../Portable/xlf/CSharpResources.pl.xlf | 8 ++-- .../Portable/xlf/CSharpResources.pt-BR.xlf | 8 ++-- .../Portable/xlf/CSharpResources.ru.xlf | 8 ++-- .../Portable/xlf/CSharpResources.tr.xlf | 8 ++-- .../Portable/xlf/CSharpResources.zh-Hans.xlf | 8 ++-- .../Portable/xlf/CSharpResources.zh-Hant.xlf | 8 ++-- .../Emit2/FlowAnalysis/RegionAnalysisTests.cs | 6 +-- .../Test/Semantic/Semantics/RefFieldTests.cs | 37 +++++++++++++++---- 16 files changed, 86 insertions(+), 65 deletions(-) diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 01609dec4e62a..122215e476dd4 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -7785,9 +7785,9 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ Reference kind modifier of parameter doesn't match the corresponding parameter in target. - ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. - ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. \ No newline at end of file diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index 1055956485b90..1843746b93f2a 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -4993,13 +4993,13 @@ - ref field '{0}' should be ref-assigned before use. - ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. - ref field should be ref-assigned before use. - ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index eadb249b470ab..cdaa8b3aef881 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -4993,13 +4993,13 @@ - ref field '{0}' should be ref-assigned before use. - ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. - ref field should be ref-assigned before use. - ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index f0f40073c4fb8..76b2a0c417491 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -4993,13 +4993,13 @@ - ref field '{0}' should be ref-assigned before use. - ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. - ref field should be ref-assigned before use. - ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index 575c18867b4e0..e1c47664245ba 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -4993,13 +4993,13 @@ - ref field '{0}' should be ref-assigned before use. - ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. - ref field should be ref-assigned before use. - ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index b15f898bb69c5..c029d795c5f74 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -4993,13 +4993,13 @@ target:module Compila un modulo che può essere aggiunto ad altro - ref field '{0}' should be ref-assigned before use. - ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. - ref field should be ref-assigned before use. - ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index a64e85fd68f11..97785aec3af7d 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -4993,13 +4993,13 @@ - ref field '{0}' should be ref-assigned before use. - ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. - ref field should be ref-assigned before use. - ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index 35895ea33480f..b60c0da2ba4bf 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -4993,13 +4993,13 @@ - ref field '{0}' should be ref-assigned before use. - ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. - ref field should be ref-assigned before use. - ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 33c3a4fa147d5..01727554eb8d6 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -4993,13 +4993,13 @@ - ref field '{0}' should be ref-assigned before use. - ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. - ref field should be ref-assigned before use. - ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index 12303a2736e3f..aa4ceb2dd9658 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -4993,13 +4993,13 @@ - ref field '{0}' should be ref-assigned before use. - ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. - ref field should be ref-assigned before use. - ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index 6b4139144fb4d..87e41d20ba602 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -4993,13 +4993,13 @@ - ref field '{0}' should be ref-assigned before use. - ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. - ref field should be ref-assigned before use. - ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index ec9f85d4cb26b..684ad19037f43 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -4993,13 +4993,13 @@ - ref field '{0}' should be ref-assigned before use. - ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. - ref field should be ref-assigned before use. - ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index aff896a4be37b..059ad18d226ec 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -4993,13 +4993,13 @@ - ref field '{0}' should be ref-assigned before use. - ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. - ref field should be ref-assigned before use. - ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index e4da1a386d141..9873ee020c49a 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -4993,13 +4993,13 @@ strument:TestCoverage 產生檢測要收集 - ref field '{0}' should be ref-assigned before use. - ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. + Ref field '{0}' should be ref-assigned before use. - ref field should be ref-assigned before use. - ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. + Ref field should be ref-assigned before use. diff --git a/src/Compilers/CSharp/Test/Emit2/FlowAnalysis/RegionAnalysisTests.cs b/src/Compilers/CSharp/Test/Emit2/FlowAnalysis/RegionAnalysisTests.cs index 5c5751aa4f4f8..70ac8531881e7 100644 --- a/src/Compilers/CSharp/Test/Emit2/FlowAnalysis/RegionAnalysisTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/FlowAnalysis/RegionAnalysisTests.cs @@ -14097,7 +14097,7 @@ static void M(" + refModifier + @"Buffer22 x) Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside)); } - [Fact] + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69148")] public void RefField_Assignment() { var comp = CreateCompilation(""" @@ -14109,7 +14109,7 @@ ref struct RS """, targetFramework: TargetFramework.NetCoreApp); comp.VerifyEmitDiagnostics( - // (4,20): warning CS9201: ref field 'ri' should be ref-assigned before use. + // (4,20): warning CS9201: Ref field 'ri' should be ref-assigned before use. // public RS() => ri = 0; Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "ri").WithArguments("ri").WithLocation(4, 20)); @@ -14122,7 +14122,7 @@ ref struct RS Assert.Equal("this", GetSymbolNamesJoined(flowAnalysis.WrittenInside)); } - [Fact] + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69148")] public void RefField_RefAssignment() { var comp = CreateCompilation(""" diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs index 102c1d37a1d4d..2ffa271b0446d 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs @@ -29549,7 +29549,7 @@ static ref int Local2(ref int x2, int y2) Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(27, 2)); } - [Fact] + [ConditionalFact(typeof(CoreClrOnly)), WorkItem("https://github.com/dotnet/roslyn/issues/69148")] public void RefField_Assignment_AutoDefault_01() { var verifier = CompileAndVerify(""" @@ -29576,7 +29576,7 @@ ref struct RS expectedOutput: "1"); verifier.VerifyDiagnostics( - // (15,20): warning CS9201: 'ref' field 'ri' should be ref-assigned before use. + // (15,20): warning CS9201: Ref field 'ri' should be ref-assigned before use. // public RS() => ri = 0; Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "ri").WithArguments("ri").WithLocation(15, 20)); @@ -29597,7 +29597,7 @@ .maxstack 2 """); } - [Fact] + [ConditionalFact(typeof(CoreClrOnly)), WorkItem("https://github.com/dotnet/roslyn/issues/69148")] public void RefField_Assignment_AutoDefault_02() { var verifier = CompileAndVerify(""" @@ -29633,7 +29633,7 @@ public RS() // (15,12): warning CS9022: Control is returned to caller before field 'RS.ri' is explicitly assigned, causing a preceding implicit assignment of 'default'. // public RS() Diagnostic(ErrorCode.WRN_UnassignedThisSupportedVersion, "RS").WithArguments("RS.ri").WithLocation(15, 12), - // (17,21): warning CS9201: 'ref' field 'ri' should be ref-assigned before use. + // (17,21): warning CS9201: Ref field 'ri' should be ref-assigned before use. // int local = ri; // 1 Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "ri").WithArguments("ri").WithLocation(17, 21)); @@ -29656,7 +29656,7 @@ .locals init (int V_0) //local """); } - [Fact] + [ConditionalFact(typeof(CoreClrOnly)), WorkItem("https://github.com/dotnet/roslyn/issues/69148")] public void RefField_Assignment_AutoDefault_03() { var verifier = CompileAndVerify(""" @@ -29695,10 +29695,10 @@ public RS(bool ignored) expectedOutput: "12"); verifier.VerifyDiagnostics( - // (20,29): warning CS9201: ref field 'ri' should be ref-assigned before use. + // (20,29): warning CS9201: Ref field 'ri' should be ref-assigned before use. // ref int local = ref ri; // 1 Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "ri").WithArguments("ri").WithLocation(20, 29), - // (25,29): warning CS9201: ref field 'ri' should be ref-assigned before use. + // (25,29): warning CS9201: Ref field 'ri' should be ref-assigned before use. // ref int local = ref ri; // 2 Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "ri").WithArguments("ri").WithLocation(25, 29)); @@ -29720,7 +29720,7 @@ .locals init (int& V_0) //local """); } - [Fact] + [ConditionalFact(typeof(CoreClrOnly)), WorkItem("https://github.com/dotnet/roslyn/issues/69148")] public void RefField_Assignment_AutoDefault_04() { var verifier = CompileAndVerify(""" @@ -29756,5 +29756,26 @@ public RS(ref int ri, bool ignored) verifier.VerifyDiagnostics(); } + + [ConditionalFact(typeof(CoreClrOnly)), WorkItem("https://github.com/dotnet/roslyn/issues/69148")] + public void RefField_Assignment_AutoDefault_05() + { + var comp = CreateCompilation(""" + ref struct RS + { + ref readonly int ri; + public RS() => ri = 0; + } + """, + targetFramework: TargetFramework.NetCoreApp); + + comp.VerifyDiagnostics( + // (4,20): error CS8331: Cannot assign to field 'ri' or use it as the right hand side of a ref assignment because it is a readonly variable + // public RS() => ri = 0; + Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "ri").WithArguments("field", "ri").WithLocation(4, 20), + // (4,20): warning CS9201: Ref field 'ri' should be ref-assigned before use. + // public RS() => ri = 0; + Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "ri").WithArguments("ri").WithLocation(4, 20)); + } } } From 76d34cf7f9cdb8ecfc2fd3ecfaf48b88eb021dc9 Mon Sep 17 00:00:00 2001 From: Rikki Gibson Date: Tue, 1 Aug 2023 11:49:44 -0700 Subject: [PATCH 9/9] Fix baseline comment --- src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs index 2ffa271b0446d..774b169a26bb3 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs @@ -29634,7 +29634,7 @@ public RS() // public RS() Diagnostic(ErrorCode.WRN_UnassignedThisSupportedVersion, "RS").WithArguments("RS.ri").WithLocation(15, 12), // (17,21): warning CS9201: Ref field 'ri' should be ref-assigned before use. - // int local = ri; // 1 + // int local = ri; Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "ri").WithArguments("ri").WithLocation(17, 21)); verifier.VerifyIL("RS..ctor", """