Bug 98930 - ICE with static variable in template function used as template argument
Summary: ICE with static variable in template function used as template argument
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 11.0
: P3 normal
Target Milestone: 12.0
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-checking, ice-on-valid-code, link-failure
: 98288 (view as bug list)
Depends on:
Blocks: constexpr
  Show dependency treegraph
 
Reported: 2021-02-02 09:55 UTC by Matthieu M
Modified: 2021-10-05 13:53 UTC (History)
2 users (show)

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


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Matthieu M 2021-02-02 09:55:38 UTC
The following code crashes gcc trunk (11.0) and produces a linker error on prior versions -- from 7.2 to 10.2.1 -- from -O0 to -O3.

Link to compiler explorer: https://godbolt.org/z/qox73Y



Self-sufficient code snippet:

template <char const* format>
class Source {
public:
    explicit Source() noexcept {
        asm volatile("" : : "r,m"(format) : "memory");
    }

    int index() const noexcept { return 0; }
};

template <typename T>
T impl() {
    static constexpr const char FORMAT_[] = "Hello, {}!";
    static Source<FORMAT_> const SOURCE{};

    return SOURCE.index();
}

int main() {
    return impl<int>();
}



GCC trunk crash:

<source>: In instantiation of 'Source<format>::Source() [with const char* format = (& FORMAT_)]':
<source>:4:14:   required from here
<source>:4:14: internal compiler error: in discriminator_for_local_entity, at cp/mangle.c:1949
    4 |     explicit Source() noexcept {
      |              ^~~~~~
0x1ce5ce9 internal_error(char const*, ...)
	???:0
0x6b6f1b fancy_abort(char const*, int, char const*)
	???:0
0x812f3b mangle_decl(tree_node*)
	???:0
0x135b052 decl_assembler_name(tree_node*)
	???:0
0x138e478 assign_assembler_name_if_needed(tree_node*)
	???:0
0xb48015 cgraph_node::analyze()
	???:0
0xb4c6dd symbol_table::finalize_compilation_unit()
	???:0



GCC 10.2 linker error:

/opt/compiler-explorer/gcc-10.2.0/bin/../lib/gcc/x86_64-linux-gnu/10.2.0/../../../../x86_64-linux-gnu/bin/ld: /tmp/cc6YCcxH.o: in function `_ZN6SourceIXadL_ZZ4implIT_ES1_vE7FORMAT_EEEC1Ev':
/home/ce/<source>:5: undefined reference to `_ZZ4implIT_ES0_vE7FORMAT_'
collect2: error: ld returned 1 exit status



Other compilers: ICE on Clang 11.0, Works on Clang (trunk).



In the same area (local static constexpr) I found 2 bug reports:

- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95686
- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98288 (which I reported)


Regards.
Comment 1 Andrew Pinski 2021-10-02 06:10:12 UTC
*** Bug 98288 has been marked as a duplicate of this bug. ***
Comment 2 Andrew Pinski 2021-10-02 06:12:00 UTC
Confirmed.
Comment 3 Andrew Pinski 2021-10-02 06:21:03 UTC
Shortest testcase:
template <int* format>
struct g { g() { *format =1; } };

template <int>
void impl() {
    static int i=1;
    static g<&i> h{};
}

int main() {
  impl<0>();
  return 0;
}
Comment 4 GCC Commits 2021-10-05 13:50:36 UTC
The master branch has been updated by Patrick Palka <ppalka@gcc.gnu.org>:

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

commit r12-4186-gf3930418cb82000fae3cb4e98e870428800cf295
Author: Patrick Palka <ppalka@redhat.com>
Date:   Tue Oct 5 09:50:02 2021 -0400

    c++: templated static local var has value-dep addr [PR98930]
    
    Here uses_template_parms returns false for the dependent type A<&impl::i>,
    which causes tsubst_aggr_type to think it's non-dependent and not bother
    substituting into it, leading to breakage.
    
    This patch fixes this by making has_value_dependent_address also return
    true for templated static local variables.
    
            PR c++/98930
    
    gcc/cp/ChangeLog:
    
            * pt.c (has_value_dependent_address): Return true for a static
            local variable from a function template.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp1z/nontype4.C: New test.
            * g++.dg/cpp1z/nontype4a.C: New test.
Comment 5 Patrick Palka 2021-10-05 13:53:59 UTC
Fixed for GCC 12, thanks for the bug report.