не, в современных компиляторах эти флажки вообще влияют только на вес, а дальше компиль уже сам все решает.
да, always_inline подвинет вес функции ближе в сторону инлайнинга, но инлайнинг он не гарантирует.
https://github.com/llvm/llvm-project/blob/main/llvm/lib/Transforms/IPO/AlwaysInliner.cpp#L175/// The always inliner *only* handles functions which are marked with the
/// attribute to force inlining. As such, it is dramatically simpler and avoids
/// using the powerful (but expensive) inline cost analysis. Instead it uses
/// a very simple and boring direct walk of the instructions looking for
/// impossible-to-inline constructs.
Хочу ззаметить, что always_inline даже пытется заинлайнить циклы
https://github.com/llvm/llvm-project/blob/main/llvm/lib/Transforms/IPO/AlwaysInliner.cpp#L146Ну и сюдя по этой весовой функции:
https://github.com/llvm/llvm-project/blob/8b0bd54d0ec968df28ccc58bbb537a7b7c074ef2/llvm/lib/Analysis/InlineCost.cpp#L2619Инлайн не происходит по следующим причинам:
1) Наличие indirect branches (aka computed goto)
2) Не может вычислить адрес функции (indirect call)
3) Рекурсивные вызовы
4) ReturnsTwice (имеет аттрибут returns_twice)
5) Имеет всякую экзотику вроде va_start, @llvm.icall.branch.funnel и @llvm.localescape
В общем то все. И да, во всех случаях он должен выдать предупреждение