Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Fix Issue 7322 -- Taking address of deprecated functions isn't refused #1064

Closed
wants to merge 1 commit into from

8 participants

edmccard Daniel Murphy Hara Kenji David Nadlinger Don Clugston Andrei Alexandrescu Walter Bright Andrej Mitrovic
Daniel Murphy
Collaborator

Please add the test cases that incorrectly fail from the bugzilla report.

Hara Kenji
Collaborator

@edmccard : Can you merge small fail_compilation tests into one module with TEST_OUTPUT feature?

David Nadlinger
Collaborator

@9rnsr: In case of deprecation warnings, this might work, but in general, I'd prefer them to stay as separate tests. You simply can't test if the compiler exits with a failure for multiple tests in one compilation run, and grepping for all of them in the output might cause problems if we ever change how many error messages are displayed. Hm, maybe using multiple -versions might be a bulletproof way to merge multiple fail_compilation tests together? Would need an extension to d_do_test, though.

Hara Kenji
Collaborator

Yes, in general case that way will not work, but a deprecation error does not change the semantics of its later code, so compiler should warn all deprecation uses in one compilation. Then, squashing tests to one module with TEST_OUTPUT can represent such dmd's diagnostic output specification.

edmccard

I'll have to do some more work. I thought it was working in the case "auto x = &y" but it isn't; I should have time to fix it in the next day or two. Then I'll be able to add the test case from the bug report. I will also consolidate the tests and use TEST_OUTPUT.

edmccard

Sorry for the delay. The issue was not with auto declarations, but with template functions. At the beginning of SymOffExp::castTo (here: edmccard@4c497d9#L0L1467) was a test:

if (type == t && hasOverloads == 0) 
    return this;

As far as I can tell, this is only reached when template functions are involved? Removing it allows the test case from the bug report, with &rjustify!string, to pass. and it passes the test suite.

Was there a reason to skip the rest of castTo for template functions (or other things where hasOverloads == 0), or is it safe to remove the check?

(Also, the fail_compliation tests have been consolidated to use TEST_OUTPUT)

Don Clugston
Collaborator

Please remove the import of std.string from the test case. Ideally no tests should use Phobos. Removing all the existing ones would be a pain but we should certainly not introduce any new tests involving it. Your output test includes a deprecation warning, that is definitely going to be removed and will change. If you need to, create a module with a function in it with the same signature as what you're using in the test.

edmccard

Rebased, and changed the template function test to use a top-level function in the test source, instead of from std.string.

test/fail_compilation/fail7322.d
((2 lines not shown))
  2
+TEST_OUTPUT:
  3
+---
  4
+fail_compilation/fail7322.d(25): Deprecation: function fail7322.f1 is deprecated
  5
+fail_compilation/fail7322.d(26): Deprecation: function fail7322.f2 is deprecated
  6
+fail_compilation/fail7322.d(28): Deprecation: function fail7322.f1 is deprecated
  7
+fail_compilation/fail7322.d(29): Deprecation: function fail7322.f2 is deprecated
  8
+fail_compilation/fail7322.d(32): Deprecation: function fail7322.A1.f is deprecated
  9
+fail_compilation/fail7322.d(35): Deprecation: function fail7322.A2.f is deprecated
  10
+fail_compilation/fail7322.d(38): Deprecation: function fail7322.A1.f is deprecated
  11
+fail_compilation/fail7322.d(41): Deprecation: function fail7322.A2.f is deprecated
  12
+fail_compilation/fail7322.d(43): Deprecation: function std.string.rjustify!(string).rjustify is deprecated - Please use std.string.rightJustify instead.
  13
+---
  14
+*/
  15
+
  16
+#line 1
  17
+import std.string;
1
Andrej Mitrovic Collaborator

The import is still here, maybe you forgot to commit before a push -f?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
edmccard

@AndrejMitrovic, looks like that's what I did. Fixed now.

Don Clugston donc commented on the diff November 22, 2012
test/fail_compilation/fail7322.d
((46 lines not shown))
  46
+    f4(&f2);
  47
+
  48
+    auto a1 = new A1();
  49
+    void delegate(float) dg1 = &a1.f;
  50
+
  51
+    auto a2 = new A2();
  52
+    void delegate() dg2 = &a2.f;
  53
+
  54
+    auto a3 = new A1();
  55
+    f5(&a3.f);
  56
+
  57
+    auto a4 = new A2();
  58
+    f6(&a4.f);
  59
+
  60
+    auto fp3 = &f7!string;
  61
+    f4(&f7!string);
1
Don Clugston Collaborator
donc added a note November 22, 2012

Sorry for dragging this on so long, but could you please add a test corresponding to Kenji's comment 4. Eg, right here add:

void function(int) shouldbeok = &f1;

which shouldn't generate any new errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Andrei Alexandrescu
Owner

ping?

Andrei Alexandrescu
Owner

reping - will close in one week

Hara Kenji
Collaborator
9rnsr commented July 04, 2013

I added bug 7322 fix in #2130 - deprecated attribute check should be deferred until one of overloaded function is exactly picked up.

Walter Bright

@9rnsr does that mean this should be close?

Hara Kenji
Collaborator
Hara Kenji 9rnsr closed this January 04, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
14  src/cast.c
@@ -1464,8 +1464,6 @@ Expression *SymOffExp::castTo(Scope *sc, Type *t)
1464 1464
     printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n",
1465 1465
         toChars(), type->toChars(), t->toChars());
