Skip to content

Commit

Permalink
Support: ensure proper state in ErrorOr copy ctors before calling 'get'
Browse files Browse the repository at this point in the history
Some paths through the copy constructors for 'ErrorOr' were calling
'get' when 'HasError' and 'IsValid' were not properly initialized.
Depending on what happened to be in memory for those member variables
the asserts in 'get' might incorrectly fire.  Fixed by ensuring that
the member variables in question are always initialized before calling
'get'.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174381 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
meadori committed Feb 5, 2013
1 parent f5b39cd commit 2ebc580
Showing 1 changed file with 4 additions and 7 deletions.
11 changes: 4 additions & 7 deletions include/llvm/Support/ErrorOr.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,18 +204,17 @@ class ErrorOr {
// Construct an invalid ErrorOr if other is invalid.
if (!Other.IsValid)
return;
IsValid = true;
if (!Other.HasError) {
// Get the other value.
new (get()) storage_type(*Other.get());
HasError = false;
new (get()) storage_type(*Other.get());
} else {
// Get other's error.
Error = Other.Error;
HasError = true;
Error->aquire();
}

IsValid = true;
}

ErrorOr &operator =(const ErrorOr &Other) {
Expand All @@ -234,11 +233,11 @@ class ErrorOr {
// Construct an invalid ErrorOr if other is invalid.
if (!Other.IsValid)
return;
IsValid = true;
if (!Other.HasError) {
// Get the other value.
IsValid = true;
new (get()) storage_type(std::move(*Other.get()));
HasError = false;
new (get()) storage_type(std::move(*Other.get()));
// Tell other not to do any destruction.
Other.IsValid = false;
} else {
Expand All @@ -248,8 +247,6 @@ class ErrorOr {
// Tell other not to do any destruction.
Other.IsValid = false;
}

IsValid = true;
}

ErrorOr &operator =(ErrorOr &&Other) {
Expand Down

0 comments on commit 2ebc580

Please sign in to comment.