Skip to content

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

HuidaeCho
Copy link
Member

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.

It does not make sense for a noreturn function to have a return type other than void.

@github-actions github-actions bot added raster Related to raster data processing C Related code is in C libraries module labels May 31, 2025
@HuidaeCho HuidaeCho changed the title Build: Fix warnings about control paths build: Fix warnings about control paths May 31, 2025
Copy link
Member

@echoix echoix left a 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/Common-Function-Attributes.html#index-noreturn-function-attribute

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;
Copy link
Member

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.

Copy link
Contributor

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).

Copy link
Member Author

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;
Copy link
Contributor

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?

Copy link
Member Author

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]

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

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

Copy link
Member Author

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

Copy link
Member

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?

Copy link
Contributor

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)):

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

Copy link
Contributor

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;

Copy link
Contributor

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)

Copy link
Contributor

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C Related code is in C libraries module raster Related to raster data processing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants