llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.55k stars 11.8k forks source link

clang incorrectly judges default copy constructor in template class #99749

Open Rush10233 opened 3 months ago

Rush10233 commented 3 months ago

Consider the following code:

template<typename T>
class Box
{
public:
  Box(const Box<int>&)=default;
  //Box(const Box<T>&)=default;
};

The constructor of class Box in line 5 should be a normal user-defined constructor instead of a copy constructor as the parameter list is incompatible(the real copy ctor should be in the form of that in line 6), so it should not be declared as defaulted. Both GCC and MSVC reject the code, but clang accepts it.

MSVC provides the following diagnostic:

example.cpp
<source>(6): error C2610: 'Box<T>::Box(const Box<int> &)': is not a special member function or comparison operator which can be defaulted
<source>(6): note: the template instantiation context (the oldest one first) is
<source>(3): note: while compiling class template 'Box'
Compiler returned: 2

Please see https://godbolt.org/z/EbY3zWKc1

halayli commented 3 months ago

IMO Clang's behavior is more correct here because it delays sema analysis until template instantiation. Technically speaking, Box<int> is valid. But this can only be determined up on instantiation.

llvmbot commented 3 months ago

@llvm/issue-subscribers-clang-frontend

Author: None (Rush10233)

Consider the following code: ```c++ template<typename T> class Box { public: Box(const Box<int>&)=default; //Box(const Box<T>&)=default; }; ``` The constructor of class `Box` in line 5 should be a normal user-defined constructor instead of a copy constructor as the parameter list is incompatible(the real copy ctor should be in the form of that in line 6), so it should not be declared as defaulted. Both GCC and MSVC reject the code, but clang accepts it. MSVC provides the following diagnostic: ```c++ example.cpp <source>(6): error C2610: 'Box<T>::Box(const Box<int> &)': is not a special member function or comparison operator which can be defaulted <source>(6): note: the template instantiation context (the oldest one first) is <source>(3): note: while compiling class template 'Box' Compiler returned: 2 ``` Please see [https://godbolt.org/z/EbY3zWKc1](https://godbolt.org/z/EbY3zWKc1)