[mcs] When setting struct empty layout consider compiler generated fields. Fixes...
authorMarek Safar <marek.safar@gmail.com>
Tue, 23 May 2017 06:35:58 +0000 (08:35 +0200)
committerMarek Safar <marek.safar@gmail.com>
Tue, 23 May 2017 06:41:04 +0000 (08:41 +0200)
external/ikvm
mcs/errors/cs0208-19.cs [new file with mode: 0644]
mcs/mcs/class.cs
mcs/mcs/decl.cs
mcs/mcs/property.cs
mcs/tests/test-943.cs [new file with mode: 0644]

index 7c1e61bec8c069b2cc9e214c3094b147d76bbf82..847e05fced5c9a41ff0f24f1f9d40d5a8a5772c1 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 7c1e61bec8c069b2cc9e214c3094b147d76bbf82
+Subproject commit 847e05fced5c9a41ff0f24f1f9d40d5a8a5772c1
diff --git a/mcs/errors/cs0208-19.cs b/mcs/errors/cs0208-19.cs
new file mode 100644 (file)
index 0000000..82b0f43
--- /dev/null
@@ -0,0 +1,20 @@
+// CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type `CS208.Foo'
+// Line: 17
+// Compiler options: -unsafe
+
+namespace CS208
+{
+       public struct Foo
+       {
+               public string PP { get; set; }
+       }
+
+       public class Bar
+       {
+               unsafe static void Main ()
+               {                       
+                       Foo f = new Foo ();
+                       void *s = &f;
+               }
+       }
+}
index 2f2fe4580b400dfc74c80bd59366ceeeada97f71..d1aedad9971215c790a12e6adb52a332cdd52c79 100644 (file)
@@ -639,6 +639,15 @@ namespace Mono.CSharp
                        }
                }
 
+               public bool HasInstanceField {
+                       get {
+                               return (caching_flags & Flags.HasInstanceField) != 0;
+                       }
+                       set {
+                               caching_flags |= Flags.HasInstanceField;
+                       }
+               }
+
                // Indicated whether container has StructLayout attribute set Explicit
                public bool HasExplicitLayout {
                        get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
@@ -848,18 +857,22 @@ namespace Mono.CSharp
                        if ((field.ModFlags & Modifiers.STATIC) != 0)
                                return true;
 
-                       var first_field = PartialContainer.first_nonstatic_field;
-                       if (first_field == null) {
+                       if (!PartialContainer.HasInstanceField) {
+                               PartialContainer.HasInstanceField = true;
                                PartialContainer.first_nonstatic_field = field;
                                return true;
                        }
 
-                       if (Kind == MemberKind.Struct && first_field.Parent != field.Parent) {
-                               Report.SymbolRelatedToPreviousError (first_field.Parent);
-                               Report.Warning (282, 3, field.Location,
-                                       "struct instance field `{0}' found in different declaration from instance field `{1}'",
-                                       field.GetSignatureForError (), first_field.GetSignatureForError ());
+                       if (Kind == MemberKind.Struct) {
+                               var first_field = PartialContainer.first_nonstatic_field;
+                               if (first_field.Parent != field.Parent) {
+                                       Report.SymbolRelatedToPreviousError (first_field.Parent);
+                                       Report.Warning (282, 3, field.Location,
+                                               "struct instance field `{0}' found in different declaration from instance field `{1}'",
+                                               field.GetSignatureForError (), first_field.GetSignatureForError ());
+                               }
                        }
+
                        return true;
                }
 
@@ -1299,7 +1312,7 @@ namespace Mono.CSharp
                        //
                        // Sets .size to 1 for structs with no instance fields
                        //
-                       int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null && !(this is StateMachine) ? 1 : 0;
+                       int type_size = Kind == MemberKind.Struct && !HasInstanceField && !(this is StateMachine) ? 1 : 0;
 
                        var parent_def = Parent as TypeDefinition;
                        if (parent_def == null) {
@@ -2214,6 +2227,10 @@ namespace Mono.CSharp
                                Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (TypeBuilder);
 
 #if STATIC
+                       if (Kind == MemberKind.Struct && HasInstanceField) {
+                               TypeBuilder.__SetLayout (0, 0);
+                       }
+
                        if ((TypeBuilder.Attributes & TypeAttributes.StringFormatMask) == 0 && Module.HasDefaultCharSet)
                                TypeBuilder.__SetAttributes (TypeBuilder.Attributes | Module.DefaultCharSetType);
 #endif
@@ -3146,7 +3163,7 @@ namespace Mono.CSharp
                                return false;
                        }
 
-                       if (first_nonstatic_field != null) {
+                       if (HasInstanceField) {
                                requires_delayed_unmanagedtype_check = true;
 
                                foreach (var member in Members) {
index 340eb488ab08c6a37f1d52cae579f9e7edb38643..0f0b1d1bb69749696d80b025d5da5bf27faf276b 100644 (file)
@@ -290,7 +290,8 @@ namespace Mono.CSharp {
                        HasInstanceConstructor = 1 << 16,
                        HasUserOperators = 1 << 17,
                        CanBeReused = 1 << 18,
-                       InterfacesExpanded = 1 << 19
+                       InterfacesExpanded = 1 << 19,
+                       HasInstanceField = 1 << 20
                }
 
                /// <summary>
index 6b1990e1f0983d87bd8b91d0f60dee7efe51129c..5d831e940b523b144287c7e0d47f0394e3677147 100644 (file)
@@ -820,8 +820,10 @@ namespace Mono.CSharp
                        Parent.PartialContainer.Members.Add (BackingField);
 
                        FieldExpr fe = new FieldExpr (BackingField, Location);
-                       if ((BackingField.ModFlags & Modifiers.STATIC) == 0)
+                       if ((BackingField.ModFlags & Modifiers.STATIC) == 0) {
                                fe.InstanceExpression = new CompilerGeneratedThis (Parent.CurrentType, Location);
+                               Parent.PartialContainer.HasInstanceField = true;
+                       }
 
                        //
                        // Create get block but we careful with location to
diff --git a/mcs/tests/test-943.cs b/mcs/tests/test-943.cs
new file mode 100644 (file)
index 0000000..088e2f7
--- /dev/null
@@ -0,0 +1,19 @@
+using System;
+
+public struct MyStruct
+{
+       public int X { get; set; }
+}
+
+class X
+{
+       public static int Main ()
+       {
+               var s = typeof (MyStruct);
+
+               if (s.StructLayoutAttribute.Size != 0)
+                       return 1;
+
+               return 0;
+       }
+}
\ No newline at end of file