+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
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;
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)