This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author serhiy.storchaka
Recipients ammar2, gregory.p.smith, malin, serhiy.storchaka, sir-sigurd, vstinner, zach.ware
Date 2019-09-19.14:59:53
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1568905193.84.0.365973061271.issue38205@roundup.psfhosted.org>
In-reply-to
Content
_Py_NO_RETURN is a promise that the code past the function is unreachable, not that the function call is unreachable.

> I'm not sure how __builtin_unreachable could be used with Py_UNREACHABLE() macro.

In the release mode Py_UNREACHABLE() can be replaced with __builtin_unreachable().

> For example, if a function accepts an enum, but is called with a value which is not part of the enum: what should happen? Should Python crash?

If the accessibility of the code depends on the call from Python code, we should raise normal exception. If it is not possible to pass it out of the function, we should use PyErr_WriteUnraisable().

If the accessibility of the code depends on the call from C code, 
we can use PyErr_BadInternalCall() or raise a SystemError directly.

If we are in the situation where recovering from errors is not possible (for example if the memory manager is broken) we use Py_FatalError().

If we are absolutely sure that the code never can be executed (unless memory was corrupted or something like), we use Py_UNREACHABLE(). It will silence compiler complains, fail loudly in debug mode if our assumption is wrong (this is our programming bug), and allow the compiler to optimize out the code if substituted by __builtin_unreachable() in the release mode.

> I don't see how the compiler can guess that the code is never executed with the current macro.

But we can make the macro to expand to __builtin_unreachable in the release mode. Or just to no-op if there is other way to silence the compiler warning.

> Using a function allows to put a breakpoint on it.

You can put a brackpoint on Py_FatalError().

> In fact, I can easily modify PR 16280 to keep the macro, since I only call Py_FatalError() with a string.

It would be nice. We can consider using __builtin_unreachable() in different issue. I am also going to use Py_UNREACHABLE() more widely to write more uniform, but still optimal code. It could replace

    if (cond1) { ...
    } else if (cond2) { ...
    } else if (cond3) { ...
    } else {
        assert (!cond4);
        ...
    }

with

    if (cond1) { ...
    } else if (cond2) { ...
    } else if (cond3) { ...
    } else if (cond4) { ...
    } else {
        Py_UNREACHABLE();
    }
History
Date User Action Args
2019-09-19 14:59:53serhiy.storchakasetrecipients: + serhiy.storchaka, gregory.p.smith, vstinner, zach.ware, malin, ammar2, sir-sigurd
2019-09-19 14:59:53serhiy.storchakasetmessageid: <1568905193.84.0.365973061271.issue38205@roundup.psfhosted.org>
2019-09-19 14:59:53serhiy.storchakalinkissue38205 messages
2019-09-19 14:59:53serhiy.storchakacreate