https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79173
--- Comment #26 from Marc Glisse <glisse at gcc dot gnu.org> --- (In reply to CVS Commits from comment #22) > While the design of these builtins in clang is questionable, > rather than being say > unsigned __builtin_addc (unsigned, unsigned, bool, bool *) > so that it is clear they add two [0, 0xffffffff] range numbers > plus one [0, 1] range carry in and give [0, 0xffffffff] range > return plus [0, 1] range carry out, they actually instead > add 3 [0, 0xffffffff] values together but the carry out > isn't then the expected [0, 2] value because > 0xffffffffULL + 0xffffffff + 0xffffffff is 0x2fffffffd, > but just [0, 1] whether there was any overflow at all. That is very strange. I always thought that the original intent was for __builtin_addc to assume that its third argument was in [0, 1] and generate a single addc instruction on hardware that has it, and the type only ended up being the same as the others for convenience (also C used not to have a bool type). The final overflow never being 2 confirms this. It may be worth discussing with clang developers if they would be willing to document such a [0, 1] restriction, and maybe have ubsan check it.