Date: Sun, 2 Mar 2014 09:25:15 -0700 From: Warner Losh <imp@bsdimp.com> To: Ahmed Charles <acharles@outlook.com> Cc: "freebsd-toolchain@FreeBSD.org" <freebsd-toolchain@freebsd.org> Subject: Re: More dangerous UB handling of clang (compared to gcc) Message-ID: <3DC02993-ADCF-4403-BA0F-61DBEDDB2116@gmail.com> In-Reply-To: <BLU182-W8476794FA6158DED9ACB59DF8D0@phx.gbl> References: <20140228150650.GE29171@hades.panopticon>, <214F7253-A262-4ED1-8E38-672A5ECDFB6D@bsdimp.com> <BLU182-W8476794FA6158DED9ACB59DF8D0@phx.gbl>
next in thread | previous in thread | raw e-mail | index | archive | help
On Mar 1, 2014, at 4:18 PM, Ahmed Charles <acharles@outlook.com> wrote: > ---------------------------------------- >> Subject: Re: More dangerous UB handling of clang (compared to gcc) >> From: bsdimp@gmail.com >> Date: Fri, 28 Feb 2014 08:38:38 -0700 >> To: amdmi3@amdmi3.ru >> CC: freebsd-toolchain@FreeBSD.org >>=20 >>=20 >> On Feb 28, 2014, at 8:06 AM, Dmitry Marakasov <amdmi3@amdmi3.ru> = wrote: >>=20 >>> Hi! >>>=20 >>> Another issue I wanted to mention: compared to gcc, clang handles >>> some undefined behaviour cases more dangerously. It has the full >>> right to do so as it's UB, however we may want to take extra steps >>> to find and fix these cases. >>=20 >> Except this is a flat out bug=E2=80=A6. >>=20 >>> Example: >>>=20 >>> --- ub.cc begins here --- >>> #include <iostream> >>>=20 >>> int func1() { >>> std::cerr << "func1()\n"; >>> /* no return */ >>> } >>>=20 >>> void func2() { >>> std::cerr << "NEVER CALLED\n"; >>> } >>>=20 >>> int main() { >>> func1(); >>> return 0; >>> } >>> --- ub.cc ends here --- >>>=20 >>> --- >>> % g++46 -o ub ub.cc && ./ub >>> func1() >>> % g++46 -O2 -o ub ub.cc && ./ub >>> func1() >>> % clang++ -o ub ub.cc && ./ub >>> ub.cc:6:1: warning: control reaches end of non-void function >>> [-Wreturn-type] >>> } >>> ^ >>> 1 warning generated. >>> func1() >>> Illegal instruction >>> % clang++ -O2 -o ub ub.cc && ./ub >>> ub.cc:6:1: warning: control reaches end of non-void function >>> [-Wreturn-type] >>> } >>> ^ >>> 1 warning generated. >>> func1() >>> NEVER CALLED >>> Segmentation fault >>> --- >>>=20 >>> As you can see, while with gcc the function returns even if it has = no >>> return statement, with clang it either crashes or calls the = following >>> function. This may lead to new crashes and security problems after >>> switching to clang (most likely in ports code of course). >>=20 >> This is a flat out bug. When control reaches the end of a function, = it must return, even if there=E2=80=99s no return statement. The value = returned from func1() is, of course, undefined, but this is well defined = behavior in the standard=E2=80=A6 >>=20 >> I=E2=80=99d be very interested to see chapter and verse on this = one... >=20 > n3690: 6.6.3[stmt.return]/p2 >=20 > Flowing off the end of a function is equivalent to a return with no = value; this results in undefined behavior in a value-returning function. >=20 > C++ and C are distinctly different in this regard. Seems like the =E2=80=98jump into the next function=E2=80=99 as a result = of the core dump you put in being optimized away is a breathtakingly = stupid, but allowed, undefined behavior. I mean, as stupid as forking = rogue when #pragma is encountered. Better for that forced core dump to = not be optimized away, or there be a return statement. Hence my belief that the resolution is bogus. >>> I wonder of we could make use of -Werror=3Dreturn-type which makes = the >>> warning issued by clang here fatal, what do you think? If adding it = to >>> default CFLAGS/CXXFLAGS is not an option, we may at least have an >>> extra `strict' pkg-fallout builder. >>>=20 >>> Related clang bug: http://llvm.org/bugs/show_bug.cgi?id=3D18296 = (resoleved >>> as INVALID). >>=20 >> I believe this resolution is, in fact, bogus. Sure, insert ud2, but = also put a f=E2=80=99ing return in there. >>=20 >> I know in C11,this id definitely the case: >>=20 >> 6.9.1: >> 12 If the } that terminates a function is reached, and the value of = the function call is used by >> the caller, the behavior is unde=EF=AC=81ned. >>=20 >> But the C++ standard is somewhat opaque on the topic, but none of the = 56 instances of =E2=80=98undefined results=E2=80=99 in the standard = appeared to apply. >>=20 >>> I'm also positively sure that I've encountered another problematic >>> UB case with another warning, but I don't remember which. Real >>> list of useful Werror's may be quite big. >>=20 >> Yea, this is a big deal. Sure, people shouldn=E2=80=99t do this, but = this kind of undefined behavior is well outside the bounds of = traditional compilers. >>=20 >> Warner >>=20 >>=20 >> _______________________________________________ >> freebsd-toolchain@freebsd.org mailing list >> http://lists.freebsd.org/mailman/listinfo/freebsd-toolchain >> To unsubscribe, send any mail to = "freebsd-toolchain-unsubscribe@freebsd.org" = =20 > _______________________________________________ > freebsd-toolchain@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-toolchain > To unsubscribe, send any mail to = "freebsd-toolchain-unsubscribe@freebsd.org"
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3DC02993-ADCF-4403-BA0F-61DBEDDB2116>