Bug 319224 (MONO76363) - [GMCS] generic interface which has a recursive parameter crashes
Summary: [GMCS] generic interface which has a recursive parameter crashes
Status: RESOLVED FIXED
Alias: MONO76363
Product: Mono: Compilers
Classification: Mono
Component: C# (show other bugs)
Version: 1.1
Hardware: Other Other
: P3 - Medium : Normal
Target Milestone: ---
Assignee: Martin Baulig
QA Contact: Mono Bugs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-10-07 20:08 UTC by Atsushi Enomoto
Modified: 2007-09-15 21:24 UTC (History)
0 users

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Wiest 2007-09-15 19:33:51 UTC


---- Reported by atsushi@ximian.com 2005-10-07 13:08:44 MST ----

Compile the two lines below:

public interface IFoo<T> where T : IFoo<T> { }
public interface IBaz<T> where T : IFoo<T> { }


Actual Results:

Unhandled Exception: System.NullReferenceException: Object reference not
set to an instance of an object
in <0x00069> Mono.CSharp.Convert:TypeParam_EffectiveBaseType
(Mono.CSharp.EmitContext ec, Mono.CSharp.GenericConstraints gc)
in <0x000af> Mono.CSharp.Convert:ImplicitTypeParameterConversion
(Mono.CSharp.EmitContext ec, Mono.CSharp.Expression expr, System.Type
target_type)
in <0x00061> Mono.CSharp.Convert:ImplicitReferenceConversionExists
(Mono.CSharp.EmitContext ec, Mono.CSharp.Expression expr, System.Type
target_type)
in <0x003cd> Mono.CSharp.Convert:ImplicitStandardConversionExists
(Mono.CSharp.EmitContext ec, Mono.CSharp.Expression expr, System.Type
target_type)
in <0x0016f> Mono.CSharp.ConstructedType:CheckConstraint
(Mono.CSharp.EmitContext ec, System.Type ptype, Mono.CSharp.Expression
expr, System.Type ctype)
in <0x00430> Mono.CSharp.ConstructedType:CheckConstraints
(Mono.CSharp.EmitContext ec, Int32 index)
in <0x00018> Mono.CSharp.ConstructedType:CheckConstraints
(Mono.CSharp.EmitContext ec)
in <0x00125> Mono.CSharp.Expression:ResolveAsTypeTerminal
(Mono.CSharp.EmitContext ec, Boolean silent)
in <0x00010> Mono.CSharp.Expression:ResolveAsTypeTerminal
(Mono.CSharp.EmitContext ec)
in <0x006c7> Mono.CSharp.Constraints:ResolveTypes (Mono.CSharp.EmitContextec)
in <0x0001d> Mono.CSharp.TypeParameter:ResolveType (Mono.CSharp.EmitContextec)
in <0x00031> Mono.CSharp.TypeParameter:DefineType (Mono.CSharp.EmitContext
ec, System.Reflection.Emit.MethodBuilder builder,
System.Reflection.MethodInfo implementing, Boolean is_override)
in <0x00013> Mono.CSharp.TypeParameter:DefineType (Mono.CSharp.EmitContextec)
in <0x00316> Mono.CSharp.TypeContainer:ResolveType ()
in <0x000dd> Mono.CSharp.RootContext:PopulateTypes ()
in <0x00b7b> Mono.CSharp.Driver:MainDriver (System.String[] args)
in <0x00051> Mono.CSharp.Driver:Main (System.String[] args)

Expected Results:

no error except for "entrypoint not found".

How often does this happen? 

consistently.

Additional Information:

- When we remove the second line, it does not happen.
- When we remove either of "where" clause, it does not happen.
- Such interfaces could make sense e.g. with
    class Foo : IFoo<Foo> {}
    class Bar : IFoo<Foo> {}
- csc compiles it without error (except for entrypoint stuff).



---- Additional Comments From martin@ximian.com 2005-10-20 00:24:27 MST ----

Backtrace with line numbers:

