[clang] [Clang] Ensure default arguments in friend declarations are only allowed in defining declarations to prevent multiple reachable declarations (PR #113777)

Matheus Izvekov via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 6 10:19:09 PST 2024


================
@@ -185,3 +185,27 @@ template<typename T> struct S {
   friend void X::f(T::type);
 };
 }
+
+namespace GH113324 {
+template <typename = int> struct ct {
+  friend void f1(ct, int = 0);               // expected-error {{friend declaration specifying a default argument must be a definition}}
+  friend void f2(ct a, ct = decltype(a){ }); // expected-error {{friend declaration specifying a default argument must be a definition}}
+};
+
+template<typename T>
+class C {
+public:
+  friend void foo(T a = 1); // expected-error {{friend declaration specifying a default argument must be a definition}}
+};
+
+template<typename T>
+void foo(T a) { } // expected-note {{candidate function template not viable: requires single argument 'a', but no arguments were provided}}
+
+void test() {
+  f1(ct<>{});
+  f2(ct<>{});
+
+  C<int> c;
+  foo(); // expected-error {{no matching function for call to 'foo'}}
----------------
mizvekov wrote:

The test I had in mind was something like:
```C++
template<class T> using alias = int;

template<typename T> struct C {
  friend void foo(C, int a = alias<T&>(1));
};

void test() {
  foo(C<void>());
}
```

With your previous patch, we would be able to diagnose the instantiation failure here (forming reference to void), while the current version of the patch doesn't, since it skips instantiation of the default argument.

https://github.com/llvm/llvm-project/pull/113777


More information about the cfe-commits mailing list