Bug 38630 - VS2010 asserts a null iterator passed to std::copy in Vector::operator=
Summary: VS2010 asserts a null iterator passed to std::copy in Vector::operator=
Status: CLOSED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Web Template Framework (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC Windows 7
: P2 Normal
Assignee: QtWebKit Unassigned
URL:
Keywords: Qt, QtTriaged
Depends on:
Blocks: 35784
  Show dependency treegraph
 
Reported: 2010-05-06 01:13 PDT by Jocelyn Turcotte
Modified: 2010-11-04 05:47 PDT (History)
6 users (show)

See Also:


Attachments
Patch (1.62 KB, patch)
2010-05-06 01:16 PDT, Jocelyn Turcotte
no flags Details | Formatted Diff | Diff
Kent's proposal patch (2.10 KB, patch)
2010-05-10 04:53 PDT, Jocelyn Turcotte
no flags Details | Formatted Diff | Diff
Kent's proposal patch v2 (2.11 KB, patch)
2010-05-10 05:32 PDT, Jocelyn Turcotte
ap: review-
ap: commit-queue-
Details | Formatted Diff | Diff
Patch v2 (1.73 KB, patch)
2010-05-11 02:50 PDT, Jocelyn Turcotte
ap: review+
ap: commit-queue-
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jocelyn Turcotte 2010-05-06 01:13:06 PDT
This happens when copying an empty Vector over another empty Vector.

Release builds works correctly.
Comment 1 Jocelyn Turcotte 2010-05-06 01:16:18 PDT
Created attachment 55211 [details]
Patch

Fixes the assert.
Comment 2 Alexey Proskuryakov 2010-05-07 13:58:40 PDT
It's not good for performance to add another branch. Perhaps this should only be done when building with VS2010? And a bug should probably be filed with Microsoft.
Comment 3 Kent Tamura 2010-05-08 10:25:48 PDT
AFAIK, passing 0 to an Iterator parameter is invalid in C++. So this behavior of VS2010 seems reasonable.
If we worry about the performance, we should use "#if COMPILER(MSVC)" here.
Comment 4 Kent Tamura 2010-05-08 10:43:00 PDT
I think we should add just

} else if (!other.size())
    return *this;

(No removing "if (!begin()) return *this;")

This is an optimization for all compilers and solve the VS2010 issue.
Comment 5 Alexey Proskuryakov 2010-05-08 10:57:00 PDT
I do not see any restrictions on input or output iterators in copy() algorithm
description in C++ standard. Do you have a reference for this requirement?

> This is an optimization for all compilers and solve the VS2010 issue.

