On 2020-02-05 10:42 +0800, Xi Ruoyao wrote: > I can't reproduce this. > > $ cat test1.c > void text(void) {} > int data = 1; > int bss = 0; > int common; > $ cat test2.c > #include <assert.h> > > extern void text(void); > extern int data; > extern int bss; > extern int common; > > int main() > { > assert(bss == 0 && data == 1); > return 0; > } > $ cc test1.c test2.c -flto -fno-common > $ ./a.out > $ > > Did you forgot the "extern" in test2.c for "int common;"? "int common;" is a > tentative definition, equivalent to "int common = 0;", in ANSI C. "-fcommon" is > a workaround enabled by default to resolve same tentative definitions in > multiple files. With "-fno-common" there is no such a workaround so the linker > will complain. Hi Xi, no, that's not the issue. The actual files as used in configure are shown below. Because of nm showing the variable as a "T" symbol, conftest.c got generated with a function declaration for nm_test_var, instead of the expected variable declaration. This causes the configure test to fail with conftest.cpp:6:12: error: variable 'nm_test_var' redeclared as function Without -fno-common, nm_test_var shows up as a "C" symbol, so it gets it right for the configure test, but it would be wrong if/when it's actually used for .bss or .data symbols. I found that there is a bugzilla entry for this https://sourceware.org/bugzilla/show_bug.cgi?id=25355 already. I also got to wondering why this doesn't break gcc-10 LTO bootstrap, which also uses libtool, and it turns out its because lt__PROGRAM_LTX_preloaded_symbols[] is declared as a file-scope constant, which in C++ defaults to static linkage. We use xg++ as the compiler for the configure test, and at -O1 and above, conftest.c gets optimized into nothing (i.e. no symbol references remain) and so the error doesn't trigger. conftest.c: #ifdef __cplusplus extern "C" { #endif extern int nm_test_func(); extern int nm_test_var(); /* This is incorrectly a function declaration */ /* The mapping between symbol names and symbols. */ const struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, {"nm_test_func", (void *) &nm_test_func}, {"nm_test_var", (void *) &nm_test_var}, {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif conftstm.c: #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} PS: I didn't receive your e-mail but saw it on gcc-help archive. Not sure why.