Non-reentrant Functions as Macros for utilities used in both Main and Interrupts
Like the compiler message tells you, the code is duplicated. This has the very same effect as being inlined, put aside the overhead for call and return. Both versions are independent and can't influence each other.

So it's up to you to choose.


Relying on the compiler's capability makes your code less portable. And you get the compiler message which might be disturbing.
AFAIK inline just gives the compiler a hint. It does not have to obey it.
You best bet would be to use your last idea of making it a macro expression / statement.

For the latter this is common style:

#define function_name() do { /* anything it should do */ } while (0)

so you could use it like a void expression. If you accidentally try to assign it you'll get an error message. Please note the missing semicolon at the end. This will be provided at the place of the usage:

function_name();