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:35:40 -0800 Message-ID: <5696A70C.6080700@infradead.org> References: 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'" To: "Blower, Melanie" , "'tglx@linutronix.de'" , "'mingo@redhat.com'" , "'hpa@zytor.com'" , "'avi@redhat.com'" Return-path: Received: from bombadil.infradead.org ([198.137.202.9]:54825 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753927AbcAMTfm (ORCPT ); Wed, 13 Jan 2016 14:35:42 -0500 In-Reply-To: Sender: kvm-owner@vger.kernel.org List-ID: On 01/13/16 11:22, Blower, Melanie wrote: > [1.] Incorrect C usage in drivers/block/null_blk.c causes kernel com= pilation 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_ops= " was declared with a never-completed type > static struct nvm_dev_ops null_lnvm_dev_ops;=20 >=20 > Clark Nelson, one of Intel's C++ language lawyers, explains why this = declaration is illegal: >=20 > 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; or with gcc when building linux-next-20160111: =2E./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; ^ > 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 def= inition and has internal linkage, the declared type shall not be an in= complete type. > =20 > The declaration is a tentative definition because it has no initial= izer, 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 compiler= is expected to allocate memory for it in some data section, but the c= ompiler 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 corre= sponding pointer parameter at all. So after inlining and dead code eli= mination, no reference to the variable survives, so it doesn't need to= be allocated after all, so it doesn't matter that the size of the allo= cation isn't known. > =20 > When optimization isn't used, and the variable isn't discovered to b= e unnecessary, GCC also reports an error for this declaration. > =20 > However, it's fairly obvious that GCC wasn't carefully and consiste= ntly designed to allow this sort of thing. If the same declaration app= ears in a block scope, without the static keyword, GCC reports an erro= r regardless of the optimization level, even if the variable is never = referenced at all, even if the declaration appears in a static functio= n that is never used. The logic by which the original static declaratio= n is accepted would suggest that the auto declaration should also be ac= cepted, but it isn't. > =20 > The simple fix would be to add an empty member list to the declarati= on: > =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 more= stable and predictable than support for optimizing out unused invalid= variable declarations. >=20 >=20 > [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.= redhat.com) (gcc version 4.8.3 20140911 (Red Hat 4.8.3-7) (GCC) ) #1 SM= P Thu Jan 29 18:37:38 EST 2015 > [5.] Output of Oops.. message (if applicable) with symbolic informati= on=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 Linux= version 16.0 update 1 > [7.] Environment > I'm not going to include the environment details since they're irrele= vant. > [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/i= omem) > [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: >=20 > Please cc: me on replies to this message. Thanks and regards, Melanie= Blower (Intel C++ compiler team) >=20 --=20 ~Randy