More dangerous UB handling of clang (compared to gcc)

Warner Losh bsdimp at gmail.com
Fri Feb 28 15:38:43 UTC 2014


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

> Hi!
> 
> 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….

> Example:
> 
> --- ub.cc begins here ---
> #include <iostream>
> 
> int func1() {
> 	std::cerr << "func1()\n";
> 	/* no return */
> }
> 
> void func2() {
> 	std::cerr << "NEVER CALLED\n";
> }
> 
> int main() {
> 	func1();
> 	return 0;
> }
> --- ub.cc ends here ---
> 
> ---
> % 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
> ---
> 
> 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’s no return statement. The value returned from func1() is, of course, undefined, but this is well defined behavior in the standard…

I’d be very interested to see chapter and verse on this one...

> I wonder of we could make use of -Werror=return-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.
> 
> Related clang bug: http://llvm.org/bugs/show_bug.cgi?id=18296 (resoleved
> as INVALID).

I believe this resolution is, in fact, bogus. Sure, insert ud2, but also put a f’ing 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 undefined.

But the C++ standard is somewhat opaque on the topic, but none of the 56 instances of ‘undefined results’ 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’t do this, but this kind of undefined behavior is well outside the bounds of traditional compilers.

Warner




More information about the freebsd-toolchain mailing list