From mboxrd@z Thu Jan 1 00:00:00 1970 From: Randy Dunlap Subject: Re: PROBLEM: compilation issue, Incorrect C usage in drivers/block/null_blk.c causes kernel compilation failure with Intel c++ compiler Date: Wed, 13 Jan 2016 11:37:27 -0800 Message-ID: <5696A777.7070004@infradead.org> References: <5696A70C.6080700@infradead.org> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: QUOTED-PRINTABLE Cc: "'x86@kernel.org'" , "'kvm@vger.kernel.org'" , "'linux-kernel@vger.kernel.org'" , axboe To: "Blower, Melanie" , "'tglx@linutronix.de'" , "'mingo@redhat.com'" , "'hpa@zytor.com'" , "'avi@redhat.com'" Return-path: In-Reply-To: <5696A70C.6080700@infradead.org> Sender: linux-kernel-owner@vger.kernel.org List-Id: kvm.vger.kernel.org [add Jens Axboe] On 01/13/16 11:35, Randy Dunlap wrote: > On 01/13/16 11:22, Blower, Melanie wrote: >> [1.] Incorrect C usage in drivers/block/null_blk.c causes kernel co= mpilation failure with Intel c++ compiler >> [2.] Full description of the problem/report: >> Using icc, >> drivers/block/null_blk.c(569): error: variable "null_lnvm_dev_op= s" was declared with a never-completed type >> static struct nvm_dev_ops null_lnvm_dev_ops;=20 >> >> Clark Nelson, one of Intel's C++ language lawyers, explains why this= declaration is illegal: >> >> Discussion: >> Here is the problematic declaration, which appears near line 585 of= file drivers/block/null_blk.c: >> =20 >> static struct nvm_dev_ops null_lnvm_dev_ops; >=20 >=20 > or with gcc when building linux-next-20160111: >=20 > ../drivers/block/null_blk.c:569:27: error: storage size of =C2=80=C2=98= 'null_lnvm_dev_ops=C2=80'=C2=99 isn'=C2=80=C2=99t known > static struct nvm_dev_ops null_lnvm_dev_ops; > ^ >=20 >=20 >> This clearly violates 6.9.2 paragraph 3 of the C standard: >> =20 >> If the declaration of an identifier for an object is a tentative de= finition and has internal linkage, the declared type shall not be an i= ncomplete type. >> =20 >> The declaration is a tentative definition because it has no initia= lizer, it has internal linkage because the static keyword is used, and= yet the type is definitely an incomplete type. >> =20 >> In general, the problem with such a declaration is that the compile= r is expected to allocate memory for it in some data section, but the = compiler is given no idea how much memory to allocate. >> =20 >> As it turns out, the only way this variable is used is to take its = address and pass it to an inline function, which doesn't use the corr= esponding pointer parameter at all. So after inlining and dead code el= imination, no reference to the variable survives, so it doesn't need t= o be allocated after all, so it doesn't matter that the size of the all= ocation isn't known. >> =20 >> When optimization isn't used, and the variable isn't discovered to = be unnecessary, GCC also reports an error for this declaration. >> =20 >> However, it's fairly obvious that GCC wasn't carefully and consist= ently designed to allow this sort of thing. If the same declaration ap= pears in a block scope, without the static keyword, GCC reports an err= or regardless of the optimization level, even if the variable is never= referenced at all, even if the declaration appears in a static functi= on that is never used. The logic by which the original static declarati= on is accepted would suggest that the auto declaration should also be a= ccepted, but it isn't. >> =20 >> The simple fix would be to add an empty member list to the declarat= ion: >> =20 >> static struct nvm_dev_ops {} null_lnvm_dev_ops; >> =20 >> That would still not conform to the C standard, which doesn't allow= an empty member list. But support for an empty member list is much mor= e stable and predictable than support for optimizing out unused invali= d variable declarations. >> >> >> [3.] Keywords : kernel >> [4.] Kernel version (from /proc/version):=20 >> We're building linux-4.4-rc8.tar.xz with the Intel compiler >> Here's host information where the Kernel build occurs: >> Linux version 3.10.0-229.el7.x86_64 (mockbuild@x86-035.build.eng.bos= =2Eredhat.com) (gcc version 4.8.3 20140911 (Red Hat 4.8.3-7) (GCC) ) #1= SMP Thu Jan 29 18:37:38 EST 2015 >> [5.] Output of Oops.. message (if applicable) with symbolic informat= ion=20 >> resolved (see Documentation/oops-tracing.txt) >> n/a >> [6.] A small shell script or example program which triggers the >> problem (if possible) >> Compile kernel linux-4.4-rc8.tar.xz with Intel C++ compiler for Linu= x version 16.0 update 1 >> [7.] Environment >> I'm not going to include the environment details since they're irrel= evant. >> [7.1.] Software (add the output of the ver_linux script here) >> [7.2.] Processor information (from /proc/cpuinfo): >> [7.3.] Module information (from /proc/modules): >> [7.4.] Loaded driver and hardware information (/proc/ioports, /proc/= iomem) >> [7.5.] PCI information ('lspci -vvv' as root) >> [7.6.] SCSI information (from /proc/scsi/scsi) >> [7.7.] Other information that might be relevant to the problem >> (please look in /proc and include all information that you >> think to be relevant): >> [X.] Other notes, patches, fixes, workarounds: >> >> Please cc: me on replies to this message. Thanks and regards, Melani= e Blower (Intel C++ compiler team) >> >=20 >=20 --=20 ~Randy