I tried to build with the following *FLAGS to optimize the build: -flto=4 -Werror=odr -Werror=lto-type-mismatch -Werror=strict-aliasing
Note the -Werror=* flags are used to help detect cases where the compiler tries to optimize by assuming UB cannot exist in the source code -- if it does exist, ordinarily the code would be miscompiled, and this says to make the miscompilation a fatal error.
I got this error:
make[3]: Entering directory '/var/tmp/portage/sci-electronics/ngspice-42/work/ngspice-42-binaries/src/xspice/icm'
for cm in spice2poly digital analog xtradev xtraevt table ; do \
make cm=$cm $cm/$cm.cm \
|| exit 1; \
done
make[4]: Entering directory '/var/tmp/portage/sci-electronics/ngspice-42/work/ngspice-42-binaries/src/xspice/icm'
x86_64-pc-linux-gnu-gcc -march=native -fstack-protector-all -O2 -pipe -fdiagnostics-color=always -frecord-gcc-switches -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 -fstack-clash-protection -flto=4 -Werror=odr -Werror=lto-type-mismatch -Werror=strict-aliasing -Wformat -Werror=format-security -Werror=implicit-function-declaration -Werror=implicit-int -Werror=int-conversion -Werror=incompatible-pointer-types -fopenmp -fPIC -fvisibility=hidden -shared spice2poly/dlmain.o dstring.o spice2poly/icm_spice2poly/cfunc.o spice2poly/icm_spice2poly/ifspec.o -lm -o spice2poly/spice2poly.cm
spice2poly/cmextrn.h:1:19: error: type of ‘spice2poly_info’ does not match original declaration [-Werror=lto-type-mismatch]
1 | extern SPICEdev spice2poly_info;
| ^
spice2poly/icm_spice2poly/ifspec.c:135:10: note: ‘spice2poly_info’ was previously declared here
135 | SPICEdev spice2poly_info = {
| ^
spice2poly/icm_spice2poly/ifspec.c:135:10: note: code may be misoptimized unless ‘-fno-strict-aliasing’ is used
lto1: some warnings being treated as errors
lto-wrapper: fatal error: x86_64-pc-linux-gnu-gcc returned 1 exit status
compilation terminated.
/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status
make[4]: *** [GNUmakefile:114: spice2poly/spice2poly.cm] Error 1
Previously reported downstream: https://bugs.gentoo.org/862513
Attached is a full build log.
Thanks for the report.
Do you have a recommendation how to solve the potential problem in the code?
If the function name is changed in ifspec.ifs, even by one character, the compilation succeeds. But then the problem occurs with several of the digital code models, There should be a pattern to the behaviour, but I have not found it.
Last edit: Giles Atkinson 2024-03-25
Isn't the compiler complaining about the missing 'extern'? I also notice an extra space between '..dev' and 'spice2..', had a strange problem with that myself a few days ago.
When I look at \src\include\ngspice\devdefs.h, I find this:
When I then look at \visualc\xspice\icm\spice2poly\icm_spice2poly\icm_spice2poly-ifspec.c,
there is
The position of the CIDER thing is different. Can this be the root cause?
I have a fix, but I do not think it should be adopted:
An obvious question: how does that work? I found it after I decided that the warning message (treated as error) is probably the result of a compiler bug. What does the warning say? It lacks any detail, but seems to mean that the typedef SPICEdev has a different meaning in dlmain.c and the ifspec.c file output from cmpp. That is ridiculous: SPICEdev is defined once in devdefs.h, there are no conditionals in the definition and the header is included into both C files.
If there is a gcc bug, how might it work? Perhaps the compiler "thinks" there are two different devdefs.h header files - it is confused by compiling source from different directory levels. It turns out that dlmain.c makes no use of the SPICEdev variables: they are placed in a global array to be found by dlsym() after the code-model library has been dynamically loaded. There are no other references,. So devdef.h can be removed from dlmain.c with a little ugly fix, and then the compiler can not be confused. It works!
Some supporting evidence that this is a gcc bug: according to the gcc manual, -flto is not some tweak to code generation like most -fxxxx options. It goes deep, so deep that the format of the generated .o files is very different when it is used. That is easily confirmed with readelf. Also the option seems much less mature than gcc's traditional functions. The only other time I saw it used is in compiling for microcontrollers, where optimising for size is important. So it seems the -flto option is not much used with software for bigger computers, and likely not mature. A web search for the error message in this case turns up only variations of this bug report for other software. All come from Gentoo.
Finally, the error report is sensitive to the function name in ifspec.ifs. That smells bad, and the ngspice part seems so simple that the bad smell must be coming from the compiler.
Possibly one of the types in the struct that changes. A composite type depends on all the types in the composite.
Indeed, that appears to be the case (thanks, abidiff!):
IFdevices are wildly different between the src/xspice/icm/xtraevt/dlmain.i dlmain TU and src/xspice/icm/xtraevt/d_to_real/ifspec.c TU. Preprocessing both reveals the difference.
The reason the hack works is because the differing type never gets declared, the fwdecl simply gets merged with the correct type.
File names are not relevant here. GCC just compares the types. They differ. Redeclaring the same file twice (i.e. using header files) does not cause this error.
This is indeed the case. Despite that, LTO is perfectly (assuming no bugs) standards compliant. It happens to often detect ODR-violations and similar issues (like the type mismatches above), simply due to being a massively global analysis pass.
Not at all, it is widely deployed (many distros, not just Gentoo) build with it. Some examples:
https://fedoraproject.org/wiki/LTOByDefault
https://wiki.ubuntu.com/ToolChain/LTO
This is because we test quite publicly.
Last edit: Arsen Arsenović 2024-03-25
In \src\include\ngspice\ifsim.h, in the definition of struct IFdevice, there is an additional
after
int flags;
which is not there in
and again also the sequence differs (position of
int flags;
before or after the XSPICE entries (does that matter?).A test might be to compile without
--enable-osdi
.Last edit: Holger Vogt 2024-03-25
Thank you for the corrections Arsen Arsenović. As usually happens, the hypothesis that the compiler is at fault is quite wrong, but this time has led to correct fix:
When dlmain.c can see the configured options the layouts are the same.
But now:
In earlier testing, my builds were successful with this change. But now, on Linux, I see what I hope are the same errors:
I do not know what has changed and unfortunately did not record the build options that hid these errors. This needs more testing, but appears to be a fix:
The LTO option is also reporting a lot of "...may be used uninitialized" warnings that may be worth looking at.
Your solution will not compile with MS Windows. I do have
That also works on my machine (Debian Linux). G.