You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In C++14 builds, butil::optional<T> uses a custom implementation whose defaulted copy and move operations copy raw storage. For non-trivial types such as std::string, this can cause a double-free.
What is changed and the side effects?
Changed:
Construct, assign, and destroy the contained value correctly during copy and move operations.
Make move operations conditionally noexcept based on T.
Add lifetime regression tests and an explicit C++14 ASan/UBSan CI check.
Side effects:
Performance effects: Copy and move operations now invoke the contained type's operations instead of copying raw storage.
Breaking backward compatibility: No intended API break. Copy/move type traits for unsupported operations remain outside the scope of this change.
Check List:
Please make sure your changes are compilable.
When providing us with a new feature, it is best to add related tests.
The reason will be displayed to describe this comment to others. Learn more.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Fixes incorrect lifetime handling in the C++14 butil::optional<T> implementation that could double-free non-trivial types, and adds regression coverage plus CI sanitizer coverage to catch similar issues.
Changes:
Implement explicit copy/move construction and assignment for engaged optionals (no raw storage copying).
Add lifetime/assignment-state regression tests including move-only values.
Add a dedicated C++14 ASan/UBSan CI compilation/run for optional_unittest.
File
Description
test/optional_unittest.cpp
Adds non-trivial lifetime, assignment-state, and move-only regression tests; enforces C++14 impl when targeted.
src/butil/containers/optional.h
Replaces defaulted copy/move ops with correct value construction/assignment; adds conditional noexcept for moves.
.github/workflows/ci-linux.yml
Adds a dedicated C++14 sanitizer run of the optional unit test.
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
Active moderate and critical findings remain: the converting move path incorrectly resets the source, and the added test contains an assertion that cannot compile.
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
The change leaves optional::swap and free swap unconditionally noexcept even though the new move paths can throw, causing std::terminate for throwing move operations instead of propagating exceptions.
No open issues 🎉
1 previously missed issue
In code that hasn't changed since last review
Make swap noexcept conditional on contained type operations
src/butil/containers/optional.h:379
The new move operations now invoke T's move constructor/assignment, but optional::swap (and the free swap) are still unconditionally noexcept. In the empty/non-empty branches, swap routes through this move assignment/value assignment, so a T whose move operation throws now causes std::terminate instead of propagating the exception; the engaged/engaged branch can throw via std::swap as well. Make the swap declarations' exception specification reflect the contained type's swappability/move construction, and update the implementation accordingly.
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What problem does this PR solve?
Issue Number: resolve
Problem Summary:
In C++14 builds,
butil::optional<T>uses a custom implementation whose defaulted copy and move operations copy raw storage. For non-trivial types such asstd::string, this can cause a double-free.What is changed and the side effects?
Changed:
noexceptbased onT.Side effects:
Performance effects: Copy and move operations now invoke the contained type's operations instead of copying raw storage.
Breaking backward compatibility: No intended API break. Copy/move type traits for unsupported operations remain outside the scope of this change.
Check List: