From: Hans Verkuil <hverkuil@xs4all.nl>
To: Christopher Li <sparse@chrisli.org>
Cc: Linux-Sparse <linux-sparse@vger.kernel.org>,
Linux Media Mailing List <linux-media@vger.kernel.org>
Subject: Re: sparse: ARRAY_SIZE and sparse array initialization
Date: Sun, 30 Mar 2014 14:03:08 +0200 [thread overview]
Message-ID: <533807FC.5050008@xs4all.nl> (raw)
In-Reply-To: <CANeU7Qksj-tq0fjsZya1otX75sV4JOsAdXHr5Kxu-WyvYrksSw@mail.gmail.com>
Hi Chris,
On 03/30/2014 08:10 AM, Christopher Li wrote:
> On Fri, Mar 28, 2014 at 3:50 AM, Hans Verkuil <hverkuil@xs4all.nl> wrote:
>> Is there any chance that the three issues I reported will be fixed? If not,
>> then I'll work around it in the kernel code.
>>
>
> Most likely it is a sparse issue. Can you generate a minimal stand alone
> test case that expose this bug? I try to simplify it as following, but
> it does not
> reproduce the error.
>
>
> #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
>
> static const char *v4l2_type_names[] = {
> [1] = "mmap",
> [9] = "userptr",
> [2] = "overlay",
> [3] = "dmabuf",
> };
>
> #define prt_names(a, arr) (((unsigned)(a)) < ARRAY_SIZE(arr) ? arr[a]
> : "unknown")
>
>
> extern void prt(const char *name);
>
> static void v4l_print_requestbuffers(const void *arg, int write_only)
> {
> const struct v4l2_requestbuffers *p = arg;
>
> prt(prt_names(3, v4l2_type_names));
> }
>
>
> If you have the test case, you are welcome to submit a patch to
> add the test case.
I experimented a bit more and it turned out that the use of EXPORT_SYMBOL
for the array is what causes the problem. Reproducible with this:
#include <linux/kernel.h>
#define prt_names(a, arr) (((unsigned)(a)) < ARRAY_SIZE(arr) ? arr[a] : "unknown")
extern const char *v4l2_names[];
const char *v4l2_names[] = {
[1] = "mmap",
[9] = "userptr",
[2] = "overlay",
[3] = "dmabuf",
};
EXPORT_SYMBOL(v4l2_names);
extern void prt(const char *name);
static void v4l_print_requestbuffers(const void *arg, int write_only)
{
prt(prt_names(3, v4l2_names));
}
And with this sparse command:
sparse -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/4.8/include -Iarch/x86/include -Iarch/x86/include/generated -Iinclude -Iarch/x86/include/uapi -Iarch/x86/include/generated/uapi -Iinclude/uapi -Iinclude/generated/uapi -include include/linux/kconfig.h -D__KERNEL__ x.c
If I remove EXPORT_SYMBOL all is well. EXPORT_SYMBOL expands to this:
extern typeof(v4l2_names) v4l2_names;
extern __attribute__((externally_visible)) void *__crc_v4l2_names __attribute__((weak));
static const unsigned long __kcrctab_v4l2_names __attribute__((__used__)) __attribute__((section("___kcrctab" "" "+" "v4l2_names"), unused)) = (unsigned long) &__crc_v4l2_names;
static const char __kstrtab_v4l2_names[] __attribute__((section("__ksymtab_strings"), aligned(1))) = "v4l2_names";
extern const struct kernel_symbol __ksymtab_v4l2_names;
__attribute__((externally_visible)) const struct kernel_symbol __ksymtab_v4l2_names __attribute__((__used__)) __attribute__((section("___ksymtab" "" "+" "v4l2_names"), unused)) = { (unsigned long)&v4l2_names, __kstrtab_v4l2_names };
I did some more research and the key is the first line:
extern typeof(v4l2_names) v4l2_names;
If I add that to your test case:
static const char *v4l2_type_names[] = {
[1] = "mmap",
[9] = "userptr",
[2] = "overlay",
[3] = "dmabuf",
};
extern typeof(v4l2_type_names) v4l2_type_names;
Then I get the same error with your test case.
The smallest test case I can make is this:
====== extern-array.c ======
extern const char *v4l2_type_names[];
const char *v4l2_type_names[] = {
"test"
};
extern const char *v4l2_type_names[];
static void test(void)
{
unsigned sz = sizeof(v4l2_type_names);
}
/*
* check-name: duplicate extern array
*
* check-error-start
* check-error-end
*/
====== extern-array.c ======
If I leave out the both 'extern' declarations I get:
warning: symbol 'v4l2_type_names' was not declared. Should it be static?
Which is a correct warning.
If I leave out the second 'extern' only, then all is fine. If I add both
'extern' declarations, then I get:
error: cannot size expression
which is clearly a sparse bug somewhere.
Regards,
Hans
next prev parent reply other threads:[~2014-03-30 12:03 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-15 12:09 sparse: ARRAY_SIZE and sparse array initialization Hans Verkuil
2014-03-15 12:12 ` Hans Verkuil
2014-03-28 10:50 ` Hans Verkuil
2014-03-30 6:10 ` Christopher Li
2014-03-30 12:03 ` Hans Verkuil [this message]
2014-03-30 16:48 ` Linus Torvalds
2014-03-30 17:03 ` Hans Verkuil
2014-03-30 17:16 ` Christopher Li
2014-03-30 17:24 ` Linus Torvalds
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=533807FC.5050008@xs4all.nl \
--to=hverkuil@xs4all.nl \
--cc=linux-media@vger.kernel.org \
--cc=linux-sparse@vger.kernel.org \
--cc=sparse@chrisli.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).