Support: ensure proper state in ErrorOr copy ctors before calling 'get'
authorMeador Inge <meadori@codesourcery.com>
Tue, 5 Feb 2013 15:41:27 +0000 (15:41 +0000)
committerMeador Inge <meadori@codesourcery.com>
Tue, 5 Feb 2013 15:41:27 +0000 (15:41 +0000)
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

include/llvm/Support/ErrorOr.h

index 653b9e5c88f2d2bbcaec04d6a74ba5ff573b0424..c22c3ca84ff6ce683943f6762532b51fdf6d33dc 100644 (file)
@@ -204,18 +204,17 @@ public:
     // 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) {
@@ -234,11 +233,11 @@ public:
     // 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 {
@@ -248,8 +247,6 @@ public:
       // Tell other not to do any destruction.
       Other.IsValid = false;
     }
-
-    IsValid = true;
   }
 
   ErrorOr &operator =(ErrorOr &&Other) {