https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127079

            Bug ID: 127079
           Summary: [modules] Conflicting default argument from unrelated
                    function
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: Lavrentii.Tsvetkov at viridiengroup dot com
  Target Milestone: ---

Created attachment 65424
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65424&action=edit
Patch for the test suite

When a default argument is provided to a static class function, an unrelated
global function with a matching signature is considered if the value of the
default argument is the same. This happens if the declarations are present in
both the module and the global module fragment.
This results in rejection of the valid program. The bug is order-dependent;
swapping the order of the declarations prevents the bug from being triggered.

The following snippet reproduces the problem when included both in the module
and the module fragment:

int g(int = -1);

class A
{
    static int f(int = -1);
};

Reproducible with latest master gcc version 17.0.0 20260819 (experimental)
(GCC).
Patch for testsuite to reproduce the bug is attached.
g++ -std=c++20 -fmodules -fno-module-lazy default-arg-5_a.H default-arg-5_b.C

Reported error:
In file included from default-arg-5_a.H:3,
of module ./default-arg-5_a.H, imported at default-arg-5_b.C:4:
default-arg-5.h:5:17: error: conflicting default argument for parameter 1 of
‘static int A::f(int)’
    5 |   static int f (int = -1);
      |                 ^~~~~~~~
In file included from default-arg-5_b.C:3:
default-arg-5.h:5:17: note: existing default declared here
    5 |   static int f (int = -1);
      |                 ^~~~~~~~



Note: I have also found what I believe is a structurally similar issue, but I'm
not sure if the code is supposed to be valid:

namespace { constexpr int n = -1; }
int f(int = n);

If the code above is rightly rejected, it might be rejected with a suboptimal
error message. For example, attempts to export the value from the anonymous
namespace itself raise only a warning: "exporting ‘constexpr const int
{anonymous}::n’ that does not have external linkage
[-Wexpose-global-module-tu-local]", whereas removing the namespace gives
"warning: ‘int f(int)’ exposes TU-local entity ‘n’
[-Wexpose-global-module-tu-local]" (if refactored to export only f using
modules instead of header units).

Reply via email to