Bug 99000 - [modules] merging of textual redefinitions: declaration std::__copy_move_a2 conflicts with import
Summary: [modules] merging of textual redefinitions: declaration std::__copy_move_a2 c...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 11.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 110447 114990 120323 120676 120764 124430 124919 (view as bug list)
Depends on:
Blocks: c++-modules 114990
  Show dependency treegraph
 
Reported: 2021-02-08 11:08 UTC by Boris Kolpackov
Modified: 2026-04-18 13:09 UTC (History)
12 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-02-08 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Boris Kolpackov 2021-02-08 11:08:52 UTC
The following header unit import causes the "declaration conflicts with import" error:

cat <<EOF >hello.hxx
#pragma once

#include <string_view>

namespace hello
{
  void
  say_hello (const std::string_view& name);
}
EOF

cat <<EOF >hello.cxx
import "hello.hxx";

#include <iostream>

namespace hello
{
  void
  say_hello (const std::string_view& n)
  {
    std::cout << "Hello, " << n << '!' << std::endl;
  }
}
EOF

g++ -std=c++2a -fmodules-ts -fmodule-header -x c++-header hello.hxx
g++ -std=c++2a -fmodules-ts x c++ -c hello.cxx
In file included from /home/boris/work/build2/tests/modules/gcc2/gcc-install/include/c++/11.0.0/bits/locale_facets.h:48,
                 from /home/boris/work/build2/tests/modules/gcc2/gcc-install/include/c++/11.0.0/bits/basic_ios.h:37,
                 from /home/boris/work/build2/tests/modules/gcc2/gcc-install/include/c++/11.0.0/ios:44,
                 from /home/boris/work/build2/tests/modules/gcc2/gcc-install/include/c++/11.0.0/ostream:38,
                 from /home/boris/work/build2/tests/modules/gcc2/gcc-install/include/c++/11.0.0/iostream:39,
                 from hello.cxx:3:
/home/boris/work/build2/tests/modules/gcc2/gcc-install/include/c++/11.0.0/bits/streambuf_iterator.h:367:72: error: declaration ‘template<bool _IsMove, class _CharT> typename __gnu_cxx::__enable_if<std::__is_char<_CharT>::__value, _CharT*>::__type std::__copy_move_a2(std::istreambuf_iterator<_CharT, std::char_traits<_CharT> >, std::istreambuf_iterator<_CharT, std::char_traits<_CharT> >, _CharT*)’ conflicts with import
  367 |                    istreambuf_iterator<_CharT> __last, _CharT* __result)
      |                                                                        ^
In file included from /home/boris/work/build2/tests/modules/gcc2/gcc-install/include/c++/11.0.0/bits/char_traits.h:39,
                 from /home/boris/work/build2/tests/modules/gcc2/gcc-install/include/c++/11.0.0/string_view:41,
                 from hello.hxx:3,
