www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3674] New: forward reference error with multiple overloads with same name

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3674

           Summary: forward reference error with multiple overloads with
                    same name
           Product: D
           Version: 2.037
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Keywords: rejects-valid
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: r.sagitario gmx.de


--- Comment #0 from Rainer Schuetze <r.sagitario gmx.de> 2010-01-05 00:24:36
PST ---
The following code fails to compile:

public interface IQGraphicsItem
{
    public QGraphicsObject toGraphicsObject();
    public QGraphicsObject toGraphicsObject() const;
}

public class QGraphicsLineItem : IQGraphicsItem
{
    public final QGraphicsObject toGraphicsObject() { return null; } // Line 10
    public final QGraphicsObject toGraphicsObject() const { return null; }
}

public abstract class QGraphicsObject : IQGraphicsItem // line 14
{
    public final QGraphicsObject toGraphicsObject() { return null; }
    public final QGraphicsObject toGraphicsObject() const { return null; }
}

with error:

test.d(14): Error: class test.QGraphicsObject base class is forward referenced
by QGraphicsObject

Actually the error is caused on by the reference in line 11.
The error does not happen there is only a single method toGraphicsObject().

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 05 2010
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3674


Rainer Schuetze <r.sagitario gmx.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch


--- Comment #1 from Rainer Schuetze <r.sagitario gmx.de> 2010-01-05 00:36:08
PST ---
The error occurs when dmd tries to match the overloaded member function to the
functions in the base class, but hits the slightly different prototype. It then
tries to check the return type for covariance, which fails on the forward
referenced class.

here's a patch (or maybe just a workaround as I'm not perfectly sure what this
does to erronous declarations), but it also fixes the problem, if the return
type is actually a forward referenced covariant class.

Index: func.c
===================================================================
--- func.c    (revision 324)
+++ func.c    (working copy)
   -510,9 +510,20   
             /* Only need to have a tintro if the vptr
              * offsets differ
              */
+            unsigned errors = global.errors;
+            global.gag++;            // suppress printing of error messages
             int offset;
-            if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset))
+            int baseOf = fdv->type->nextOf()->isBaseOf(type->nextOf(),
&offset);
+            global.gag--;            // suppress printing of error messages
+            if(errors != global.errors)
             {
+                // any error in isBaseOf() is a forward reference error, so we
bail out
+                global.errors = errors;
+                cd->sizeok = 2;    // can't finish due to forward reference
+                return;
+            }
+            if (baseOf)
+            {
                 ti = fdv->type;
 #if 0
                 if (offset)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 05 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3674


Eldar Insafutdinov <e.insafutdinov gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |e.insafutdinov gmail.com


--- Comment #2 from Eldar Insafutdinov <e.insafutdinov gmail.com> 2010-01-06
00:14:03 PST ---
As it implies from the testcase this is a blocker for QtD.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 06 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3674


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla digitalmars.com


--- Comment #3 from Walter Bright <bugzilla digitalmars.com> 2010-01-17
23:55:32 PST ---
Changeset 338

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 17 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3674



--- Comment #4 from Rainer Schuetze <r.sagitario gmx.de> 2010-01-20 14:48:34
PST ---
The current revision (342) now shows a different error, even with a slightly
reduced test case:

public class IQGraphicsItem
{
    public QGraphicsObject toGraphicsObject();
    public QGraphicsObject toGraphicsObject() const;
}

public abstract class QGraphicsObject : IQGraphicsItem
{
    public final QGraphicsObject toGraphicsObject() { return null; }  // Line
10
    public final QGraphicsObject toGraphicsObject() const { return null; } //
Line 11
}

and causes
test.d(11): Error: function test.QGraphicsObject.toGraphicsObject cannot
override final function test.QGraphicsObject.toGraphicsObject

This is what happens:
dmd searches its vtbl for a covariant function that is overridden by
"toGraphicsObject() const". The rules in Type::covariant() state, that it's ok
to match the non-const version of toGraphicsObject(). This triggers two
problems:

- The first match is taken, not the best.
- The class's vtbl is searched, not the vtbl of the base class. As the
non-const version of the function is already matched and placed into the vtbl,
the function type might have changed due to covariance. In this case, it is
final now.

Here's a patch to solve both issues:

Index: func.c
===================================================================
--- func.c    (revision 342)
+++ func.c    (working copy)
   -382,7 +382,7   
     }

     // Find index of existing function in vtbl[] to override
