Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 28 Feb 2014 08:38:38 -0700
From:      Warner Losh <bsdimp@gmail.com>
To:        Dmitry Marakasov <amdmi3@amdmi3.ru>
Cc:        freebsd-toolchain@FreeBSD.org
Subject:   Re: More dangerous UB handling of clang (compared to gcc)
Message-ID:  <214F7253-A262-4ED1-8E38-672A5ECDFB6D@bsdimp.com>
In-Reply-To: <20140228150650.GE29171@hades.panopticon>
References:  <20140228150650.GE29171@hades.panopticon>

next in thread | previous in thread | raw e-mail | index | archive | help

On Feb 28, 2014, at 8:06 AM, Dmitry Marakasov <amdmi3@amdmi3.ru> wrote:

> 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.

Except this is a flat out bug=E2=80=A6.

> 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).

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

I=E2=80=99d be very interested to see chapter and verse on this one...

> 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).

I believe this resolution is, in fact, bogus. Sure, insert ud2, but also =
put a f=E2=80=99ing return in there.

I know in C11,this id definitely the case:

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.

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.

> 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.

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.

Warner





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?214F7253-A262-4ED1-8E38-672A5ECDFB6D>