[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:31:40 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:

No, I mean not crashing is definitely better. But the error recovery is worse in some situations.

The right fix would be to somehow find the correct function decl pattern for instantiating the default argument.
This would be the function template declaration where that particular default argument was written.

This might not necessarily need to use `getTemplateInstantiationPattern` for that; you could try some other way of finding it. But that ideal fix might be more involved, and I think the current approach is fine as a quick fix, so feel free to continue with this current patch, or otherwise try the better fix, as you wish.

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


More information about the cfe-commits mailing list