Closed
Description
Summary:
Starting from commit 38b3d87bd384a469a6618ec6a971352cb4f813ba
in LLVM, Clang 20 reports
error: redefinition of default argument
when using friend
functions
in template classes, even though the default argument is only defined once.
Steps to Reproduce:
Compile the following minimal example with Clang 20:
#include <iostream>
#include <memory>
namespace Work {
namespace detail {
class Obj;
} // namespace detail
using Ptr = std::unique_ptr<detail::Obj>;
template <int>
Ptr Create(const void* key = nullptr); // default argument only once.
namespace detail {
class Obj {
protected:
Obj(const void* key) {
std::cout << "Obj::Obj\n";
}
};
template <int>
class ObjImpl : public Obj {
public:
ObjImpl(const void* key)
: Obj(key) {
std::cout << "ObjImpl::ObjImpl\n";
}
template <int>
friend Ptr Work::Create(const void*);
};
} // namespace detail
template <int i>
Ptr Create(const void* key) { // error: redefinition of default argument
return Ptr(new detail::ObjImpl<i>(key));
}
} // namespace Work
int main() {
auto ptr = Work::Create<192>(nullptr);
return 0;
}
Result:
clang++ reports:
./build/bin/clang++ -std=c++20 /mnt/e/test/error.cpp
/mnt/e/test/error.cpp:38:24: error: redefinition of default argument
13 | Ptr Create(const void* key) {
| ^
/mnt/e/test/error.cpp:39:20: note: in instantiation of template class 'Work::detail::ObjImpl<192>' requested here
39 | return Ptr(new detail::ObjImpl<i>(key));
| ^
/mnt/e/test/error.cpp:45:22: note: in instantiation of function template specialization 'Work::Create<192>' requested here
45 | auto ptr = Work::Create<192>(nullptr);
| ^
/mnt/e/test/error.cpp:32:40: note: previous definition is here
32 | friend Ptr Work::Create(const void*);
| ^
1 error generated.
Workaround:
If we remove the default parameter from Ptr Create(const void* key = nullptr);, then Clang++ compiles correctly.
If we remove the friend declaration, Clang++ also compiles correctly.
Regression:
git branch: release/20.x
First bad commit: 38b3d87
This issue does not occur in earlier versions of branch.