Bug 101095 - Bogus "error: conflicting global module declaration" for abbreviated function template using placeholder type in noexcept
Summary: Bogus "error: conflicting global module declaration" for abbreviated function...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 11.1.1
: P3 normal
Target Milestone: 11.3
Assignee: Jason Merrill
URL:
Keywords: rejects-valid
Depends on:
Blocks: c++-modules
  Show dependency treegraph
 
Reported: 2021-06-16 12:36 UTC by Jonathan Wakely
Modified: 2023-11-28 00:06 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-06-16 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Wakely 2021-06-16 12:36:42 UTC
cat > mod.h <<EOT
#ifndef MOD_H
#define MOD_H
template<typename T> concept rhubarb = true;
template<typename T> constexpr bool nothrow = true;
void donkey(rhubarb auto i) noexcept(nothrow<decltype(i)>) { }
#endif
EOT

cat > mod.H <<EOT
#include "mod.h"
EOT

cat > mod.C <<EOT
#include "mod.h"
import "mod.H";

int main()
{
  donkey(1);
}
EOT

g++ -std=c++20 -fmodule-header mod.H -c
g++ -std=c++20 -fmodules-ts mod.C

This gives a bogus error:

In file included from mod.H:1,
of module ./mod.H, imported at mod.C:2:
mod.h: In function ‘int main()’:
mod.h:5:6: error: conflicting global module declaration ‘template<class auto:1> void donkey(auto:1)’
    5 | void donkey(rhubarb auto i) noexcept(nothrow<decltype(i)>) { }
      |      ^~~~~~
In file included from mod.C:1:
mod.h:5:6: note: existing declaration ‘template<class auto:1>  requires  rhubarb<auto:1> void donkey(auto:1)’
    5 | void donkey(rhubarb auto i) noexcept(nothrow<decltype(i)>) { }
      |      ^~~~~~
mod.C:6:3: note: during load of binding ‘::donkey’
    6 |   donkey(1);
      |   ^~~~~~


The code compiles OK if the noexcept-specifier doesn't refer to the auto:1 type.
Comment 1 Jonathan Wakely 2021-06-16 15:24:30 UTC
This causes:

FAIL: g++.dg/modules/xtreme-header-2_b.C -std=c++2a (test for excess errors)
FAIL: g++.dg/modules/xtreme-header-2_b.C -std=c++2b (test for excess errors)
FAIL: g++.dg/modules/xtreme-tr1_b.C -std=c++2a (test for excess errors)
FAIL: g++.dg/modules/xtreme-tr1_b.C -std=c++2b (test for excess errors)
Comment 2 GCC Commits 2021-07-15 03:18:46 UTC
The master branch has been updated by Jason Merrill <jason@gcc.gnu.org>:

https://gcc.gnu.org/g:0b7a11874d4eb428c18a91f38786032ce0e77a96

commit r12-2313-g0b7a11874d4eb428c18a91f38786032ce0e77a96
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Jul 14 17:10:49 2021 -0400

    c++: fix tree_contains_struct for C++ types [PR101095]
    
    Many of the types from cp-tree.def were only marked as having tree_common,
    when actually most of them have type_non_common.  This broke
    g++.dg/modules/xtreme-header-2, as the modules code relies on
    tree_contains_struct to know what bits it needs to stream.
    
    We don't seem to use type_non_common for TYPE_ARGUMENT_PACK, so I bumped it
    down to TS_TYPE_COMMON.  I tried doing the same in cp_tree_size, but that
    breaks without more extensive changes to tree_node_structure.
    
    Why do we need the init_ts function anyway?  It seems redundant with
    tree_node_structure.
    
            PR c++/101095
    
    gcc/cp/ChangeLog:
    
            * cp-objcp-common.c (cp_common_init_ts): Mark types as types.
            (cp_tree_size): Remove redundant entries.
Comment 3 GCC Commits 2022-03-22 05:18:16 UTC
The releases/gcc-11 branch has been updated by Jason Merrill <jason@gcc.gnu.org>:

https://gcc.gnu.org/g:0a63e3ee2d5c9aa0e51aa1eb54c3d14c06418ac3

commit r11-9680-g0a63e3ee2d5c9aa0e51aa1eb54c3d14c06418ac3
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Jul 14 17:10:49 2021 -0400

    c++: fix tree_contains_struct for C++ types [PR101095]
    
    Many of the types from cp-tree.def were only marked as having tree_common,
    when actually most of them have type_non_common.  This broke
    g++.dg/modules/xtreme-header-2, as the modules code relies on
    tree_contains_struct to know what bits it needs to stream.
    
    We don't seem to use type_non_common for TYPE_ARGUMENT_PACK, so I bumped it
    down to TS_TYPE_COMMON.  I tried doing the same in cp_tree_size, but that
    breaks without more extensive changes to tree_node_structure.
    
    Why do we need the init_ts function anyway?  It seems redundant with
    tree_node_structure.
    
            PR c++/101095
    
    gcc/cp/ChangeLog:
    
            * cp-objcp-common.c (cp_common_init_ts): Mark types as types.
            (cp_tree_size): Remove redundant entries.
Comment 4 Patrick Palka 2022-10-20 16:45:26 UTC
Fixed for GCC 11.3+ I suppose