of module ./hello.hxx, imported at hello.cxx:1:
/home/boris/work/build2/tests/modules/gcc2/gcc-install/include/c++/11.0.0/bits/stl_algobase.h:471:5: note: import declared ‘template<bool _IsMove, class _CharT> typename __gnu_cxx::__enable_if<std::__is_char<_CharT>::__value, _CharT*>::__type std::__copy_move_a2(std::istreambuf_iterator<_CharT, std::char_traits<_CharT> >, std::istreambuf_iterator<_CharT, std::char_traits<_CharT> >, _CharT*)’ here
  471 |     __copy_move_a2(istreambuf_iterator<_CharT, char_traits<_CharT> >,
      |     ^~~~~~~~~~~~~~


Interestingly, if we change the #include and import order in hello.cxx, then the error goes away.
Comment 1 Nathan Sidwell 2021-02-08 20:24:47 UTC
You're hitting this:


@emph{G++'s modules support is not complete.}  Other than bugs, the
known missing pieces are:

....

@item Textual merging of reachable GM entities
Entities may be multiply defined across different header-units.
These must be de-duplicated, and this is implemented across imports,
or when an import redefines a textually-defined entity.  However the
reverse is not implemented---textually redefining an entity that has
been defined in an imported header-unit.  A redefinition error is
emitted.
Comment 2 Boris Kolpackov 2021-02-09 14:27:04 UTC
Thanks for pointing this out. Am I correct in interpreting the SUSPENDED status as unlikely to be fixed for GCC 11?
Comment 3 Patrick Palka 2024-03-13 17:53:19 UTC
*** Bug 110447 has been marked as a duplicate of this bug. ***
Comment 4 Jason Merrill 2024-07-01 17:43:37 UTC
Unsuspending and unassigning; this is a bug, but (as I understand) Nathan doesn't currently have time to work on modules issues.
Comment 5 Nathaniel Shead 2025-05-17 14:52:55 UTC
*** Bug 120323 has been marked as a duplicate of this bug. ***
Comment 6 Nathaniel Shead 2025-06-23 10:19:16 UTC
*** Bug 120764 has been marked as a duplicate of this bug. ***
Comment 7 Nathaniel Shead 2025-06-23 10:28:39 UTC
*** Bug 120676 has been marked as a duplicate of this bug. ***
Comment 8 GCC Commits 2025-09-06 10:38:34 UTC
The master branch has been updated by Nathaniel Shead <nshead@gcc.gnu.org>:

https://gcc.gnu.org/g:c39dbb652fafbb06507d23dcec6627ac9a9398cf

commit r16-3612-gc39dbb652fafbb06507d23dcec6627ac9a9398cf
Author: Nathaniel Shead <nathanieloshead@gmail.com>
Date:   Sun Aug 31 14:47:43 2025 +1000

    c++/modules: Support ADL on non-discarded GM entities [PR121705]
    
    [basic.lookup.argdep] p4 says that ADL also finds declarations of
    functions or function templates from a point of lookup within the
    module, only ignoring discarded (or internal) GM entities.
    
    To implement this we need to create bindings for these entities so that
    we can guarantee that name lookup will discover they exist.  This raises
    some complications, though, as we ideally would like to avoid having
    bindings that contain no declarations, or emitting GM namespaces that
    only contain discarded or internal functions.
    
    This patch does this by additionally creating a new binding whenever we
    call make_dependency on a non-EK_FOR_BINDING decl.  We don't do this for
    using-decls, as at the point of use of a GM entity we no longer know
    whether we called through a using-decl or the declaration directly;
    however, this behaviour is explicitly supported by [module.global.frag]
    p3.6.
    
    Creating these bindings caused g++.dg/modules/default-arg-4_* to fail.
    It turns out that this makes the behaviour look identical to
    g++.dg/modules/default-arg-5, which is incorrectly dg-error-ing default
    value redeclarations (we only currently error because of PR c++/99000).
    This patch removes the otherwise identical test and turns the dg-errors
    into xfailed dg-bogus.
    
    As a drive-by fix this also fixes an ICE when debug printing friend
    function instantiations.
    
            PR c++/121705
            PR c++/117658
    
    gcc/cp/ChangeLog:
    
            * module.cc (depset::hash::make_dependency): Make bindings for
            GM functions.
            (depset::hash::add_binding_entity): Adjust comment.
            (depset::hash::add_deduction_guides): Add log.
            * ptree.cc (cxx_print_xnode): Handle friend functions where
            TI_TEMPLATE is an OVERLOAD or IDENTIFIER.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/modules/default-arg-4_a.C: XFAIL bogus errors.
            * g++.dg/modules/default-arg-4_b.C: Likewise.
            * g++.dg/modules/default-arg-5_a.C: Remove duplicate test.
            * g++.dg/modules/default-arg-5_b.C: Likewise.
            * g++.dg/modules/adl-9_a.C: New test.
            * g++.dg/modules/adl-9_b.C: New test.
            * g++.dg/modules/gmf-5.C: New test.
    
    Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
    Reviewed-by: Jason Merrill <jason@redhat.com>
Comment 9 Nathaniel Shead 2025-09-09 23:30:20 UTC
*** Bug 114990 has been marked as a duplicate of this bug. ***
Comment 10 GCC Commits 2025-10-05 10:56:14 UTC
The master branch has been updated by Nathaniel Shead <nshead@gcc.gnu.org>:

https://gcc.gnu.org/g:fa6544ef5f50a824cabeda4906453d4545fbf66f

commit r16-4228-gfa6544ef5f50a824cabeda4906453d4545fbf66f
Author: Nathaniel Shead <nathanieloshead@gmail.com>
Date:   Fri Sep 26 22:10:15 2025 +1000

    c++/modules: Avoid ICE when redefining a type reachable via import [PR122053]
    
    This shouldn't be an error (see PR c++/99000), but we can at least avoid
    the ICE by ensuring that we load any pending type definition before
    calling pushdecl, so that we error before committing to filling in the
    class definition.
    
    Something like this will probably still be helpful even for implementing
    textual deduplication as we now at least ensure check_module_override is
    called for this case.
    
            PR c++/122053
    
    gcc/cp/ChangeLog:
    
            * name-lookup.cc (pushtag): Load any imported definition of type
            before calling pushdecl.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/modules/pr122053_a.C: New test.
            * g++.dg/modules/pr122053_b.C: New test.
    
    Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
    Reviewed-by: Jason Merrill <jason@redhat.com>
Comment 11 Patrick Palka 2025-12-11 15:02:21 UTC
After r16-6012-g9783f6f2f67f94 "c++/modules: #include <vector> -> import <bits/stdc++.h>" I believe include-after-import should naturally work in GCC 16 when mixing std module and headers #includes.

So for example

  import std;
  #include <vector>

successfully compiles and is handled as if

  import std;
  import <bits/stdc++.h>;
Comment 12 d7d1cd 2025-12-12 07:14:49 UTC
(In reply to Patrick Palka from comment #11)
> So for example
> 
>   import std;
>   #include <vector>
> 
> successfully compiles

Sorry, but this example doesn't compile with gcc trunk. Here's an attempt to reproduce it with godbolt: https://godbolt.org/z/cc863WYK7
Comment 13 Patrick Palka 2025-12-12 15:58:40 UTC
(In reply to d7d1cd from comment #12)
> (In reply to Patrick Palka from comment #11)
> > So for example
> > 
> >   import std;
> >   #include <vector>
> > 
> > successfully compiles
> 
> Sorry, but this example doesn't compile with gcc trunk. Here's an attempt to
> reproduce it with godbolt: https://godbolt.org/z/cc863WYK7
I forgot to mention you need to use `--compile-std-module` or otherwise manually compile the `<bits/stdc++.h>` as a header unit beforehand in order for the translation to happen.
Comment 14 Sergey Shumakov 2026-01-20 21:24:11 UTC
This flag actually causes Godbolt to timeout. set(CMAKE_CXX_SCAN_FOR_MODULES ON) to the rescue (https://godbolt.org/z/Ee5bdM38c). Yet, this does not compile with the original redefinition false positive.

The modularized example, in contrast, (https://godbolt.org/z/vTza6eGY3) compiles even on GCC 15.1 Does that mean that the redefinition issue only stands for normal TUs and works in the global module fragment for the modularized one?
Comment 15 d7d1cd 2026-01-21 07:16:52 UTC
(In reply to Sergey Shumakov from comment #14)
> This flag actually causes Godbolt to timeout.

Godbolt is forcibly terminating the compilation because it is taking too long.


(In reply to Sergey Shumakov from comment #14)
> set(CMAKE_CXX_SCAN_FOR_MODULESON) to the rescue (https://godbolt.org/z/Ee5bdM38c). Yet, this does not
> compile with the original redefinition false positive.

You didn't specify the --compile-std-module flag in the example. Furthermore, the CMAKE_CXX_SCAN_FOR_MODULES=ON option is enabled by default in CMake. Otherwise, a compilation error would occur: https://godbolt.org/z/o9YfKP5dK
Comment 16 d7d1cd 2026-01-21 07:35:11 UTC
(In reply to Patrick Palka from comment #13)
> I forgot to mention you need to use `--compile-std-module` or otherwise
> manually compile the `<bits/stdc++.h>` as a header unit beforehand in order
> for the translation to happen.

I still haven't figured out how to use this flag. Here's an example; it doesn't compile (even though CMake tries to compile standard library modules and fails): https://godbolt.org/z/G3Gv6sK1s.

Please show me how to use this flag correctly.
Comment 17 d7d1cd 2026-01-22 13:26:13 UTC
(In reply to Patrick Palka from comment #13)
> I forgot to mention you need to use `--compile-std-module` or otherwise
> manually compile the `<bits/stdc++.h>` as a header unit beforehand in order
> for the translation to happen.

What is the point of the --compile-std-module flag (and the capabilities implemented in https://gcc.gnu.org/cgit/gcc/commit/?id=9783f6f2f67f94) if the main C++ build system refused to use it: https://gitlab.kitware.com/cmake/cmake/-/issues/27528?
Comment 18 Nathaniel Shead 2026-03-10 13:12:36 UTC
*** Bug 124430 has been marked as a duplicate of this bug. ***
Comment 19 Patrick Palka 2026-04-18 13:09:10 UTC
*** Bug 124919 has been marked as a duplicate of this bug. ***