It is wrong, but only because of the weirdness of how this works.
The call to strlen is not replaced with builtin_strlen, it defines both a builtin_strlen and a strlen.
Both are marked pure and nothrow.
Due to some wonderful oddness around freestanding environments, if you use -fno-builtin, it will define neither.
Due to some wonderful oddness around freestanding environments, if you use -fno-builtin, it will define neither.