<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><span class="vcard"><a class="email" href="mailto:richard-llvm@metafoo.co.uk" title="Richard Smith <richard-llvm@metafoo.co.uk>"> <span class="fn">Richard Smith</span></a>
</span> changed
          <a class="bz_bug_link 
          bz_status_RESOLVED  bz_closed"
   title="RESOLVED INVALID - Can not use a struct type of base containing both enum and protected destructor"
   href="https://bugs.llvm.org/show_bug.cgi?id=47365">bug 47365</a>
          <br>
             <table border="1" cellspacing="0" cellpadding="8">
          <tr>
            <th>What</th>
            <th>Removed</th>
            <th>Added</th>
          </tr>

         <tr>
           <td style="text-align:right;">Resolution</td>
           <td>---
           </td>
           <td>INVALID
           </td>
         </tr>

         <tr>
           <td style="text-align:right;">Status</td>
           <td>NEW
           </td>
           <td>RESOLVED
           </td>
         </tr></table>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_RESOLVED  bz_closed"
   title="RESOLVED INVALID - Can not use a struct type of base containing both enum and protected destructor"
   href="https://bugs.llvm.org/show_bug.cgi?id=47365#c1">Comment # 1</a>
              on <a class="bz_bug_link 
          bz_status_RESOLVED  bz_closed"
   title="RESOLVED INVALID - Can not use a struct type of base containing both enum and protected destructor"
   href="https://bugs.llvm.org/show_bug.cgi?id=47365">bug 47365</a>
              from <span class="vcard"><a class="email" href="mailto:richard-llvm@metafoo.co.uk" title="Richard Smith <richard-llvm@metafoo.co.uk>"> <span class="fn">Richard Smith</span></a>
</span></b>
        <pre>This is a GCC bug. The relevant language rule is [dcl.init.aggr]/8:

"""
The destructor for each element of class type is potentially invoked (11.4.6)
from the context where the aggregate initialization occurs.
"""

... and per [class.dtor]/15:

"""
A program is ill-formed if a destructor that is potentially invoked is deleted
or not accessible from the context of the invocation.
"""

To see why this rule exists, consider this variant on your testcase:

struct B {
protected:
    ~B() {}
};

struct C : B { int n; };

int f();

void g() {
    C c{{}, f()};
//    C c{B{}, f()};
}

Here, if f() throws an exception, the destructor for the temporary B object
constructed as C's base class needs to be called, but B::~B() is inaccessible
from the context of g().

If you make B's destructor public, GCC miscompiles the above testcase by
failing to destroy the B base class if the call to f() throws an exception.

If you uncomment the second line of g(), then GCC rejects the above example,
even though those two lines are equivalent.</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>