[llvm-dev] New Error object for CoverageMapping/createBinary

Vedant Kumar via llvm-dev llvm-dev at lists.llvm.org
Thu Sep 8 07:33:02 PDT 2016


Hi Gaël,

The copy constructor for the Error class has intentionally been marked as
deleted. My experience has been that this helps me write better error-handling
code, and ultimately makes debugging errors much easier. See Lang's excellent
write-up for more context:

    [RFC] Error handling in LLVM libraries
    http://lists.llvm.org/pipermail/llvm-dev/2016-February/095324.html

The "tl;dr" is that an Error is supposed to be unique, and has move-only
semantics.


> On Sep 8, 2016, at 3:05 AM, Gaël Jobin via llvm-dev <llvm-dev at lists.llvm.org> wrote:
> 
> Hi all,
> 
> I saw that some methods that was returning ErrorOr<> object are now returning Expected<> object embedding Error object instead of std::error_code. I have some troubles understanding how to use the new Error class...
> 
> Until now, I was using this kind of code :
> 
>> auto BinOrErr = llvm::object::createBinary(this->execPath);
>> 
>> if(auto EC = BinOrErr.getError())
>> {
>>    errs() << "Error : " << EC.message() << "\n";
>>    return false;
>> }

This should now read:

    auto BinOrErr = llvm::object::createBinary(this->execPath);
    if (auto E = BinOrErr.takeError()) {
      errs() << "Error : " << llvm::toString(std::move(E)) << "\n";
      ...
    }

> 
> And this one:
> 
>> auto CoverageOrErr = llvm::coverage::CoverageMapping::load(this->execPath, this->profPath, arch);
>> 
>> if (auto EC = CoverageOrErr.getError())
>> {
>>    errs() << "Error: Failed to load coverage: " << EC.message() << "\n";
>>    return false;
>> }
> 
> Since LLVM 3.9, load() and createBinary() return an Expected object. I managed to get the Error object using takeError() method (instead of the old getError()). But, since the Error object is not an std::error_code, I did not found a way to retrieve the message information... I tried to convert the Error object back to std::error_code using the function errorToErrorCode() like this:
> 
>> auto CoverageOrErr = llvm::coverage::CoverageMapping::load(this->execPath, this->profPath, arch);
>> 
>> if (Error Err = CoverageOrErr.takeError())
>> {
>>    errs() << "Error: Failed to load coverage: " << errorToErrorCode(Err).message() << "\n";
>>    return false;
>> }
> 
> But I cannot compile this code because of the copy constructor being marked as deleted.

You need to give up ownership of "Err" before passing it into errorToErrorCode,
e.g:

    Error Err = ...;
    std::error_code EC = errorToErrorCode(std::move(Err));
    // The error pointed-to by Err has now been consumed ("destroyed").

Since you just want the error message, you could just write:

    Error Err = ...;
    errs() << toString(std::move(Err))

best,
vedant

> 
>> error: use of deleted function ‘llvm::Error::Error(const llvm::Error&)’
>> /home/gagou/test/llvm/include/llvm/Support/Error.h:161:3: note: declared here
>>    Error(const Error &Other) = delete;
> 
> I don't know what I'm doing wrong, other files like SymbolizableObjectFile.cpp, ObjectFile.cpp IRObjectFile.cpp, etc seems to use the function errorToErrorCode() without any issue.
> 
> Does anyone know what is the best way to retrieve the message information from an Error object?
> 
> Thank you !
> 
> Regards,
> Gael
> 
> 
> 
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev



More information about the llvm-dev mailing list