<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - [3.5 Regression] error: destructor reference must be called immediately with '()'"
   href="http://llvm.org/bugs/show_bug.cgi?id=21123">21123</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[3.5 Regression] error: destructor reference must be called immediately with '()'
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>C++
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>david.abdurachmanov@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>dgregor@apple.com, llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre><a href="http://lists.cs.uiuc.edu/pipermail/cfe-dev/2014-October/039371.html">http://lists.cs.uiuc.edu/pipermail/cfe-dev/2014-October/039371.html</a>

After moving to LLVM/Clang 3.5 I have noticed some failures, seems to be coming
from the following (5 years old) commit:
<a href="https://github.com/llvm-mirror/clang/commit/a78c5c34fbd20fde02261c3f3e21933cd58fcc04">https://github.com/llvm-mirror/clang/commit/a78c5c34fbd20fde02261c3f3e21933cd58fcc04</a>

We started getting these kind of errors:

AnalysisDataFormatsTopObjects/a/xr.cc:915:2: error: destructor reference must
be called immediately with '()'
(((::TtDilepEvtSolution*)o)->::TtDilepEvtSolution::~TtDilepEvtSolution)();
 ^
                                                    ()
AnalysisDataFormatsTopObjects/a/xr.cc:915:72: error: called object type 'void'
is not a function or function pointer

Small example below. Why is that only after dtor you **require** next token to
be '('? Yet it's fully fine to add as many extra parentheses in other cases
(see Point::dump below).

Comment from commit: The only way a reference to a destructor can be used is to
immediately call them. Since the next token is not a '(', produce a diagnostic
and build the call now.

>From IRC discussions:

davidlt: Could some comment on "error: destructor reference must be called
immediately with '()'" ?
o11c: davidlt: it means you can't type x.~X
davidlt: o11c: this means I cannot do this: (pt->Point::~Point)(); but all
other compilers allow it
o11c: davidlt: hm, that is a clang bug then
davidlt: o11c: yet I can do (((pt->Point::dump)))(); and add as much extra
parantheses as I want
K-ballo: davidlt: you can take a pointer to a member function, but not to a
constructor/destructor
davidlt: The for this check is 5 years old, but only started to work in 3.5
o11c: davidlt: parentheses are explicitly defined to have absolutely no effect
on the validity, so file a bug
o11c: (I was just reading this part of the standard, so I know what I'm talking
about)
K-ballo: o11c: (pt->Point::~Point) would be an expression, is that allowed as
an expression?
o11c: K-ballo: yes. the only constraint is that you must use a () immediately,
but the grouping is still fine
o11c: 5.2.4 says that pseudo-dtor calls are an expression; 5.1.1/6 gives the
rule about parentheses
o11c: references are from C++11
o11c: n3337 specifically
o11c: davidlt: possibly useful information to include in your bug report ^
K-ballo: o11c: what's the type of the expression pt->Point::~Point ?
o11c: K-ballo: The result shall only be used as the operand for the function
call operator (), and the result of such a call has type void
o11c: this is in 5.2.4
o11c: and 5.1.1/6 explicitly allows parentheses around any operand

$ cat dtor.cc
#include <new>
#include <cstdlib>
#include <iostream>

class Point
{
  public:
    Point(int x, int y) : x(x), y(y) { std::cerr << "ctor " << x << " " << y <<
std::endl; }
    ~Point() { std::cerr << "dtor" << std::endl; }
    void dump() { std::cerr << "x: " << x << "; y:" << y << std::endl; }
  private:
    int x, y;
};

int main(int argc, char *argv[])
{
  char *mem = (char *)malloc(100);
  Point *pt = new (mem) Point(10, 20);
  (pt->Point::dump)();
  (((pt->Point::dump)))();
  (pt->Point::~Point)();
}

$ clang++ dtor.cc
dtor.cc:20:4: error: destructor reference must be called immediately with '()'
  (pt->Point::~Point)();
   ^
               ()
dtor.cc:20:22: error: called object type 'void' is not a function or function
pointer
  (pt->Point::~Point)();
  ~~~~~~~~~~~~~~~~~~~^
2 errors generated.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>