=====
(mdb) frame
#0: 0x404b0a29 in
Mono.CSharp.Convert.TypeParam_EffectiveBaseType(Mono.CSharp.EmitContext,Mono.CSharp.GenericConstraints)+0x91
at /work/rohan/mono/mcs/gmcs/convert.cs:64
  64                    foreach (Type t in gc.InterfaceConstraints) {
(mdb) bt
(*) #0: 0x404b0a29 in
Mono.CSharp.Convert.TypeParam_EffectiveBaseType(Mono.CSharp.EmitContext,Mono.CSharp.GenericConstraints)+0x91
at /work/rohan/mono/mcs/gmcs/convert.cs:64
    #1: 0x404b072d in
Mono.CSharp.Convert.ImplicitTypeParameterConversion(Mono.CSharp.EmitContext,Mono.CSharp.Expression,System.Type)+0xed
at /work/rohan/mono/mcs/gmcs/convert.cs:90
    #2: 0x404afbfb in
Mono.CSharp.Convert.ImplicitReferenceConversionExists(Mono.CSharp.EmitContext,Mono.CSharp.Expression,System.Type)+0x83
at /work/rohan/mono/mcs/gmcs/convert.cs:270
    #3: 0x404af552 in
Mono.CSharp.Convert.ImplicitStandardConversionExists(Mono.CSharp.EmitContext,Mono.CSharp.Expression,System.Type)+0x86a
at /work/rohan/mono/mcs/gmcs/convert.cs:720
    #4: 0x404ae182 in
Mono.CSharp.ConstructedType.CheckConstraint(Mono.CSharp.EmitContext,System.Type,Mono.CSharp.Expression,System.Type)+0x202
at /work/rohan/mono/mcs/gmcs/generic.cs:1332
    #5: 0x404aa87e in
Mono.CSharp.ConstructedType.CheckConstraints(Mono.CSharp.EmitContext,System.Int32)+0x64e
at /work/rohan/mono/mcs/gmcs/generic.cs:1405
    #6: 0x404aa1bb in
Mono.CSharp.ConstructedType.CheckConstraints(Mono.CSharp.EmitContext)+0x2b
at /work/rohan/mono/mcs/gmcs/generic.cs:1477
    #7: 0x404a7a48 in
Mono.CSharp.Expression.ResolveAsTypeTerminal(Mono.CSharp.EmitContext,System.Boolean)+0x1d8
at /work/rohan/mono/mcs/gmcs/ecore.cs:272
    #8: 0x404a7867 in
Mono.CSharp.Expression.ResolveAsTypeTerminal(Mono.CSharp.EmitContext)+0x27
at /work/rohan/mono/mcs/gmcs/ecore.cs:247
    #9: 0x404a93f7 in
Mono.CSharp.Constraints.ResolveTypes(Mono.CSharp.EmitContext)+0x8ef at
/work/rohan/mono/mcs/gmcs/generic.cs:339
    #10: 0x404a8aa6 in
Mono.CSharp.TypeParameter.ResolveType(Mono.CSharp.EmitContext)+0x2e at
/work/rohan/mono/mcs/gmcs/generic.cs:695
    #11: 0x404a833b in
Mono.CSharp.TypeParameter.DefineType(Mono.CSharp.EmitContext,System.Reflection.Emit.MethodBuilder,System.Reflection.MethodInfo,System.Boolean)+0x7b
at /work/rohan/mono/mcs/gmcs/generic.cs:725
    #12: 0x404a828e in
Mono.CSharp.TypeParameter.DefineType(Mono.CSharp.EmitContext)+0x26 at
/work/rohan/mono/mcs/gmcs/generic.cs:712
    #13: 0x404a3d80 in Mono.CSharp.TypeContainer.ResolveType()+0x480
at /work/rohan/mono/mcs/gmcs/class.cs:1425
    #14: 0x404a2c19 in Mono.CSharp.RootContext.PopulateTypes()+0x169
at /work/rohan/mono/mcs/gmcs/rootcontext.cs:526
    #15: 0x40427982 in
Mono.CSharp.Driver.MainDriver(System.String[])+0x155a at
/work/rohan/mono/mcs/gmcs/driver.cs:1603
    #16: 0x40017ed5 in Mono.CSharp.Driver.Main(System.String[])+0xa5
at /work/rohan/mono/mcs/gmcs/driver.cs:287
(mdb) p (Constraints) gc
(Mono.CSharp.Constraints) {
  name = "T", constraints = 0x007dba28, loc = 0x00b8ff50, attrs = None,
  class_constraint = null, iface_constraints = 0x00834898,
  type_param_constraints = 0x00834870, num_constraints = 1,
  class_constraint_type = null, iface_constraint_types = null,
  effective_base_type = null, resolved = true
}
(mdb) p ((Constraints) gc).iface_constraints
(System.Collections.ArrayList) {
  _size = 1,
  _items = Mono.Debugger.Languages.Mono.MonoArrayObject
[Mono.Debugger.Languages.Mono.MonoArrayType
[System.Object[]]:Mono.Debugger.Languages.Mono.MonoClassType
[System.Object]:1],
  _version = 1
}
(mdb) p ((Constraints) gc).iface_constraints [0]
(Mono.CSharp.ConstructedType) { "IFoo`1<T>" }
=====




---- Additional Comments From atsushi@ximian.com 2005-10-20 00:44:49 MST ----

The problem is that iface_constraints is null at that time. gmcs
misses to call Constraints.Resolve() for IFoo before being used by
IBaz (maybe the CheckConstraints() happens during recursive
reference?). Am not sure where it should be called though.



---- Additional Comments From martin@ximian.com 2005-10-20 00:50:58 MST ----

`iface_constraint_types' is null, not `iface_constraints'.
We need to move this from ResolveTypes() to Resolve()





---- Additional Comments From martin@ximian.com 2005-10-20 00:53:54 MST ----

I have an idea how to fix this, but I'm too tired right now.  I'll go
to bed and have a look at it when I wake up.



---- Additional Comments From martin@ximian.com 2005-10-21 14:12:13 MST ----

Ok, I think I have a fix for this.
We can resolve the types in Constraints.Resolve() and then just check
their constraints in Constraints.ResolveTypes().



---- Additional Comments From martin@ximian.com 2005-10-21 15:04:33 MST ----

Fixed in SVN; added gtest-218.cs.


Unknown operating system unknown. Setting to default OS "Other".