[llvm] r264467 - [Support] Add Error::errorForOutParameter helper.
David Blaikie via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 25 15:36:01 PDT 2016
On Fri, Mar 25, 2016 at 3:30 PM, Lang Hames <lhames at gmail.com> wrote:
> Actually, maybe RAII is the way to go here:
>
> Instead of:
>
> Foo::Foo(Error &Err) {
> // ...
> if (Cond)
> Err = ...
> // ...
> }
>
> Expected<Foo> Foo::create() {
> Error Err = Error::errorForOutParameter();
> Foo F(Err);
> if (Err)
> return std::move(Err);
> return std::move(F);
> }
>
> We could have:
>
> Foo::Foo(Error &Err) {
> ErrorForOutParam _(Err); // '_' clears checked flag at entry, unclears
> it at exit.
> // ...
> if (Cond)
> Err = ...
> // ...
> }
>
> Expected<Foo> Foo::create() {
> Error Err;
> Foo F(Err);
> if (Err)
> return std::move(Err);
> return std::move(F);
> }
>
> What do you think?
>
Yeah, seems legit - & quick/easy enough to write (not a lot of engineering
for a corner case), etc.
>
> - Lang.
>
>
> On Fri, Mar 25, 2016 at 3:14 PM, David Blaikie <dblaikie at gmail.com> wrote:
>
>>
>>
>> On Fri, Mar 25, 2016 at 3:11 PM, Lang Hames <lhames at gmail.com> wrote:
>>
>>> Hi Dave,
>>>
>>> The constructor should assign to Error no matter what (I may have failed
>>> to assign success in the MachOObjectFile constructor - I'll check), and
>>> consequently the caller will have to check no matter what. The issue is
>>> with the assignment operator. It's an error to overwrite an unchecked
>>> value, so the following will fail:
>>>
>>> Error Err = Error::success();
>>> Err = Error::success(); // <- Failure to check the first success value.
>>>
>>> Using
>>>
>>> Error = Err::errorForOutParameter();
>>> Error = Error::success();
>>>
>>> Instead is safe.
>>>
>>
>> Right... hmm, tricky. :/ yeah, not sure of the best way to account for
>> all of that & make it least error prone in these use cases.
>>
>>
>>>
>>> - Lang.
>>>
>>> On Fri, Mar 25, 2016 at 3:05 PM, David Blaikie <dblaikie at gmail.com>
>>> wrote:
>>>
>>>>
>>>>
>>>> On Fri, Mar 25, 2016 at 2:56 PM, Lang Hames via llvm-commits <
>>>> llvm-commits at lists.llvm.org> wrote:
>>>>
>>>>> Author: lhames
>>>>> Date: Fri Mar 25 16:56:35 2016
>>>>> New Revision: 264467
>>>>>
>>>>> URL: http://llvm.org/viewvc/llvm-project?rev=264467&view=rev
>>>>> Log:
>>>>> [Support] Add Error::errorForOutParameter helper.
>>>>>
>>>>> This helper method creates a pre-checked Error suitable for use as an
>>>>> out
>>>>> parameter in a constructor. This avoids the need to have the
>>>>> constructor
>>>>> check a known-good error before assigning to it.
>>>>>
>>>>
>>>> Hmm, thinking about it - how does this work to ensure safety?
>>>>
>>>> If the callee only assigns to the parameter on failure cases, won't the
>>>> code fail to assert on successful cases?
>>>>
>>>> (ie: shouldn't it actually be unchecked by default as it was before -
>>>> the caller should check it on return regardless of what the function did)
>>>>
>>>>
>>>>>
>>>>>
>>>>> Modified:
>>>>> llvm/trunk/include/llvm/Support/Error.h
>>>>> llvm/trunk/unittests/Support/ErrorTest.cpp
>>>>>
>>>>> Modified: llvm/trunk/include/llvm/Support/Error.h
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Error.h?rev=264467&r1=264466&r2=264467&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- llvm/trunk/include/llvm/Support/Error.h (original)
>>>>> +++ llvm/trunk/include/llvm/Support/Error.h Fri Mar 25 16:56:35 2016
>>>>> @@ -143,6 +143,13 @@ public:
>>>>> /// constructor, but should be preferred for readability where
>>>>> possible.
>>>>> static Error success() { return Error(); }
>>>>>
>>>>> + /// Create a 'pre-checked' success value suitable for use as an
>>>>> out-parameter.
>>>>> + static Error errorForOutParameter() {
>>>>> + Error Err;
>>>>> + (void)!!Err;
>>>>> + return Err;
>>>>> + }
>>>>> +
>>>>> // Errors are not copy-constructable.
>>>>> Error(const Error &Other) = delete;
>>>>>
>>>>>
>>>>> Modified: llvm/trunk/unittests/Support/ErrorTest.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/ErrorTest.cpp?rev=264467&r1=264466&r2=264467&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- llvm/trunk/unittests/Support/ErrorTest.cpp (original)
>>>>> +++ llvm/trunk/unittests/Support/ErrorTest.cpp Fri Mar 25 16:56:35 2016
>>>>> @@ -105,6 +105,12 @@ TEST(Error, UncheckedSuccess) {
>>>>> }
>>>>> #endif
>>>>>
>>>>> +// Test that errors to be used as out parameters are implicitly
>>>>> checked (
>>>>> +// and thus destruct quietly).
>>>>> +TEST(Error, ErrorAsOutParameter) {
>>>>> + Error E = Error::errorForOutParameter();
>>>>> +}
>>>>> +
>>>>> // Check that we abort on unhandled failure cases. (Force conversion
>>>>> to bool
>>>>> // to make sure that we don't accidentally treat checked errors as
>>>>> handled).
>>>>> // Test runs in debug mode only.
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> llvm-commits mailing list
>>>>> llvm-commits at lists.llvm.org
>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>>>>
>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160325/685c4729/attachment.html>
More information about the llvm-commits
mailing list