That also sounds like an extra branch in common case. Or did I misunderstand your proposal?
Comment 6 Kent Tamura 2010-05-09 02:58:21 PDT
(In reply to comment #5)
> I do not see any restrictions on input or output iterators in copy() algorithm
> description in C++ standard. Do you have a reference for this requirement?

I checked the C++0x draft, and I think i was wrong.  0 can be a valid iterator in general.

The standard says neither "The OutputIterator parameter must be dereferenceable" nor "It may be not dereferenceable if [first, last) is empty."  So we can't assume the VS2010 behavior is a bug.

> > This is an optimization for all compilers and solve the VS2010 issue.
> 
> That also sounds like an extra branch in common case. Or did I misunderstand your proposal?

Yes, it will make an extra branch.  But it will skip the following 3-lines of the code in a case of empty vectors.
I have no strong preference on it.  I think either of it or "#if COMPILER(MSVC)" are ok.
Comment 7 Jocelyn Turcotte 2010-05-10 04:53:35 PDT
Created attachment 55543 [details]
Kent's proposal patch

Here is a patch for the proposed fix.

This adds a branch when other.size() is non-zero and fits in capacity(), but exit earlier in other cases.

I would also be ok with wrapping the previous patch in a MSVC/MSVC2010 specific macro piece if you think this one has issues.

Anyhow the msvc behavior, being a bug or not, has been reported there:
https://connect.microsoft.com/VisualStudio/feedback/details/558044/std-copy-should-not-check-dest-when-first-last
Comment 8 WebKit Review Bot 2010-05-10 05:02:02 PDT
Attachment 55543 [details] did not pass style-queue:

Failed to run "['WebKitTools/Scripts/check-webkit-style', '--no-squash']" exit_code: 1
JavaScriptCore/wtf/Vector.h:680:  An else if statement should be written as an if statement when the prior "if" concludes with a return, break, continue or goto statement.  [readability/control_flow] [4]
JavaScriptCore/wtf/Vector.h:705:  An else if statement should be written as an if statement when the prior "if" concludes with a return, break, continue or goto statement.  [readability/control_flow] [4]
Total errors found: 2 in 2 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 9 Jocelyn Turcotte 2010-05-10 05:32:10 PDT
Created attachment 55545 [details]
Kent's proposal patch v2

Fix style issues
Comment 10 Kent Tamura 2010-05-10 06:05:14 PDT
Comment on attachment 55545 [details]
Kent's proposal patch v2

> @@ -677,14 +677,17 @@ namespace WTF {
>          if (&other == this)
>              return *this;
>          
> -        if (size() > other.size())
> +        if (size() > other.size()) {
>              shrink(other.size());
> -        else if (other.size() > capacity()) {
> +            return *this;
> +        }

This branch just resizes 'this' and doesn't copy the content of 'other'.
Comment 11 Alexey Proskuryakov 2010-05-10 09:52:05 PDT
Comment on attachment 55545 [details]
Kent's proposal patch v2

> The standard says neither "The OutputIterator parameter must be dereferenceable"
> nor "It may be not dereferenceable if [first, last) is empty."  So we can't
> assume the VS2010 behavior is a bug.

The standard doesn't need to explicitly mention everything it allows. If there is no restriction, then it's allowed.

Please make this fix only for MSVC2010, file a bug with them, and reference this bug in a comment in code, so that we could know when to remove the workaround.

-        if (size() > other.size())
+        if (size() > other.size()) {
             shrink(other.size());
-        else if (other.size() > capacity()) {
+            return *this;
+        }

This doesn't look like it could possibly work. Did you run regression tests with this patch? Or am I just confused?
Comment 12 Alexey Proskuryakov 2010-05-10 09:53:01 PDT
> This branch just resizes 'this' and doesn't copy the content of 'other'.

Sorry, didn't see your comment before reviewing. So, I'm not just confused :-)
Comment 13 Jocelyn Turcotte 2010-05-11 02:50:45 PDT
Created attachment 55682 [details]
Patch v2

(In reply to comment #11)
> This doesn't look like it could possibly work. Did you run regression tests with this patch? Or am I just confused?

No, there was a lack of testing from my part on this patch, sorry about that.

Here is the first patch enclosed to apply only when the assert would pop.
Adding only "else if (!other.size()) return *this;" would not prevent the assert when size() > other.size() and the buffer gets shrunk to 0.

See Comment #7 for a link to the reported visual studio bug.
Comment 14 Alexey Proskuryakov 2010-05-11 08:44:50 PDT
Comment on attachment 55682 [details]
Patch v2

+// Workarounds an assert in VS2010. See https://bugs.webkit.org/show_bug.cgi?id=38630

There is no verb "workarounds", it's either a noun or "works around". I still think that it would be better to have a direct link to MS issue. The use case for this comment is: can I remove this code now? - click link - read. With a Bugzilla link, there is an extra step involved. On the other hand, the Bugzilla link may be more stable.

r=me, but please fix the grammar issue.
Comment 15 Jocelyn Turcotte 2010-05-14 04:28:48 PDT
Committed r59463: <http://trac.webkit.org/changeset/59463>

Changes since the review:
- Fixed the grammar issue
- The link in the code points to the VS issue instead
- Changed the preprocessor expression to also match when _ITERATOR_DEBUG_LEVEL == 1

thanks!
Comment 16 Simon Hausmann 2010-05-14 08:39:03 PDT
Revision r59463 cherry-picked into qtwebkit-2.0 with commit a1a9dda8011dbd6ffc40bad8b4e62d2d3bf95916
Comment 17 Jocelyn Turcotte 2010-11-04 05:42:22 PDT
Update:
The bug has been fixed in Visual Studio and the fix will be available in VS2011.

http://connect.microsoft.com/VisualStudio/feedback/details/558044/std-copy-should-not-check-dest-when-first-last
Comment 18 Jocelyn Turcotte 2010-11-04 05:47:47 PDT
(In reply to comment #17)
> The bug has been fixed in Visual Studio and the fix will be available in VS2011.
err.. I mean VC11