-
-
Notifications
You must be signed in to change notification settings - Fork 360
build: Fix warnings about control paths #5806
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
base: main
Are you sure you want to change the base?
Conversation
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 also found the current GCC docs (15.1.0) for the equivalent contents linked from the GCC 3.4.3 docs.
https://gcc.gnu.org/onlinedocs/gcc-15.1.0/gcc/Function-Attributes.html
I had one question, where I'm not sure, otherwise it is straightforward.
@@ -124,6 +124,8 @@ static int is_flag(const void *p) | |||
} | |||
|
|||
G_fatal_error(_("Internal error: option or flag not found")); | |||
|
|||
return -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.
I know this is under a G_fatal_error, so shouldn't be reached. But the 4 usages of this function in this file only check with if (is_flag(p)) {}
, so a non-zero value, here -1, doesn't mean the same.
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.
Code after G_fatal_error
is never reached and thus unnecessary. (Competent static analysers recognises this too).
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 know this is under a G_fatal_error, so shouldn't be reached. But the 4 usages of this function in this file only check with
if (is_flag(p)) {}
, so a non-zero value, here -1, doesn't mean the same.
You're right. We could do if (is_flag(p) == 1)
, but again, we'll never reach return -1
anyway. It's just there to suppress the warning.
@@ -227,6 +226,7 @@ static avl_node *avl_individua(const avl_tree root, const generic_cell k, | |||
G_fatal_error("\avl.c: avl_individua: error"); | |||
} | |||
} | |||
return NULL; |
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.
This is also never reached. I wonder how you triggered these warnings?
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 think MSVC reports these warnings by default:
C:\Users\hcho\usr\grass\grass\raster\r.li\r.li.daemon\avl.c(230,1): warning C4715: 'avl_individua': not all control paths return a value [C:\Users\hcho\usr\grass\grass\build27\raster\r.li\grass_rli.vcxproj]
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.
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.
At the end of that page, it points ta a link that shows how to use __declspec(noreturn)
to annotate a function that never returns, for that analysis.
https://learn.microsoft.com/en-us/cpp/cpp/noreturn?view=msvc-170
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.
That's for void
functions technically. Or
It does not make sense for a noreturn function to have a return type other than void.
https://gcc.gnu.org/onlinedocs/gcc-3.4.3/gcc/Function-Attributes.html
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 meant fixing the annotation on G_fatal_error, it should be void right?
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.
G_fatal_error
is attributed with __attribute__((noreturn))
:
grass/include/grass/defs/gis.h
Lines 312 to 313 in d129608
void G_fatal_error(const char *, ...) __attribute__((format(printf, 1, 2))) | |
__attribute__((noreturn)); |
maybe that needs an update for windows?
This is a very common practice (no return after G_fatal_error) in GRASS code, so this should be solved in a more general way.
Something like:
void G_fatal_error(const char *, ...) __attribute__((format(printf, 1, 2)))
#if defined(_MSC_VER)
__declspec(noreturn);
#else
__attribute__((noreturn));
#endif
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.
If my proposed change works, I'd suggest defining a macro in gis.h:
#if defined(_MSC_VER)
#define G_NORETURN __declspec(noreturn)
#else
#define G_NORETURN __attribute__((noreturn))
#endif
which then can be added:
void G_fatal_error(const char *, ...) __attribute__((format(printf, 1, 2))) G_NORETURN;
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.
Or using the C11 keyword _Noreturn
#if __STDC_VERSION__ < 202311L
#define G_NORETURN _Noreturn
#else
#define G_NORETURN [[noreturn]]
#endif
...
G_NORETURN void G_fatal_error(const char *, ...) __attribute__((format(printf, 1, 2)));
(untested)
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.
The _Noreturn suggestion above doesn't work well with C++, however this seems to work:
#if __STDC_VERSION__ < 202311L
#if defined(_MSC_VER)
#define G_NORETURN __declspec(noreturn)
#else
#define G_NORETURN __attribute__((noreturn))
#endif
#else
#define G_NORETURN [[noreturn]]
#endif
(The [[noreturn]]
attribute is added to C23 as well as C++11).
This PR fixes control path warnings by adding a return statement after fatal. For noreturn functions, use
void
. See https://gcc.gnu.org/onlinedocs/gcc-3.4.3/gcc/Function-Attributes.html.