Subject: Re: linux-next: build failure after merge of the arm tree

From: "Russell King (Oracle)" <[email-masked]>
Date: Fri, 3 May 2024 13:29:49 +0100

On Fri, May 03, 2024 at 10:08:26PM +1000, Stephen Rothwell wrote:
> Hi Russell,
> 
> On Fri, 3 May 2024 09:18:00 +0100 "Russell King (Oracle)" <[email-masked]> wrote:
> >
> > On Fri, May 03, 2024 at 10:15:16AM +1000, Stephen Rothwell wrote:
> > > 
> > > After merging the arm tree, today's linux-next build (x86_64 allmodconfig)
> > > failed like this:
> > > 
> > > drivers/clk/clkdev.c: In function 'vclkdev_alloc':
> > > drivers/clk/clkdev.c:195:16: error: assignment to '__va_list_tag (*)[1]' from incompatible pointer type '__va_list_tag **' [-Werror=incompatible-pointer-types]
> > >   195 |         fmt.va = &ap;
> > >       |                ^
> > > cc1: all warnings being treated as errors  
> > 
> > This builds perfectly fine for me - this is on debian stable with
> > arm-linux-gnueabihf-gcc (Debian 10.2.1-6) 10.2.1 20210110:
> > 
> > No warnings, no errors.
> > 
> > va_format is defined as:
> > 
> > struct va_format {
> >         const char *fmt;
> >         va_list *va;
> > };
> > 
> > and what we have here is a "va_list ap".
> > 
> > Therefore, the assignment:
> > 
> >         fmt.va = &ap;
> > 
> > is correct.
> > 
> > What certainly won't work is:
> > 
> > 	fmt.va = ap;
> > 
> > and there aren't any other reasonable alternatives.
> > 
> > My conclusion: your compiler is being stupid.
> 
> Definitely possible.  My build is an x86_64 allmodconfig cross build
> hosted on PowerPC64LE.
> 
> $ x86_64-linux-gnu-gcc --version
> x86_64-linux-gnu-gcc (Debian 13.2.0-7) 13.2.0
> 
> It still fails for me even just building your tree.  :-(
> 
> And if I revert commit 5d998425e37b it does not fail (of course).

So I think the questions are...

1) why does this fail with this compiler?

2) why does this instance fail, when we have plenty of other instances
in the kernel doing the same thing? (grep vaf fs/)

I'm wrong about the va_start()/va_end() - those are done in the
caller, e.g. clkdev_create() does the va_start..va_end before
passing the va_list to vclkdev_create() which then passes it down
to vclkdev_alloc(). So it would be wrong to add another va_start()
in vclkdev_alloc().

The only thing I can think of doing is something like:

#ifdef CONFIg_X86_64
	pr_error("%s:%s ID is greater than %zu\n",
		 "[compiler error - unreportable device]",
        	 con_id, failure, max_size);
#else
	{
		struct va_format fmt;
	        fmt.fmt = dev_fmt;
	        fmt.va = &ap;
	        pr_err("%pV:%s: %s ID is greater than %zu\n",
        	       &fmt, con_id, failure, max_size);
	}
#endif
	kfree(cla);
	return NULL;

which would be better than nothing... but really we shouldn't be
working around what looks to me like a compiler bug like this.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!