Index: src/OFApplication.h ================================================================== --- src/OFApplication.h +++ src/OFApplication.h @@ -162,18 +162,18 @@ + (OFDictionary*)environment; /*! * @brief Terminates the application. */ -+ (void)terminate; ++ (void)terminate OF_NO_RETURN; /*! * @brief Terminates the application with the specified status. * * @param status The status with which the application will terminate */ -+ (void)terminateWithStatus: (int)status; ++ (void)terminateWithStatus: (int)status OF_NO_RETURN; /*! * @brief Gets args and argv. * * @param argc A pointer where a pointer to argc should be stored Index: src/OFDeflateStream.m ================================================================== --- src/OFDeflateStream.m +++ src/OFDeflateStream.m @@ -743,14 +743,13 @@ break; #undef CTX } - /* Get rid of a warning, never reached anyway */ - OF_ENSURE(0); + OF_UNREACHABLE } - (bool)lowlevelIsAtEndOfStream { return _atEndOfStream; } @end Index: src/OFMutableString_UTF8.m ================================================================== --- src/OFMutableString_UTF8.m +++ src/OFMutableString_UTF8.m @@ -265,12 +265,11 @@ resizeMemory: _s->cString size: _s->cStringLength + 1]; } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } - } else - assert(0); + } } - (void)appendUTF8String: (const char*)UTF8String { size_t UTF8StringLength = strlen(UTF8String); Index: src/OFObject.h ================================================================== --- src/OFObject.h +++ src/OFObject.h @@ -91,12 +91,14 @@ # endif #endif #if defined(__clang__) || __GCC_VERSION__ >= 406 # define OF_SENTINEL __attribute__((sentinel)) +# define OF_NO_RETURN __attribute__((noreturn)) #else # define OF_SENTINEL +# define OF_NO_RETURN #endif #if __has_attribute(objc_requires_super) # define OF_REQUIRES_SUPER __attribute__((objc_requires_super)) #else @@ -944,11 +946,11 @@ * @warning If you override this method, you must make sure that it never * returns. * * @param selector The selector not understood by the receiver */ -- (void)doesNotRecognizeSelector: (SEL)selector; +- (void)doesNotRecognizeSelector: (SEL)selector OF_NO_RETURN; @end /*! * @protocol OFCopying OFObject.h ObjFW/OFObject.h * Index: src/OFThread.h ================================================================== --- src/OFThread.h +++ src/OFThread.h @@ -143,18 +143,18 @@ #ifdef OF_HAVE_THREADS /*! * @brief Terminates the current thread, letting it return nil. */ -+ (void)terminate; ++ (void)terminate OF_NO_RETURN; /*! * @brief Terminates the current thread, letting it return the specified object. * * @param object The object which the terminated thread will return */ -+ (void)terminateWithObject: (id)object; ++ (void)terminateWithObject: (id)object OF_NO_RETURN; # ifdef OF_HAVE_BLOCKS /*! * @brief Initializes an already allocated thread with the specified block. * Index: src/OFThread.m ================================================================== --- src/OFThread.m +++ src/OFThread.m @@ -236,10 +236,17 @@ #ifdef OF_HAVE_THREADS + (void)terminate { [self terminateWithObject: nil]; + + /* + * For some reason, Clang thinks terminateWithObject: can return - even + * though it is declared noreturn - and warns that terminate returns + * while being declared noreturn. + */ + OF_UNREACHABLE } + (void)terminateWithObject: (id)object { OFThread *thread = of_tlskey_get(threadSelfKey); Index: src/macros.h ================================================================== --- src/macros.h +++ src/macros.h @@ -145,14 +145,20 @@ #define OF_IVAR_OFFSET(ivar) ((intptr_t)&ivar - (intptr_t)self) #define OF_GETTER(ivar, atomic) \ return objc_getProperty(self, _cmd, OF_IVAR_OFFSET(ivar), atomic); #define OF_SETTER(ivar, value, atomic, copy) \ objc_setProperty(self, _cmd, OF_IVAR_OFFSET(ivar), value, atomic, copy); + +#if defined(__clang__) || __GCC_VERSION__ >= 405 +# define OF_UNREACHABLE __builtin_unreachable(); +#else +# define OF_UNREACHABLE abort(); +#endif #define OF_UNRECOGNIZED_SELECTOR \ [self doesNotRecognizeSelector: _cmd]; \ - abort(); + OF_UNREACHABLE #define OF_INVALID_INIT_METHOD \ @try { \ [self doesNotRecognizeSelector: _cmd]; \ } @catch (id e) { \ [self release]; \ Index: src/threading.h ================================================================== --- src/threading.h +++ src/threading.h @@ -141,11 +141,11 @@ #else # error of_thread_detach not implemented! #endif } -static OF_INLINE void +static OF_INLINE void OF_NO_RETURN of_thread_exit(void) { #if defined(OF_HAVE_PTHREADS) pthread_exit(NULL); #elif defined(_WIN32)