diff --git a/mkspecs/common/clang.conf b/mkspecs/common/clang.conf
index 6235296ef3312c999b8a8f35a6e760d2480fba21..2c29bb88fb1ba22324293d8dcfb1bc5c25a08084 100644
--- a/mkspecs/common/clang.conf
+++ b/mkspecs/common/clang.conf
@@ -7,6 +7,9 @@ QMAKE_COMPILER          = gcc clang llvm   # clang pretends to be gcc
 QMAKE_CC                = clang
 QMAKE_CXX               = clang++
 
+QMAKE_LINK_C            = $$QMAKE_CC
+QMAKE_LINK_C_SHLIB      = $$QMAKE_CC
+
 QMAKE_LINK              = $$QMAKE_CXX
 QMAKE_LINK_SHLIB        = $$QMAKE_CXX
 
diff --git a/mkspecs/unsupported/freebsd-clang/qmake.conf b/mkspecs/unsupported/freebsd-clang/qmake.conf
index ad4fa3487ed3b5c867a3572e0b8f47704e8e46a4..2cfd763688e5cf3b7322652844c45baac2205247 100644
--- a/mkspecs/unsupported/freebsd-clang/qmake.conf
+++ b/mkspecs/unsupported/freebsd-clang/qmake.conf
@@ -13,6 +13,7 @@ QMAKE_CXXFLAGS_THREAD   = $$QMAKE_CFLAGS_THREAD
 QMAKE_INCDIR            = /usr/local/include
 QMAKE_LIBDIR            = /usr/local/lib
 
+QMAKE_LFLAGS_NOUNDEF    = -Wl,--no-undefined
 QMAKE_LFLAGS_THREAD     = -pthread
 
 QMAKE_LIBS              =
@@ -28,6 +29,5 @@ QMAKE_RANLIB            =
 
 include(../../common/unix.conf)
 include(../../common/gcc-base-unix.conf)
-include(../../common/g++-unix.conf)
 include(../../common/clang.conf)
 load(qt_config)
