* [PATCH v2] sparse: treat function pointers as pointers to const data
@ 2014-09-07 12:36 Ard Biesheuvel
2014-09-07 17:14 ` Josh Triplett
0 siblings, 1 reply; 3+ messages in thread
From: Ard Biesheuvel @ 2014-09-07 12:36 UTC (permalink / raw)
To: sparse, linux-sparse; +Cc: will.deacon, Ard Biesheuvel
This code snippet:
static void bar(void const *arg)
{
int (*foo)(void) = arg;
}
produces the following warning:
test.c:4:28: warning: incorrect type in initializer (different modifiers)
test.c:4:28: expected int ( *foo )( ... )
test.c:4:28: got void const *arg
which is caused by the fact that the function pointer 'foo' is not annotated
as being a pointer to const data. However, dereferencing a function pointer
does not produce an lvalue, so a function pointer points to const data by
definition, and we should treat it accordingly.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
OK, so while my v1 did solve the example case, it turns out universally treating
function pointers as pointers to const data produces so much fallout that it
does more harm than good.
Instead, this v2 only addresses function pointer initializers and assignments.
--
Ard.
evaluate.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/evaluate.c b/evaluate.c
index 66556150ddac..a5a830978bda 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -1359,6 +1359,15 @@ static int compatible_assignment_types(struct expression *expr, struct symbol *t
typediff = "different address spaces";
goto Err;
}
+ /*
+ * If this is a function pointer assignment, it is
+ * actually fine to assign a pointer to const data to
+ * it, as a function pointer points to const data
+ * implicitly, i.e., dereferencing it does not produce
+ * an lvalue.
+ */
+ if (b1->type == SYM_FN)
+ mod1 |= MOD_CONST;
if (mod2 & ~mod1) {
typediff = "different modifiers";
goto Err;
--
1.8.3.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v2] sparse: treat function pointers as pointers to const data
2014-09-07 12:36 [PATCH v2] sparse: treat function pointers as pointers to const data Ard Biesheuvel
@ 2014-09-07 17:14 ` Josh Triplett
2014-09-07 17:29 ` Ard Biesheuvel
0 siblings, 1 reply; 3+ messages in thread
From: Josh Triplett @ 2014-09-07 17:14 UTC (permalink / raw)
To: Ard Biesheuvel; +Cc: sparse, linux-sparse, will.deacon
On Sun, Sep 07, 2014 at 02:36:53PM +0200, Ard Biesheuvel wrote:
> This code snippet:
>
> static void bar(void const *arg)
> {
> int (*foo)(void) = arg;
> }
>
> produces the following warning:
>
> test.c:4:28: warning: incorrect type in initializer (different modifiers)
> test.c:4:28: expected int ( *foo )( ... )
> test.c:4:28: got void const *arg
>
> which is caused by the fact that the function pointer 'foo' is not annotated
> as being a pointer to const data. However, dereferencing a function pointer
> does not produce an lvalue, so a function pointer points to const data by
> definition, and we should treat it accordingly.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
As a data point: gcc does not warn about this case either, whereas it
does warn about "int *foo = arg". So, this seems fine to me.
Reviewed-by: Josh Triplett <josh@joshtriplett.org>
> OK, so while my v1 did solve the example case, it turns out universally treating
> function pointers as pointers to const data produces so much fallout that it
> does more harm than good.
Can you elaborate on the fallout, and ideally provide that rationale in
the commit message?
- Josh Triplett
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v2] sparse: treat function pointers as pointers to const data
2014-09-07 17:14 ` Josh Triplett
@ 2014-09-07 17:29 ` Ard Biesheuvel
0 siblings, 0 replies; 3+ messages in thread
From: Ard Biesheuvel @ 2014-09-07 17:29 UTC (permalink / raw)
To: Josh Triplett; +Cc: sparse, linux-sparse, Will Deacon
On 7 September 2014 19:14, Josh Triplett <josh@joshtriplett.org> wrote:
> On Sun, Sep 07, 2014 at 02:36:53PM +0200, Ard Biesheuvel wrote:
>> This code snippet:
>>
>> static void bar(void const *arg)
>> {
>> int (*foo)(void) = arg;
>> }
>>
>> produces the following warning:
>>
>> test.c:4:28: warning: incorrect type in initializer (different modifiers)
>> test.c:4:28: expected int ( *foo )( ... )
>> test.c:4:28: got void const *arg
>>
>> which is caused by the fact that the function pointer 'foo' is not annotated
>> as being a pointer to const data. However, dereferencing a function pointer
>> does not produce an lvalue, so a function pointer points to const data by
>> definition, and we should treat it accordingly.
>>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>
> As a data point: gcc does not warn about this case either, whereas it
> does warn about "int *foo = arg". So, this seems fine to me.
>
> Reviewed-by: Josh Triplett <josh@joshtriplett.org>
>
>> OK, so while my v1 did solve the example case, it turns out universally treating
>> function pointers as pointers to const data produces so much fallout that it
>> does more harm than good.
>
> Can you elaborate on the fallout, and ideally provide that rationale in
> the commit message?
>
Treating a function pointer as pointer-to-const-data in every
occurrence results in sparse triggering on the inverse case, i.e.
extern int (*foo)(void);
void *arg = foo;
which is a pattern that is widely used in the kernel, arguably
incorrect (considering the nature of a function pointer) but not the
case I intended to address.
I will put something to that effect in the v3 commit message.
Cheers,
Ard.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-09-07 17:29 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-09-07 12:36 [PATCH v2] sparse: treat function pointers as pointers to const data Ard Biesheuvel
2014-09-07 17:14 ` Josh Triplett
2014-09-07 17:29 ` Ard Biesheuvel
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.