-    vi = findVtblIndex(&cd->vtbl, cd->baseClass ? cd->baseClass->vtbl.dim :
0);
+    vi = cd->baseClass ? findVtblIndex(&cd->baseClass->vtbl,
cd->baseClass->vtbl.dim) : -1;
     switch (vi)
     {
         case -1:
   -426,7 +426,7   
         return;

         default:
-        {   FuncDeclaration *fdv = (FuncDeclaration *)cd->vtbl.data[vi];
+        {   FuncDeclaration *fdv = (FuncDeclaration
*)cd->baseClass->vtbl.data[vi];
         // This function is covariant with fdv
         if (fdv->isFinal())
             error("cannot override final function %s", fdv->toPrettyChars());
   -1689,11 +1689,15   

 int FuncDeclaration::findVtblIndex(Array *vtbl, int dim)
 {
+    FuncDeclaration *mismatch = 0;
+    int bestvi = -1;
     for (int vi = 0; vi < dim; vi++)
     {
     FuncDeclaration *fdv = ((Dsymbol *)vtbl->data[vi])->isFuncDeclaration();
     if (fdv && fdv->ident == ident)
     {
+        if (type->equals(fdv->type))
+        return vi;
         int cov = type->covariant(fdv->type);
         //printf("\tbaseclass cov = %d\n", cov);
         switch (cov)
   -1702,14 +1706,15   
             break;

         case 1:
-            return vi;
+            bestvi = vi; // covariant, but not identical
+            break;

         case 2:
+            if(!mismatch) // give a second chance to find exact match
+            mismatch = fdv;
             //type->print();
             //fdv->type->print();
             //printf("%s %s\n", type->deco, fdv->type->deco);
-            error("of type %s overrides but is not covariant with %s of type
%s",
-            type->toChars(), fdv->toPrettyChars(), fdv->type->toChars());
             break;

         case 3:
   -1720,7 +1725,10   
         }
     }
     }
-    return -1;
+    if(bestvi < 0 && mismatch)
+    error("of type %s overrides but is not covariant with %s of type %s",
+        type->toChars(), mismatch->toPrettyChars(),
mismatch->type->toChars());
+    return bestvi;
 }

 /****************************************************

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 20 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3674



--- Comment #5 from Eldar Insafutdinov <e.insafutdinov gmail.com> 2010-01-21
13:37:38 PST ---
When fixing this also make sure this testcase passes:

public class IQGraphicsItem
{
    public QGraphicsObject toGraphicsObject();
    public const(QGraphicsObject) toGraphicsObject() const;
}

public abstract class QGraphicsObject : IQGraphicsItem
{
    public final QGraphicsObject toGraphicsObject() { return null; }
    public final const(QGraphicsObject) toGraphicsObject() const { return null;
}
}

As it currently doesn't, with a different error message.

Thanks.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 21 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3674



--- Comment #6 from Walter Bright <bugzilla digitalmars.com> 2010-01-21
20:21:23 PST ---
Changeset 344 for second problem.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 21 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3674



--- Comment #7 from Rainer Schuetze <r.sagitario gmx.de> 2010-01-22 00:39:03
PST ---
Thanks, it works now. This also fixes issue 3282 which is what happened if you
did not use "final" to produce an error at compile time. See comments there for
another quirk.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 22 2010
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3674


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED


--- Comment #8 from Walter Bright <bugzilla digitalmars.com> 2010-01-30
22:41:16 PST ---
fixed dmd 1.056 and 2.040

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 30 2010