Bug 77555 - unused inline function in-function static variable accessed from outside leads to linker error
Summary: unused inline function in-function static variable accessed from outside lead...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 6.1.1
: P3 normal
Target Milestone: 7.0
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code, lto, wrong-code
Depends on:
Blocks:
 
Reported: 2016-09-11 00:24 UTC by Martin
Modified: 2021-08-10 21:37 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2016-09-11 00:00:00


Attachments
examples showing the behavior. (705 bytes, application/zip)
2016-09-11 00:24 UTC, Martin
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Martin 2016-09-11 00:24:51 UTC
Created attachment 39603 [details]
examples showing the behavior.

Two part problem,

==== Part one

Unused inline functions can cause static variables to be instantiated by constexpr variable taking the address of the static variable. The attached test.cpp shows it working.

=== Part two ===

In-function static variables can be made visible outside, through templates, and this causes a linker error. Not a compilation error.

test2.cpp:(.text._ZZN9someclass6unusedEvEN6getter3getEv[_ZZN9someclass6unusedEvEN6getter3getEv]+0x7): undefined reference to `someclass::unused()::function_static'

The error happens with g++ 4.8.5, 5.3.0, 6.1.1, with -std=c++11, -std=c++14, -std=c++1z. clang++-3.5 crashes, 3.8 and 3.9 compiles and objdump shows that the in-function static variables are instantiated but the function is not emitted (since it's implicitly inline). Any static variable that's not used is not instantiated. The attached test2.cpp shows this. Naturally the behavior doesn't change if the class is instantiated, and is not affected by optimization, which I believe in gcc has extra control flow analysis. The only difference to the error with optimization is that with O1 or above the unused reference is from _GLOBAL__sub_I_main.

IMHO, gcc should follow the example of clang and instantiate static variables if they're referenced. Definitely not a linker error, I don't know if part one is required by the standard, but it seems plausible either way. If so, the compiler should detect the use of such static variables and emit them.
Comment 1 Markus Trippelsdorf 2016-09-11 05:38:15 UTC
 % cat test2.ii
extern "C" void printf(...);
struct A {
  A(int, char *p2) { printf(p2); }
};
template <int, typename> struct B { static A static_var; };
template <int LINE, typename GETTER>
A B<LINE, GETTER>::static_var{0, GETTER::get()};
struct C {
  void unused() {
    static char function_static;
    struct D {
      static char *get() { return &function_static; }
    };
    auto addr = B<0, D>::static_var;
  }
};
int main() {}
 
 % clang++ -flto -O2 test2.ii
 % clang++ -O2 test2.ii
 % icpc -O2 test2.ii
 % g++ -O2 test2.ii
/tmp/ccskrvWq.o:test2.ii:function _GLOBAL__sub_I_main: error: undefined reference to 'C::unused()::function_static'
collect2: error: ld returned 1 exit status

(with -flto we get an ICE:)
 % g++ -flto -O2 test2.ii
test2.ii:17:13: internal compiler error: in get_partitioning_class, at symtab.c:1850
 int main() {}
             ^
0x98fdd1 symtab_node::get_partitioning_class()
        ../../gcc/gcc/symtab.c:1850
0xc4ddb7 lto_output_varpool_node
        ../../gcc/gcc/lto-cgraph.c:614
0xc4ddb7 output_symtab()
        ../../gcc/gcc/lto-cgraph.c:1024
0xc60ba9 lto_output()
        ../../gcc/gcc/lto-streamer-out.c:2395
0xccb4ee write_lto
        ../../gcc/gcc/passes.c:2455
0xccefce ipa_write_summaries_1
        ../../gcc/gcc/passes.c:2519
0xccefce ipa_write_summaries()
        ../../gcc/gcc/passes.c:2579
0x9a8020 ipa_passes
        ../../gcc/gcc/cgraphunit.c:2330
0x9a8020 symbol_table::compile()
        ../../gcc/gcc/cgraphunit.c:2424
0x9aa8a1 symbol_table::compile()
        ../../gcc/gcc/cgraphunit.c:2557
0x9aa8a1 symbol_table::finalize_compilation_unit()
        ../../gcc/gcc/cgraphunit.c:2583
Please submit a full bug report,
Comment 2 paolo@gcc.gnu.org 2017-10-23 11:39:51 UTC
Author: paolo
Date: Mon Oct 23 11:39:20 2017
New Revision: 254006

URL: https://gcc.gnu.org/viewcvs?rev=254006&root=gcc&view=rev
Log:
2017-10-23  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/77555
	* g++.dg/torture/pr77555.C: New.

Added:
    trunk/gcc/testsuite/g++.dg/torture/pr77555.C
Modified:
    trunk/gcc/testsuite/ChangeLog
Comment 3 Paolo Carlini 2017-10-23 11:40:44 UTC
Fixed in 7.1.0.