1466 1466
 #endif
1467  
-    if (type == t && hasOverloads == 0)
1468  
-        return this;
1469 1467
     Expression *e;
1470 1468
     Type *tb = t->toBasetype();
1471 1469
     Type *typeb = type->toBasetype();
@@ -1474,8 +1472,7 @@ Expression *SymOffExp::castTo(Scope *sc, Type *t)
1474 1472
         // Look for pointers to functions where the functions are overloaded.
1475 1473
         FuncDeclaration *f;
1476 1474
 
1477  
-        if (hasOverloads &&
1478  
-            typeb->ty == Tpointer && typeb->nextOf()->ty == Tfunction &&
  1475
+        if (typeb->ty == Tpointer && typeb->nextOf()->ty == Tfunction &&
1479 1476
             (tb->ty == Tpointer || tb->ty == Tdelegate) && tb->nextOf()->ty == Tfunction)
1480 1477
         {
1481 1478
             f = var->isFuncDeclaration();
@@ -1510,6 +1507,7 @@ Expression *SymOffExp::castTo(Scope *sc, Type *t)
1510 1507
                         e = new SymOffExp(loc, f, 0);
1511 1508
                         e->type = t;
1512 1509
                     }
  1510
+                    checkDeprecated(sc, f);
1513 1511
 #if DMDV2
1514 1512
                     f->tookAddressOf++;
1515 1513
 #endif
@@ -1520,7 +1518,10 @@ Expression *SymOffExp::castTo(Scope *sc, Type *t)
1520 1518
         e = Expression::castTo(sc, t);
1521 1519
     }
1522 1520
     else
