On Fri, Aug 15, 2025 at 12:38:01PM +0200, Jakub Jelinek wrote: > Hi! > > The following patch adds some testcases for the default argument (function > and template) part of the paper, making sure we diagnose multiple defargs > in the same TU and when visible in modules and DTRT when some aren't visible > and some are visible and they are equal. Not testing when they are > different since that is IFNDR. > > Tested on x86_64-linux and i686-linux, ok for trunk? > > 2025-08-15 Jakub Jelinek <ja...@redhat.com> > > PR c++/121552 > * g++.dg/parse/defarg21.C: New test. > * g++.dg/template/defarg24.C: New test. > * g++.dg/modules/default-arg-4_a.C: New test. > * g++.dg/modules/default-arg-4_b.C: New test. > * g++.dg/modules/default-arg-5_a.C: New test. > * g++.dg/modules/default-arg-5_b.C: New test. > > --- gcc/testsuite/g++.dg/parse/defarg21.C.jj 2025-08-15 11:17:39.446828030 > +0200 > +++ gcc/testsuite/g++.dg/parse/defarg21.C 2025-08-15 11:17:33.679900471 > +0200 > @@ -0,0 +1,38 @@ > +// C++20 P1766R1 - Mitigating minor modules maladies > +// { dg-do compile } > + > +int f1 (int); > +int f1 (int = 42); > +int f2 (int); > +int f2 (int = 42); // { dg-message "previous specification in 'int > f2\\\(int\\\)' here" } > +int f2 (int = 42); // { dg-error "default argument given for > parameter 1 of 'int f2\\\(int\\\)'" } > +int f3 (int = 42); // { dg-message "previous specification in 'int > f3\\\(int\\\)' here" } > +int f3 (int = 43); // { dg-error "default argument given for > parameter 1 of 'int f3\\\(int\\\)'" } > +namespace A > +{ > + int f4 (int = 1); // { dg-message "previous specification in 'int > A::f4\\\(int\\\)' here" } > + int f5 (int = 1); // { dg-message "previous specification in 'int > A::f5\\\(int\\\)' here" } > +} > +namespace A > +{ > + int f4 (int = 1); // { dg-error "default argument given for > parameter 1 of 'int A::f4\\\(int\\\)'" } > + int f5 (int = 2); // { dg-error "default argument given for > parameter 1 of 'int A::f5\\\(int\\\)'" } > +} > +template <int N> > +int f6 (long = 42L); > +template <int N> > +int f6 (long = 42L); // { dg-error "redeclaration of 'template<int > N> int f6\\\(long int\\\)' may not have default arguments" } > + > +void > +foo () > +{ > + int f7 (int = 42); // { dg-message "previous specification in 'int > f7\\\(int\\\)' here" } > + int f7 (int = 42); // { dg-error "default argument given for > parameter 1 of 'int f7\\\(int\\\)'" } > + int f8 (int = 42); > + { > + int f8 (int = 42); > + { > + int f8 (int = 43); > + } > + } > +} > --- gcc/testsuite/g++.dg/template/defarg24.C.jj 2025-08-15 > 11:19:33.886390518 +0200 > +++ gcc/testsuite/g++.dg/template/defarg24.C 2025-08-15 11:31:12.396664456 > +0200 > @@ -0,0 +1,37 @@ > +// C++20 P1766R1 - Mitigating minor modules maladies > +// { dg-do compile { target c++11 } } > + > +template <int N> > +int f1 (int); > +template <int N = 42> > +int f1 (int); > +template <int N> // { dg-message "original definition > appeared here" } > +int f2 (int); > +template <int N = 42> > +int f2 (int); > +template <int N = 42> // { dg-error "redefinition of > default argument for 'int N'" } > +int f2 (int); > +template <int N = 42> // { dg-message "original > definition appeared here" } > +int f3 (int); > +template <int N = 43> // { dg-error "redefinition of > default argument for 'int N'" } > +int f3 (int); > +template <typename T> > +int f4 (int); > +template <typename T = int> > +int f4 (int); > +namespace A > +{ > + template <typename T> // { dg-message "original > definition appeared here" } > + int f5 (int); > + template <typename T = int> > + int f5 (int); > + template <typename T = int> // { dg-message "original > definition appeared here" } > + int f6 (int); > +} > +namespace A > +{ > + template <typename T = int> // { dg-error "redefinition of > default argument for 'class T'" } > + int f5 (int); > + template <typename T = long> // { dg-error "redefinition of > default argument for 'class T'" } > + int f6 (int); > +} > --- gcc/testsuite/g++.dg/modules/default-arg-4_a.C.jj 2025-08-15 > 12:16:07.521139287 +0200 > +++ gcc/testsuite/g++.dg/modules/default-arg-4_a.C 2025-08-15 > 12:31:11.313828020 +0200 > @@ -0,0 +1,19 @@ > +// C++20 P1766R1 - Mitigating minor modules maladies > +// { dg-additional-options "-fmodules-ts -Wno-global-module" } > +// { dg-module-cmi M } > + > +module; > + > +int foo (int i = 42); > +template <typename T, typename U = int> > +int bar (); > +template <typename T, int N = 42> > +int baz (); > + > +export module M; > + > +export inline int > +qux () > +{ > + return foo () + bar <int> () + baz <int> (); > +} > --- gcc/testsuite/g++.dg/modules/default-arg-4_b.C.jj 2025-08-15 > 12:16:12.027082865 +0200 > +++ gcc/testsuite/g++.dg/modules/default-arg-4_b.C 2025-08-15 > 12:29:25.186152954 +0200 > @@ -0,0 +1,36 @@ > +// C++20 P1766R1 - Mitigating minor modules maladies > +// { dg-do run } > +// { dg-additional-options "-fmodules-ts" } > + > +import M; > + > +int > +foo (int i = 42) > +{ > + return i; > +} > + > +template <typename T, typename U = int> > +int > +bar () > +{ > + return sizeof (U); > +} > + > +template <typename T, int N = 42> > +int > +baz () > +{ > + return N; > +} > + > +int > +main () > +{ > + if (foo () + bar <int> () + baz <int> () != qux ()) > + __builtin_abort (); > + if (foo () != foo (42) > + || bar <int> () != bar <int, int> () > + || baz <int> () != baz <int, 42> ()) > + __builtin_abort (); > +} > --- gcc/testsuite/g++.dg/modules/default-arg-5_a.C.jj 2025-08-15 > 12:16:07.521139287 +0200 > +++ gcc/testsuite/g++.dg/modules/default-arg-5_a.C 2025-08-15 > 12:31:20.149717714 +0200 > @@ -0,0 +1,23 @@ > +// C++20 P1766R1 - Mitigating minor modules maladies > +// { dg-additional-options "-fmodules-ts -Wno-global-module" } > +// { dg-module-cmi M } > + > +module; > + > +int foo (int i = 42); > +template <typename T, typename U = int> > +int bar (); > +template <typename T, int N = 42> > +int baz (); > + > +export module M; > + > +export inline int > +qux () > +{ > + return foo () + bar <int> () + baz <int> (); > +} > + > +export using ::foo; > +export using ::bar; > +export using ::baz; > --- gcc/testsuite/g++.dg/modules/default-arg-5_b.C.jj 2025-08-15 > 12:16:12.027082865 +0200 > +++ gcc/testsuite/g++.dg/modules/default-arg-5_b.C 2025-08-15 > 12:28:39.750720402 +0200 > @@ -0,0 +1,35 @@ > +// C++20 P1766R1 - Mitigating minor modules maladies > +// { dg-additional-options "-fmodules-ts" } > + > +import M; > + > +int > +foo (int i = 42) // { dg-error "default argument given > for parameter 1 of 'int foo\\\(int\\\)'" }
I don't think this (or the following in this file) should be errors; we error currently because we don't implement textual deduplication (PR99000), but since the default arguments are the same, from the current wording this should be OK as far as I understand it. In particular, the default argument definition here is in a different TU from that of the definition in M, so [basic.def.odr] p2 doesn't apply. We test this the other way around in modules/default-arg-3. (Note that the wording in the C++20 WD is not the same as the wording diff given in p1766r1, it seems to have been adjusted before C++20 was published: https://timsong-cpp.github.io/cppwp/n4861/basic.def.odr#1) Let me know if I've misunderstood something here. Nathaniel