Make sure functions returning iterators have an iterator as parameter
authorThiago Macieira <thiago.macieira@intel.com>
Fri, 28 Sep 2012 12:02:29 +0000 (14:02 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Fri, 19 Oct 2012 03:35:39 +0000 (05:35 +0200)
The IA-64 C++ ABI does not encode the return type for non-template
functions (QVector is the template, not the function), which means that
these two functions have the same signature:

  Node *QVector<Node>::begin()
  typename class QTypedArrayData<Node>::iterator QVector<Node>::begin()
  [both are _ZN7QVectorI4NodeE5beginEv]

When linking compilation units compiled with different
QT_STRICT_ITERATORS settings, only one of the two out-of-line copies
will survive. Depending on the ABI, we may have a problem: the ABI can
say that a function returning a structure takes an implicit first
parameter, which a function returning a regular pointer doesn't.

Task-number: QTBUG-27277
Change-Id: I57a59e5a7c46f55faabfe85c073dca89d2a7bbf3
Reviewed-by: Jan Kundrát <jkt@flaska.net>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
src/corelib/tools/qarraydata.h
src/corelib/tools/qvector.h

index a67255a..7fecbbb 100644 (file)
@@ -209,12 +209,12 @@ struct QTypedArrayData
     T *data() { return static_cast<T *>(QArrayData::data()); }
     const T *data() const { return static_cast<const T *>(QArrayData::data()); }
 
-    iterator begin() { return data(); }
-    iterator end() { return data() + size; }
-    const_iterator begin() const { return data(); }
-    const_iterator end() const { return data() + size; }
-    const_iterator constBegin() const { return data(); }
-    const_iterator constEnd() const { return data() + size; }
+    iterator begin(iterator = iterator()) { return data(); }
+    iterator end(iterator = iterator()) { return data() + size; }
+    const_iterator begin(const_iterator = const_iterator()) const { return data(); }
+    const_iterator end(const_iterator = const_iterator()) const { return data() + size; }
+    const_iterator constBegin(const_iterator = const_iterator()) const { return data(); }
+    const_iterator constEnd(const_iterator = const_iterator()) const { return data() + size; }
 
     class AlignmentDummy { QArrayData header; T data; };
 
index c0ae048..925ad17 100644 (file)
@@ -151,6 +151,7 @@ public:
     // STL-style
     typedef typename Data::iterator iterator;
     typedef typename Data::const_iterator const_iterator;
+#if !defined(QT_STRICT_ITERATORS) || defined(Q_QDOC)
     inline iterator begin() { detach(); return d->begin(); }
     inline const_iterator begin() const { return d->constBegin(); }
     inline const_iterator cbegin() const { return d->constBegin(); }
@@ -159,6 +160,16 @@ public:
     inline const_iterator end() const { return d->constEnd(); }
     inline const_iterator cend() const { return d->constEnd(); }
     inline const_iterator constEnd() const { return d->constEnd(); }
+#else
+    inline iterator begin(iterator = iterator()) { detach(); return d->begin(); }
+    inline const_iterator begin(const_iterator = const_iterator()) const { return d->constBegin(); }
+    inline const_iterator cbegin(const_iterator = const_iterator()) const { return d->constBegin(); }
+    inline const_iterator constBegin(const_iterator = const_iterator()) const { return d->constBegin(); }
+    inline iterator end(iterator = iterator()) { detach(); return d->end(); }
+    inline const_iterator end(const_iterator = const_iterator()) const { return d->constEnd(); }
+    inline const_iterator cend(const_iterator = const_iterator()) const { return d->constEnd(); }
+    inline const_iterator constEnd(const_iterator = const_iterator()) const { return d->constEnd(); }
+#endif
     iterator insert(iterator before, int n, const T &x);
     inline iterator insert(iterator before, const T &x) { return insert(before, 1, x); }
     iterator erase(iterator begin, iterator end);