1523  
-    {   e = copy();
  1521
+    {   FuncDeclaration *f = var->isFuncDeclaration();
  1522
+        if (f)
  1523
+            checkDeprecated(sc, f);
  1524
+        e = copy();
1524 1525
         e->type = t;
1525 1526
         ((SymOffExp *)e)->hasOverloads = 0;
1526 1527
     }
@@ -1553,6 +1554,7 @@ Expression *DelegateExp::castTo(Scope *sc, Type *t)
1553 1554
                 {   int offset;
1554 1555
                     if (f->tintro && f->tintro->nextOf()->isBaseOf(f->type->nextOf(), &offset) && offset)
1555 1556
                         error("%s", msg);
  1557
+                    checkDeprecated(sc, f);
1556 1558
                     f->tookAddressOf++;
1557 1559
                     e = new DelegateExp(loc, e1, f);
1558 1560
                     e->type = t;
@@ -1566,7 +1568,7 @@ Expression *DelegateExp::castTo(Scope *sc, Type *t)
1566 1568
     }
1567 1569
     else
1568 1570
     {   int offset;
1569  
-
  1571
+        checkDeprecated(sc, func);
1570 1572
         func->tookAddressOf++;
1571 1573
         if (func->tintro && func->tintro->nextOf()->isBaseOf(func->type->nextOf(), &offset) && offset)
1572 1574
             error("%s", msg);
12  src/expression.c
@@ -1084,6 +1084,18 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
1084 1084
                         arg = arg->implicitCastTo(sc, p->type);
1085 1085
                     arg = arg->optimize(WANTvalue);
1086 1086
                 }
  1087
+                else if (arg->op == TOKsymoff)
  1088
+                {
  1089
+                    SymOffExp *se = (SymOffExp *)arg;
  1090
+                    FuncDeclaration *f = se->var->isFuncDeclaration();
  1091
+                    if (f)
  1092
+                        f->checkDeprecated(loc, sc);
  1093
+                }
  1094
+                else if (arg->op == TOKdelegate)
  1095
+                {
  1096
+                    DelegateExp *de = (DelegateExp *)arg;
  1097
+                    de->func->checkDeprecated(loc, sc);
  1098
+                }
1087 1099
             }
1088 1100
             if (p->storageClass & STCref)
1089 1101
             {
62  test/fail_compilation/fail7322.d
... ...
@@ -0,0 +1,62 @@
  1
+/*
  2
+TEST_OUTPUT:
  3
+---
  4
+fail_compilation/fail7322.d(25): Deprecation: function fail7322.f1 is deprecated
  5
+fail_compilation/fail7322.d(26): Deprecation: function fail7322.f2 is deprecated
  6
+fail_compilation/fail7322.d(28): Deprecation: function fail7322.f1 is deprecated
  7
+fail_compilation/fail7322.d(29): Deprecation: function fail7322.f2 is deprecated
  8
+fail_compilation/fail7322.d(32): Deprecation: function fail7322.A1.f is deprecated
  9
+fail_compilation/fail7322.d(35): Deprecation: function fail7322.A2.f is deprecated
  10
+fail_compilation/fail7322.d(38): Deprecation: function fail7322.A1.f is deprecated
  11
+fail_compilation/fail7322.d(41): Deprecation: function fail7322.A2.f is deprecated
  12
+fail_compilation/fail7322.d(43): Deprecation: function fail7322.f7!(string).f7 is deprecated
  13
+fail_compilation/fail7322.d(44): Deprecation: function fail7322.f7!(string).f7 is deprecated
  14
+---
  15
+*/
  16
+
  17
+#line 1
  18
+void f1(int a) {}
  19
+deprecated void f1(float a) {}
  20
+deprecated void f2() {}
  21
+
  22
+class A1
  23
+{
  24
+    void f(int a) {}
  25
+    deprecated void f(float a) {}
  26
+}
  27
+
  28
+class A2
  29
+{
  30
+    deprecated void f() {}
  31
+}
  32
+
  33
+void f3(void function(float) fp) {}
  34
+void f4(void function() fp) {}
  35
+void f5(void delegate(float) dg) {}
  36
+void f6(void delegate() dg) {}
  37
+
  38
+deprecated void f7(T)() {}
  39
+
  40
+void main()
  41
+{
  42
+    void function(float) fp1 = &f1;
  43
+    void function() fp2 = &f2;
  44
+
  45
+    f3(&f1);
  46
+    f4(&f2);
  47
+
  48
+    auto a1 = new A1();
  49
+    void delegate(float) dg1 = &a1.f;
  50
+
  51
+    auto a2 = new A2();
  52
+    void delegate() dg2 = &a2.f;
  53
+
  54
+    auto a3 = new A1();
  55
+    f5(&a3.f);
  56
+
  57
+    auto a4 = new A2();
  58
+    f6(&a4.f);
  59
+
  60
+    auto fp3 = &f7!string;
  61
+    f4(&f7!string);
  62
+}
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.