In mcs:
authorRaja R Harinath <harinath@hurrynot.org>
Thu, 12 May 2005 15:04:48 +0000 (15:04 -0000)
committerRaja R Harinath <harinath@hurrynot.org>
Thu, 12 May 2005 15:04:48 +0000 (15:04 -0000)
Fix #74920.
* typemanager.cs (unmanaged_enclosing_types): New.
(IsUnmanagedType): Avoid infloops by using
'unmanaged_enclosing_types' to talk with recursive invocations.

In tests:
* test-378.cs: New test from #74920.

svn path=/trunk/mcs/; revision=44446

mcs/errors/crash0208-9.cs [new file with mode: 0644]
mcs/mcs/ChangeLog
mcs/mcs/typemanager.cs
mcs/tests/ChangeLog
mcs/tests/Makefile
mcs/tests/test-378.cs [new file with mode: 0644]

diff --git a/mcs/errors/crash0208-9.cs b/mcs/errors/crash0208-9.cs
new file mode 100644 (file)
index 0000000..ce33dde
--- /dev/null
@@ -0,0 +1,11 @@
+// cs0208-9.cs: Cannot declare a pointer to a managed type ('Foo')
+// Line: 7
+// Compiler options: -t:library -unsafe
+
+public unsafe struct Foo
+{
+        public Foo *foo;
+       string x;
+}
+
+
index 412a68623a87c41e7a531505a68078a6c3802dec..c4b35269dd8003c18f0c2164823a882012107b3f 100644 (file)
@@ -1,3 +1,10 @@
+2005-05-12  Raja R Harinath  <harinath@gmail.com>
+
+       Fix #74920.
+       * typemanager.cs (unmanaged_enclosing_types): New.
+       (IsUnmanagedType): Avoid infloops by using
+       'unmanaged_enclosing_types' to talk with recursive invocations.
+
 2005-05-11  Duncan Mak  <duncan@novell.com>
 
        * cs-tokenizer.cs (get_cmd_arg): Check that 'c' is not -1 before
index 833cc0378603b0cdf3f15dc8bbabd37e43918ea0..a90318af1d2c91863ea469584c92f69e9555ce48 100644 (file)
@@ -1526,11 +1526,17 @@ public class TypeManager {
                return false;
        }
 
+       static Stack unmanaged_enclosing_types = new Stack (4);
+
        //
        // Whether a type is unmanaged.  This is used by the unsafe code (25.2)
        //
        public static bool IsUnmanagedType (Type t)
        {
+               // Avoid infloops in the case of: unsafe struct Foo { Foo *x; }
+               if (unmanaged_enclosing_types.Contains (t))
+                       return true;
+
                // builtins that are not unmanaged types
                if (t == TypeManager.object_type || t == TypeManager.string_type)
                        return false;
@@ -1549,34 +1555,39 @@ public class TypeManager {
                if (!IsValueType (t))
                        return false;
 
+               unmanaged_enclosing_types.Push (t);
+
+               bool retval = true;
+
                if (t is TypeBuilder){
                        TypeContainer tc = LookupTypeContainer (t);
-                       if (tc.Fields == null)
-                               return true;
-                       foreach (Field f in tc.Fields){
-                               // Avoid using f.FieldBuilder: f.Define () may not yet have been invoked.
-                               if ((f.ModFlags & Modifiers.STATIC) != 0)
-                                       continue;
-                               if (f.MemberType == null)
-                                       continue;
-                               if (!IsUnmanagedType (f.MemberType)){
-                                       Report.SymbolRelatedToPreviousError (f.Location, CSharpName (t) + "." + f.Name);
-                                       return false;
+                       if (tc.Fields != null){
+                               foreach (Field f in tc.Fields){
+                                       // Avoid using f.FieldBuilder: f.Define () may not yet have been invoked.
+                                       if ((f.ModFlags & Modifiers.STATIC) != 0)
+                                               continue;
+                                       if (f.MemberType == null)
+                                               continue;
+                                       if (!IsUnmanagedType (f.MemberType)){
+                                               Report.SymbolRelatedToPreviousError (f.Location, CSharpName (t) + "." + f.Name);
+                                               retval = false;
+                                       }
                                }
                        }
-                       return true;
-               }
-               
-               FieldInfo [] fields = t.GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
-
-               foreach (FieldInfo f in fields){
-                       if (!IsUnmanagedType (f.FieldType)){
-                               Report.SymbolRelatedToPreviousError (f);
-                               return false;
+               } else {
+                       FieldInfo [] fields = t.GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
+                       
+                       foreach (FieldInfo f in fields){
+                               if (!IsUnmanagedType (f.FieldType)){
+                                       Report.SymbolRelatedToPreviousError (f);
+                                       retval = false;
+                               }
                        }
                }
 
-               return true;
+               unmanaged_enclosing_types.Pop ();
+
+               return retval;
        }
                
        public static bool IsValueType (Type t)
index ed865502a153a8c7cb335fa2d52fd7a0136decbb..009f82c9811064cce16095ad90e63803a6aa7058 100644 (file)
@@ -1,3 +1,7 @@
+2005-05-12  Raja R Harinath  <harinath@gmail.com>
+
+       * test-378.cs: New test from #74920.
+
 2005-05-09  Raja R Harinath  <rharinath@novell.com>
 
        * Makefile (test-harness-run): Depend on $(TEST_HARNESS_EXTRAS).
index 1b365fd5dc9b7744ff7e737dd13b6706607f95ad..89dffcbe7b779acb455379220145ef0546eb6802 100644 (file)
@@ -34,7 +34,7 @@ USE_MCS_FLAGS :=
 # He may also move some to TEST_EXCLUDE_net_2_0 if some of the merges are inappropriate for GMCS.
 #
 NEW_TEST_SOURCES_common = test-336 test-369 cls-test-6 test-294 \
-       test-372 test-375 test-376 test-377
+       test-372 test-375 test-376 test-377 test-378
 
 #
 # Please do _not_ add any tests here - all new tests should go into NEW_TEST_SOURCES_common
diff --git a/mcs/tests/test-378.cs b/mcs/tests/test-378.cs
new file mode 100644 (file)
index 0000000..7675dd3
--- /dev/null
@@ -0,0 +1,8 @@
+// Compiler options: -t:library -unsafe
+
+public unsafe struct Foo
+{
+        public Foo *foo;
+}
+
+