Skip site navigation (1)Skip section navigation (2)
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>