Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clang rejects valid code for incorrectly choosing protected destructor in list initilization #81089

Open
wangbo15 opened this issue Feb 8, 2024 · 4 comments
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" rejects-valid

Comments

@wangbo15
Copy link

wangbo15 commented Feb 8, 2024

The following code should be valid accroding to C++ syntax, since the protected destructor of the Base class can be implicitly called through the calling of Derived class's dtor, which is public:

struct Base {
protected:
    ~Base() = default;  
};

struct Derived : Base{
};

int main(){
    Derived d{};
}

However we find it does not compile in clang 17.0.1 and clang-trunk. It comes out that the compiler complains about the usage of protected base destructor. When we replace the statement Derived d{}; with Derived d; in the function main, the code compiles well.

<source>:10:15: error: temporary of type 'Base' has protected destructor
   10 |     Derived d{};
      |               ^
<source>:3:5: note: declared protected here
    3 |     ~Base() = default;  
      |     ^
1 error generated.

https://godbolt.org/z/3nGbj15M3

@github-actions github-actions bot added the clang Clang issues not falling into any other category label Feb 8, 2024
@EugeneZelenko EugeneZelenko added clang:frontend Language frontend issues, e.g. anything involving "Sema" rejects-valid and removed clang Clang issues not falling into any other category labels Feb 8, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Feb 8, 2024

@llvm/issue-subscribers-clang-frontend

Author: Bo Wang (wangbo15)

The following code should be valid accroding to C++ syntax, since the protected destructor of the `Base` class can be implicitly called through the calling of `Derived` class's dtor, which is public:
struct Base {
protected:
    ~Base() = default;  
};

struct Derived : Base{
};

int main(){
    Derived d{};
}

However we find it does not compile in clang 17.0.1 and clang-trunk. It comes out that the compiler complains about the usage of protected base destructor. When we replace the statement Derived d{}; with Derived d; in the function main, the code compiles well.

&lt;source&gt;:10:15: error: temporary of type 'Base' has protected destructor
   10 |     Derived d{};
      |               ^
&lt;source&gt;:3:5: note: declared protected here
    3 |     ~Base() = default;  
      |     ^
1 error generated.

https://godbolt.org/z/3nGbj15M3

@shafik
Copy link
Collaborator

shafik commented Mar 14, 2024

I believe this is correct before C++20: https://reviews.llvm.org/D53860

I would have to look up the details to figure out where this changed.

@zygoloid
Copy link
Collaborator

In C++17 onwards, Derived is an aggregate, and so Derived d{}; performs aggregate initialization, equivalent to Derived d{{}};, which is equivalent to Derived d{Base{}};. Thus the check for an accessible base destructor is performed in the code that performs the aggregate initialization, because that code is initializing the Base object, not the Derived constructor (which isn't even called). However, see CWG2244.

@carlosgalvezp
Copy link
Contributor

carlosgalvezp commented Oct 15, 2024

Are there any updates on this issue? I just checked and GCC and MSVC handle this correctly.

Btw here's a working link to CWG 2244:
https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2244

@shafik I see this is tagged as "C++20 in Clang", but shouldn't this be tagged as C++17?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" rejects-valid
Projects
Status: No status
Development

No branches or pull requests

6 participants