-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
I don't know, Walt! #13110
I don't know, Walt! #13110
Conversation
d6407a7
to
937ecf8
Compare
The "mark arguments used" commits are broken into two sections: the first one is the first commit, which replaces the sussy baka markings (all in module/), the second is the rest of the commits, which fix CI errors as I got them. |
Once you have everything building cleanly can you squash all the related fixes together. In particular, I'm mainly looking at the "mark arguments used" commits for the user libraries. The rest looks pretty reasonable to me. |
lib/libzpool/kernel.c
Outdated
@@ -117,7 +117,8 @@ zk_thread_create(void (*func)(void *), void *arg, size_t stksize, int state) | |||
VERIFY0(pthread_attr_setstacksize(&attr, stksize)); | |||
VERIFY0(pthread_attr_setguardsize(&attr, PAGESIZE)); | |||
|
|||
VERIFY0(pthread_create(&tid, &attr, (void *(*)(void *))func, arg)); | |||
VERIFY0(pthread_create(&tid, &attr, | |||
(void *(*)(void *))(uintptr_t)func, arg)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why cast to (uintptr_t)
? You're not doing bitwise operations on pointers; that seems a bit weird. Why not (void *)
, if you need the cast at all?
Moreover, POSIX (and I guess ISO C does the same) only guarantees the following:
The following type designates an unsigned integer type with the property that any valid pointer to void can be converted to this type, then converted back to a pointer to void, and the result will compare equal to the original pointer: uintptr_t
So you really can't even transform uintptr_t -> void * -> uintptr_t
. You're only allowed to do void * -> uintptr_t -> void *
. Going from uintptr_t
to function pointer is UB, although I expect it to work, but who knows GCC 20 :)
What's the warning you're trying to silence?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
func
is void (*)(void *)
, pthread_create()
takes void *(*)(void *)
, this produces an invalid cast warning (and rightfully so):
In file included from kernel.c:27:
kernel.c: In function ‘zk_thread_create’:
kernel.c:121:6: warning: cast between incompatible function types from ‘void (*)(void *)’ to ‘void * (*)(void *)’ [-Wcast-function-type]
121 | (void *(*)(void *))func, arg));
| ^
../../lib/libspl/include/assert.h:104:37: note: in definition of macro ‘VERIFY0’
104 | const uint64_t __left = (uint64_t)(LEFT); \
| ^~~~
What I did think about doing was allocating a (func, arg) bundle and pushing it through a helper, but this would screw with the (seemingly) precise stack size measurements, so.
I mean, casting it like this is obviously technically UB anyway because of the incompatible return types, but going through an uintptr_t
(or, indeed, a pointer) is worse? But then save for a union or screwing with the stack size stuff I can't realistically come up with a good way of making the compiler go away here.
Updated to use a union.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. Here there be dragons!
- Converting between function pointers is permitted by the standard (you may not use it to call, but you can store). See C2x::6.3.2.3/8:
A pointer to a function of one type may be converted to a pointer to a function of another type and
back again; the result shall compare equal to the original pointer. If a converted pointer is used to
call a function whose type is not compatible with the referenced type, the behavior is undefined.
- The call is being done in a different translation unit, and therefore, the compiler can't know if you will invoke UB or not, so it has to assume you're not invoking UB, and so it needs to follow the ABI.
- If the ABI defines both function pointers to be compatible (I assume they are, or you'd've noticed before), then, I think (not 100% sure, dragons are flying around) it's defined behavior ($DEITY bless translation unit boundaries to workaround UB).
So I'd say you're not invoking UB with the function pointer cast, but you need a cast. I'd either use -Wno-cast-function-type
(since the compiler is invalidly blaming you) or cast to (void *)
, if you need to keep that warning. Choose your poison carefully.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good find – I rolled back to the straight cast and added -Wno-cast-function-type
to this file, pointing at this thread. It should™ be fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, there's another thing you could do to not disable the warning from the compiler: use noreturn
.
As weird as it may seem, noreturn int foo(void);
is valid C (I asked a question to corfirm it, though).
So you may use the prototype that pthread_create(3)
expects, mark it as noreturn
, and then the compiler should not warn about it.
Example:
alx@ady1:~/src/test$ cat noreturn.c
#include <stdnoreturn.h>
#include <pthread.h>
noreturn void *foo(void *x);
int bar(pthread_t *restrict th, void *arg);
noreturn void *
foo(void *x)
{
pthread_exit(x);
}
int
bar(pthread_t *restrict th, void *arg)
{
return pthread_create(th, NULL, &foo, arg);
}
alx@ady1:~/src/test$ cc -Wall -Wextra -Werror -S noreturn.c
alx@ady1:~/src/test$ clang -Wall -Wextra -Weverything -Werror -S noreturn.c
But you'd need to modify a few functions for that.
I used that trick in some embedded systems where main()
needs to be int main(void)
, but it's an infinite loop and never returns, so I declared it as noreturn int main(void)
:)
Using noreturn
in this case has the advantage that the behavior is 100% defined (as long as the Standard continues allowing this dirty hack), since you don't depend on the ABI having compatible function calls for a return of void
and void *
, but has the readability problems that one may ask WTF means noreturn void*
. Again, choose your poison carefully :p
741e802
to
2236408
Compare
@behlendorf squished all the userspace argsused, and fixed all the problems Alejandro found (and the rest that I did when rereading) – if CI gives it the all-clear then it should be g2g |
Consider this, which you may have not read since I replied when it was already marked as resolved: |
I get mail for all comments, worry not. |
35868a6
to
eb18ab9
Compare
@@ -230,7 +230,7 @@ get_special_prop(lua_State *state, dsl_dataset_t *ds, const char *dsname, | |||
char *strval = kmem_alloc(ZAP_MAXVALUELEN, KM_SLEEP); | |||
char setpoint[ZFS_MAX_DATASET_NAME_LEN] = | |||
"Internal error - setpoint not determined"; | |||
zfs_type_t ds_type; | |||
zfs_type_t ds_type = -1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it guaranteed that get_objset_type(ds, &ds_type)
won't fail below? Otherwise, you might want to check the return code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's void-casted there (and used elsewhere) so I think so, yeah.
lib/libnvpair/libnvpair_json.c
Outdated
@@ -27,6 +27,8 @@ | |||
return (-1); \ | |||
} while (0) | |||
|
|||
#define IS_UNSIGNED(tp) ((tp)0 - 1 > 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can cast -1
directly. Don't need to subtract from 0.
And you can use a slightly better version which accepts a variable:
#define is_unsigned(x) (((__typeof__(x)) -1) > 0)
So you can use c
directly:
if (((IS_UNSIGNED(c) || c >= 0x00) && c <= 0x1f) || (c > 0x7f && c <= 0xffff))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can also not to that because it doesn't work. And neither does any other suppression method, as noted in the original thread #13110 (comment)
@@ -9,6 +9,10 @@ VPATH = \ | |||
AM_CFLAGS += $(FRAME_LARGER_THAN) $(LIBTIRPC_CFLAGS) | |||
AM_CFLAGS += -fvisibility=hidden | |||
|
|||
# wchar_t is undefined-signedness, but we compare to >=0; this warns with unsigned wchar_t | |||
libnvpair_json.$(OBJEXT): CFLAGS += -Wno-type-limits | |||
libnvpair_json.l$(OBJEXT): CFLAGS += -Wno-type-limits |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much cleaner, yep :p
8179c60
to
8145488
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signed-off-by: Ahelenia Ziemiańska <[email protected]>
Signed-off-by: Ahelenia Ziemiańska <[email protected]>
Signed-off-by: Ahelenia Ziemiańska <[email protected]>
Reviewed-by: Alejandro Colomar <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes openzfs#13110
Reviewed-by: Alejandro Colomar <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes openzfs#13110
Reviewed-by: Alejandro Colomar <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes openzfs#13110
Reviewed-by: Alejandro Colomar <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes openzfs#13110
Reviewed-by: Alejandro Colomar <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes openzfs#13110
Reviewed-by: Alejandro Colomar <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes openzfs#13110
Reviewed-by: Alejandro Colomar <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes openzfs#13110
A function that returns with no value is a different thing from a function that doesn't return at all. Those are two orthogonal concepts, commonly confused. pthread_create(3) expects a pointer to a start routine that has a very precise prototype: void *(*start_routine)(void *); However, other thread functions, such as kernel ones, expect: void (*start_routine)(void *); Providing a different one is incorrect, and has only been working because the ABIs happen to produce a compatible function. We should use '_Noreturn void', since it's the natural type, and then provide a '_Noreturn void *' wrapper for pthread functions. For consistency, replace most cases of __NORETURN or __attribute__((noreturn)) by _Noreturn. _Noreturn is understood by -std=gnu89, so it should be safe to use everywhere. Ref: openzfs#13110 (comment) Ref: https://software.codidact.com/posts/285972 Reviewed-by: Brian Behlendorf <[email protected]> Co-authored-by: Ahelenia Ziemiańska <[email protected]> Signed-off-by: Alejandro Colomar <[email protected]> Closes openzfs#13120
Reviewed-by: Alejandro Colomar <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes openzfs#13110
Reviewed-by: Alejandro Colomar <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes openzfs#13110
Reviewed-by: Alejandro Colomar <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes openzfs#13110
Reviewed-by: Alejandro Colomar <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes openzfs#13110
Which produces a warning since uints are, by definition, >=0 Reviewed-by: Alejandro Colomar <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes openzfs#13110
Also remove -Wno-unused-but-set-variable Upstream-bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61118 Reviewed-by: Alejandro Colomar <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes openzfs#13110
Reviewed-by: Alejandro Colomar <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes openzfs#13110
Reviewed-by: Alejandro Colomar <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes openzfs#13110
Reviewed-by: Alejandro Colomar <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes openzfs#13110
Reviewed-by: Alejandro Colomar <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes openzfs#13110
Reviewed-by: Alejandro Colomar <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes openzfs#13110
Reviewed-by: Alejandro Colomar <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes openzfs#13110
Reviewed-by: Alejandro Colomar <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes openzfs#13110
A function that returns with no value is a different thing from a function that doesn't return at all. Those are two orthogonal concepts, commonly confused. pthread_create(3) expects a pointer to a start routine that has a very precise prototype: void *(*start_routine)(void *); However, other thread functions, such as kernel ones, expect: void (*start_routine)(void *); Providing a different one is incorrect, and has only been working because the ABIs happen to produce a compatible function. We should use '_Noreturn void', since it's the natural type, and then provide a '_Noreturn void *' wrapper for pthread functions. For consistency, replace most cases of __NORETURN or __attribute__((noreturn)) by _Noreturn. _Noreturn is understood by -std=gnu89, so it should be safe to use everywhere. Ref: openzfs#13110 (comment) Ref: https://software.codidact.com/posts/285972 Reviewed-by: Brian Behlendorf <[email protected]> Co-authored-by: Ahelenia Ziemiańska <[email protected]> Signed-off-by: Alejandro Colomar <[email protected]> Closes openzfs#13120
A function that returns with no value is a different thing from a function that doesn't return at all. Those are two orthogonal concepts, commonly confused. pthread_create(3) expects a pointer to a start routine that has a very precise prototype: void *(*start_routine)(void *); However, other thread functions, such as kernel ones, expect: void (*start_routine)(void *); Providing a different one is incorrect, and has only been working because the ABIs happen to produce a compatible function. We should use '_Noreturn void', since it's the natural type, and then provide a '_Noreturn void *' wrapper for pthread functions. For consistency, replace most cases of __NORETURN or __attribute__((noreturn)) by _Noreturn. _Noreturn is understood by -std=gnu89, so it should be safe to use everywhere. Ref: openzfs#13110 (comment) Ref: https://software.codidact.com/posts/285972 Reviewed-by: Brian Behlendorf <[email protected]> Co-authored-by: Ahelenia Ziemiańska <[email protected]> Signed-off-by: Alejandro Colomar <[email protected]> Closes openzfs#13120
A function that returns with no value is a different thing from a function that doesn't return at all. Those are two orthogonal concepts, commonly confused. pthread_create(3) expects a pointer to a start routine that has a very precise prototype: void *(*start_routine)(void *); However, other thread functions, such as kernel ones, expect: void (*start_routine)(void *); Providing a different one is incorrect, and has only been working because the ABIs happen to produce a compatible function. We should use '_Noreturn void', since it's the natural type, and then provide a '_Noreturn void *' wrapper for pthread functions. For consistency, replace most cases of __NORETURN or __attribute__((noreturn)) by _Noreturn. _Noreturn is understood by -std=gnu89, so it should be safe to use everywhere. Ref: openzfs#13110 (comment) Ref: https://software.codidact.com/posts/285972 Reviewed-by: Brian Behlendorf <[email protected]> Co-authored-by: Ahelenia Ziemiańska <[email protected]> Signed-off-by: Alejandro Colomar <[email protected]> Closes openzfs#13120
A function that returns with no value is a different thing from a function that doesn't return at all. Those are two orthogonal concepts, commonly confused. pthread_create(3) expects a pointer to a start routine that has a very precise prototype: void *(*start_routine)(void *); However, other thread functions, such as kernel ones, expect: void (*start_routine)(void *); Providing a different one is incorrect, and has only been working because the ABIs happen to produce a compatible function. We should use '_Noreturn void', since it's the natural type, and then provide a '_Noreturn void *' wrapper for pthread functions. For consistency, replace most cases of __NORETURN or __attribute__((noreturn)) by _Noreturn. _Noreturn is understood by -std=gnu89, so it should be safe to use everywhere. Ref: openzfs#13110 (comment) Ref: https://software.codidact.com/posts/285972 Reviewed-by: Brian Behlendorf <[email protected]> Co-authored-by: Ahelenia Ziemiańska <[email protected]> Signed-off-by: Alejandro Colomar <[email protected]> Closes openzfs#13120
A function that returns with no value is a different thing from a function that doesn't return at all. Those are two orthogonal concepts, commonly confused. pthread_create(3) expects a pointer to a start routine that has a very precise prototype: void *(*start_routine)(void *); However, other thread functions, such as kernel ones, expect: void (*start_routine)(void *); Providing a different one is incorrect, and has only been working because the ABIs happen to produce a compatible function. We should use '_Noreturn void', since it's the natural type, and then provide a '_Noreturn void *' wrapper for pthread functions. For consistency, replace most cases of __NORETURN or __attribute__((noreturn)) by _Noreturn. _Noreturn is understood by -std=gnu89, so it should be safe to use everywhere. Ref: openzfs#13110 (comment) Ref: https://software.codidact.com/posts/285972 Reviewed-by: Brian Behlendorf <[email protected]> Co-authored-by: Ahelenia Ziemiańska <[email protected]> Signed-off-by: Alejandro Colomar <[email protected]> Closes openzfs#13120
A function that returns with no value is a different thing from a function that doesn't return at all. Those are two orthogonal concepts, commonly confused. pthread_create(3) expects a pointer to a start routine that has a very precise prototype: void *(*start_routine)(void *); However, other thread functions, such as kernel ones, expect: void (*start_routine)(void *); Providing a different one is incorrect, and has only been working because the ABIs happen to produce a compatible function. We should use '_Noreturn void', since it's the natural type, and then provide a '_Noreturn void *' wrapper for pthread functions. For consistency, replace most cases of __NORETURN or __attribute__((noreturn)) by _Noreturn. _Noreturn is understood by -std=gnu89, so it should be safe to use everywhere. Ref: openzfs#13110 (comment) Ref: https://software.codidact.com/posts/285972 Reviewed-by: Brian Behlendorf <[email protected]> Co-authored-by: Ahelenia Ziemiańska <[email protected]> Signed-off-by: Alejandro Colomar <[email protected]> Closes openzfs#13120
A function that returns with no value is a different thing from a function that doesn't return at all. Those are two orthogonal concepts, commonly confused. pthread_create(3) expects a pointer to a start routine that has a very precise prototype: void *(*start_routine)(void *); However, other thread functions, such as kernel ones, expect: void (*start_routine)(void *); Providing a different one is incorrect, and has only been working because the ABIs happen to produce a compatible function. We should use '_Noreturn void', since it's the natural type, and then provide a '_Noreturn void *' wrapper for pthread functions. For consistency, replace most cases of __NORETURN or __attribute__((noreturn)) by _Noreturn. _Noreturn is understood by -std=gnu89, so it should be safe to use everywhere. Ref: openzfs#13110 (comment) Ref: https://software.codidact.com/posts/285972 Reviewed-by: Brian Behlendorf <[email protected]> Co-authored-by: Ahelenia Ziemiańska <[email protected]> Signed-off-by: Alejandro Colomar <[email protected]> Closes openzfs#13120
A function that returns with no value is a different thing from a function that doesn't return at all. Those are two orthogonal concepts, commonly confused. pthread_create(3) expects a pointer to a start routine that has a very precise prototype: void *(*start_routine)(void *); However, other thread functions, such as kernel ones, expect: void (*start_routine)(void *); Providing a different one is incorrect, and has only been working because the ABIs happen to produce a compatible function. We should use '_Noreturn void', since it's the natural type, and then provide a '_Noreturn void *' wrapper for pthread functions. For consistency, replace most cases of __NORETURN or __attribute__((noreturn)) by _Noreturn. _Noreturn is understood by -std=gnu89, so it should be safe to use everywhere. Ref: openzfs#13110 (comment) Ref: https://software.codidact.com/posts/285972 Reviewed-by: Brian Behlendorf <[email protected]> Co-authored-by: Ahelenia Ziemiańska <[email protected]> Signed-off-by: Alejandro Colomar <[email protected]> Closes openzfs#13120
Motivation and Context
You've been acting pretty sus lately!
Description
Almost like there's an impostor among us.
Well, there isn't any-more. See individual commit messages.
Or, well, do so tomorrow because I need to write them.Also there's a -Wunused-parameters thing for kFreeBSD module at the top. It'll probably be gone because the headers are, I'm assuming, as irredeemable as Linux's.How Has This Been Tested?
Builds. Crucially, I can finally inline my configure CFLAGS I've been nursing for two(?!!) years into the autohell rules.
Types of changes
Checklist:
Signed-off-by
.