diff --git a/src/corelib/doc/snippets/qstring/main.cpp b/src/corelib/doc/snippets/qstring/main.cpp
index bf45a31c294a02fda561ff28bb1a2928084c8272..f49c4dd35970b4254b6ffe7ecc52e2f298bd624c 100644
--- a/src/corelib/doc/snippets/qstring/main.cpp
+++ b/src/corelib/doc/snippets/qstring/main.cpp
@@ -760,14 +760,6 @@ void Widget::splitCaseSensitiveFunction()
 
 void Widget::sprintfFunction()
 {
-    //! [63]
-    size_t BufSize;
-    char buf[BufSize];
-
-    ::snprintf(buf, BufSize, "%lld", 123456789LL);
-    QString str = QString::fromUtf8(buf);
-    //! [63]
-
     //! [64]
     QString result;
     QTextStream(&result) << "pi = " << 3.14;
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 48f251e3f4292e7a6e207dbe0895f7a1f18f508b..71ca4239d058016895e2f820a27bb9437f52a1b9 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -5705,21 +5705,18 @@ QString QString::toUpper() const
     Safely builds a formatted string from the format string \a cformat
     and an arbitrary list of arguments.
 
-    The %lc escape sequence expects a unicode character of type ushort
-    (as returned by QChar::unicode()). The %ls escape sequence expects
-    a pointer to a zero-terminated array of unicode characters of type
-    ushort (as returned by QString::utf16()).
-
-    \note This function expects a UTF-8 string for %s and Latin-1 for
-    the format string.
-
-    The format string supports most of the conversion specifiers
-    provided by printf() in the standard C++ library. It doesn't
-    honor the length modifiers (e.g. \c h for \c short, \c ll for
-    \c{long long}). If you need those, use the standard snprintf()
-    function instead:
-
-    \snippet qstring/main.cpp 63
+    The format string supports the conversion specifiers, length modifiers,
+    and flags provided by printf() in the standard C++ library. The \a cformat
+    string and \c{%s} arguments must be UTF-8 encoded.
+
+    \note The \c{%lc} escape sequence expects a unicode character of type
+    \c char16_t, or \c ushort (as returned by QChar::unicode()).
+    The \c{%ls} escape sequence expects a pointer to a zero-terminated array
+    of unicode characters of type \c char16_t, or ushort (as returned by
+    QString::utf16()). This is at odds with the printf() in the standard C++
+    library, which defines \c {%lc} to print a wchar_t and \c{%ls} to print
+    a \c{wchar_t*}, and might also produce compiler warnings on platforms
+    where the size of \c {wchar_t} is not 16 bits.
 
     \warning We do not recommend using QString::sprintf() in new Qt
     code. Instead, consider using QTextStream or arg(), both of
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
index b1ec11dc71f6c25f5217dafe3dcb88843a0dc48d..00c3aced0e3108c102a73272355311cfe33e39b9 100644
--- a/src/dbus/qdbusconnection_p.h
+++ b/src/dbus/qdbusconnection_p.h
@@ -282,24 +282,18 @@ public:
     QStringList serverConnectionNames;
 
     ConnectionMode mode;
+    QDBusConnectionInterface *busService;
 
-    // members accessed in unlocked mode (except for deletion)
-    // connection and server provide their own locking mechanisms
-    // busService doesn't have state to be changed
+    // the dispatch lock protects everything related to the DBusConnection or DBusServer
+    // including the timeouts and watches
+    QMutex dispatchLock;
     DBusConnection *connection;
     DBusServer *server;
-    QDBusConnectionInterface *busService;
-
-    // watchers and timeouts are accessed from any thread
-    // but the corresponding timer and QSocketNotifier must be handled
-    // only in the object's thread
-    QMutex watchAndTimeoutLock;
     WatcherHash watchers;
     TimeoutHash timeouts;
     PendingTimeoutList timeoutsPendingAdd;
 
-    // members accessed through a lock
-    QMutex dispatchLock;
+    // the master lock protects our own internal state
     QReadWriteLock lock;
     QDBusError lastError;
 
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index 0dc8477ff4bfddb8f68b3840867685241a30848d..f27d45b1429291120acf2e77332d364c136d28c3 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -154,7 +154,7 @@ static dbus_bool_t qDBusAddTimeout(DBusTimeout *timeout, void *data)
     if (!q_dbus_timeout_get_enabled(timeout))
         return true;
 
-    QDBusWatchAndTimeoutLocker locker(AddTimeoutAction, d);
+    QDBusDispatchLocker locker(AddTimeoutAction, d);
     if (QCoreApplication::instance() && QThread::currentThread() == d->thread()) {
         // correct thread
         return qDBusRealAddTimeout(d, timeout, q_dbus_timeout_get_interval(timeout));
@@ -189,7 +189,7 @@ static void qDBusRemoveTimeout(DBusTimeout *timeout, void *data)
 
     QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data);
 
-    QDBusWatchAndTimeoutLocker locker(RemoveTimeoutAction, d);
+    QDBusDispatchLocker locker(RemoveTimeoutAction, d);
 
     // is it pending addition?
     QDBusConnectionPrivate::PendingTimeoutList::iterator pit = d->timeoutsPendingAdd.begin();
@@ -262,7 +262,7 @@ static bool qDBusRealAddWatch(QDBusConnectionPrivate *d, DBusWatch *watch, int f
 {
     QDBusConnectionPrivate::Watcher watcher;
 
-    QDBusWatchAndTimeoutLocker locker(AddWatchAction, d);
+    QDBusDispatchLocker locker(AddWatchAction, d);
     if (flags & DBUS_WATCH_READABLE) {
         //qDebug("addReadWatch %d", fd);
         watcher.watch = watch;
@@ -296,7 +296,7 @@ static void qDBusRemoveWatch(DBusWatch *watch, void *data)
     QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data);
     int fd = q_dbus_watch_get_unix_fd(watch);
 
-    QDBusWatchAndTimeoutLocker locker(RemoveWatchAction, d);
+    QDBusDispatchLocker locker(RemoveWatchAction, d);
     QDBusConnectionPrivate::WatcherHash::iterator i = d->watchers.find(fd);
     while (i != d->watchers.end() && i.key() == fd) {
         if (i.value().watch == watch) {
@@ -340,7 +340,7 @@ static void qDBusToggleWatch(DBusWatch *watch, void *data)
 
 static void qDBusRealToggleWatch(QDBusConnectionPrivate *d, DBusWatch *watch, int fd)
 {
-    QDBusWatchAndTimeoutLocker locker(ToggleWatchAction, d);
+    QDBusDispatchLocker locker(ToggleWatchAction, d);
 
     QDBusConnectionPrivate::WatcherHash::iterator i = d->watchers.find(fd);
     while (i != d->watchers.end() && i.key() == fd) {
@@ -1015,8 +1015,8 @@ void QDBusConnectionPrivate::deliverCall(QObject *object, int /*flags*/, const Q
 extern bool qDBusInitThreads();
 
 QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p)
-    : QObject(p), ref(1), capabilities(0), mode(InvalidMode), connection(0), server(0), busService(0),
-      watchAndTimeoutLock(QMutex::Recursive),
+    : QObject(p), ref(1), capabilities(0), mode(InvalidMode), busService(0),
+      dispatchLock(QMutex::Recursive), connection(0), server(0),
       rootNode(QString(QLatin1Char('/'))),
       anonymousAuthenticationAllowed(false)
 {
@@ -1126,7 +1126,7 @@ bool QDBusConnectionPrivate::handleError(const QDBusErrorInternal &error)
 void QDBusConnectionPrivate::timerEvent(QTimerEvent *e)
 {
     {
-        QDBusWatchAndTimeoutLocker locker(TimerEventAction, this);
+        QDBusDispatchLocker locker(TimerEventAction, this);
         DBusTimeout *timeout = timeouts.value(e->timerId(), 0);
         if (timeout)
             q_dbus_timeout_handle(timeout);
@@ -1145,7 +1145,7 @@ void QDBusConnectionPrivate::customEvent(QEvent *e)
     switch (ev->subtype)
     {
     case QDBusConnectionCallbackEvent::AddTimeout: {
-        QDBusWatchAndTimeoutLocker locker(RealAddTimeoutAction, this);
+        QDBusDispatchLocker locker(RealAddTimeoutAction, this);
         while (!timeoutsPendingAdd.isEmpty()) {
             QPair<DBusTimeout *, int> entry = timeoutsPendingAdd.takeFirst();
             qDBusRealAddTimeout(this, entry.first, entry.second);
@@ -1178,41 +1178,29 @@ void QDBusConnectionPrivate::doDispatch()
 
 void QDBusConnectionPrivate::socketRead(int fd)
 {
-    QVarLengthArray<DBusWatch *, 2> pendingWatches;
-
-    {
-        QDBusWatchAndTimeoutLocker locker(SocketReadAction, this);
-        WatcherHash::ConstIterator it = watchers.constFind(fd);
-        while (it != watchers.constEnd() && it.key() == fd) {
-            if (it->watch && it->read && it->read->isEnabled())
-                pendingWatches.append(it.value().watch);
-            ++it;
+    QDBusDispatchLocker locker(SocketReadAction, this);
+    WatcherHash::ConstIterator it = watchers.constFind(fd);
+    while (it != watchers.constEnd() && it.key() == fd) {
+        if (it->watch && it->read && it->read->isEnabled()) {
+            if (!q_dbus_watch_handle(it.value().watch, DBUS_WATCH_READABLE))
+                qDebug("OUT OF MEM");
         }
+        ++it;
     }
-
-    for (int i = 0; i < pendingWatches.size(); ++i)
-        if (!q_dbus_watch_handle(pendingWatches[i], DBUS_WATCH_READABLE))
-            qDebug("OUT OF MEM");
     doDispatch();
 }
 
 void QDBusConnectionPrivate::socketWrite(int fd)
 {
-    QVarLengthArray<DBusWatch *, 2> pendingWatches;
-
-    {
-        QDBusWatchAndTimeoutLocker locker(SocketWriteAction, this);
-        WatcherHash::ConstIterator it = watchers.constFind(fd);
-        while (it != watchers.constEnd() && it.key() == fd) {
-            if (it->watch && it->write && it->write->isEnabled())
-                pendingWatches.append(it.value().watch);
-            ++it;
+    QDBusDispatchLocker locker(SocketWriteAction, this);
+    WatcherHash::ConstIterator it = watchers.constFind(fd);
+    while (it != watchers.constEnd() && it.key() == fd) {
+        if (it->watch && it->write && it->write->isEnabled()) {
+            if (!q_dbus_watch_handle(it.value().watch, DBUS_WATCH_WRITABLE))
+                qDebug("OUT OF MEM");
         }
+        ++it;
     }
-
-    for (int i = 0; i < pendingWatches.size(); ++i)
-        if (!q_dbus_watch_handle(pendingWatches[i], DBUS_WATCH_WRITABLE))
-            qDebug("OUT OF MEM");
 }
 
 void QDBusConnectionPrivate::objectDestroyed(QObject *obj)
@@ -1265,7 +1253,10 @@ void QDBusConnectionPrivate::relaySignal(QObject *obj, const QMetaObject *mo, in
     //qDBusDebug() << "Emitting signal" << message;
     //qDBusDebug() << "for paths:";
     q_dbus_message_set_no_reply(msg, true); // the reply would not be delivered to anything
-    huntAndEmit(connection, msg, obj, rootNode, isScriptable, isAdaptor);
+    {
+        QDBusDispatchLocker locker(HuntAndEmitAction, this);
+        huntAndEmit(connection, msg, obj, rootNode, isScriptable, isAdaptor);
+    }
     q_dbus_message_unref(msg);
 }
 
@@ -1922,7 +1913,11 @@ int QDBusConnectionPrivate::send(const QDBusMessage& message)
 
     qDBusDebug() << this << "sending message (no reply):" << message;
     checkThread();
-    bool isOk = q_dbus_connection_send(connection, msg, 0);
+    bool isOk;
+    {
+        QDBusDispatchLocker locker(SendMessageAction, this);
+        isOk = q_dbus_connection_send(connection, msg, 0);
+    }
     int serial = 0;
     if (isOk)
         serial = q_dbus_message_get_serial(msg);
@@ -2040,7 +2035,11 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message,
 
         qDBusDebug() << this << "sending message (blocking):" << message;
         QDBusErrorInternal error;
-        DBusMessage *reply = q_dbus_connection_send_with_reply_and_block(connection, msg, timeout, error);
+        DBusMessage *reply;
+        {
+            QDBusDispatchLocker locker(SendWithReplyAndBlockAction, this);
+            reply = q_dbus_connection_send_with_reply_and_block(connection, msg, timeout, error);
+        }
 
         q_dbus_message_unref(msg);
 
diff --git a/src/dbus/qdbusthreaddebug_p.h b/src/dbus/qdbusthreaddebug_p.h
index 78db18f5c766bf35a3267f6b3e853bf4eb4645dd..804106813400aa3a758dc6c971876add39a305e7 100644
--- a/src/dbus/qdbusthreaddebug_p.h
+++ b/src/dbus/qdbusthreaddebug_p.h
@@ -86,6 +86,9 @@ enum ThreadAction {
     MessageResultReceivedAction = 26,
     ActivateSignalAction = 27,
     PendingCallBlockAction = 28,
+    SendMessageAction = 29,
+    SendWithReplyAndBlockAction = 30,
+    HuntAndEmitAction = 31,
 
     AddTimeoutAction = 50,
     RealAddTimeoutAction = 51,
@@ -196,13 +199,6 @@ struct QDBusDispatchLocker: QDBusMutexLocker
     { }
 };
 
-struct QDBusWatchAndTimeoutLocker: QDBusMutexLocker
-{
-    inline QDBusWatchAndTimeoutLocker(ThreadAction a, QDBusConnectionPrivate *s)
-        : QDBusMutexLocker(a, s, &s->watchAndTimeoutLock)
-    { }
-};
-
 #if QDBUS_THREAD_DEBUG
 # define SEM_ACQUIRE(action, sem)                                       \
     do {                                                                \
diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp
old mode 100755
new mode 100644