Commit Graph

46 Commits

Author SHA1 Message Date
Don Hinton
f2feacfbe5 [Error] Make llvm::cantFail include the original error messages
Summary:
The current implementation eats the current errors and just outputs
the message parameter passed to llvm::cantFail.  This change appends
the original error message(s), so the user can see exactly why
cantFail failed.  New logic is conditional on NDEBUG.

Reviewed By: lhames

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D69057

llvm-svn: 375176
2019-10-17 21:54:15 +00:00
Pavel Labath
623bce661a Revert "raw_ostream: add operator<< overload for std::error_code"
This reverts commit r368849, because it breaks some bots (e.g.
llvm-clang-x86_64-win-fast).

It turns out this is not as NFC as we had hoped, because operator== will
consider two std::error_codes to be distinct even though they both hold
"success" values if they have different categories.

llvm-svn: 368854
2019-08-14 13:59:04 +00:00
Pavel Labath
2c377876d9 raw_ostream: add operator<< overload for std::error_code
Summary:
The main motivation for this is unit tests, which contain a large macro
for pretty-printing std::error_code, and this macro is duplicated in
every file that needs to do this. However, the functionality may be
useful elsewhere too.

In this patch I have reimplemented the existing ASSERT_NO_ERROR macros
to reuse the new functionality, but I have kept the macro (as a
one-liner) as it is slightly more readable than ASSERT_EQ(...,
std::error_code()).

Reviewers: sammccall, ilya-biryukov

Subscribers: zturner, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D65643

llvm-svn: 368849
2019-08-14 13:33:28 +00:00
Chandler Carruth
ae65e281f3 Update the file headers across all of the LLVM projects in the monorepo
to reflect the new license.

We understand that people may be surprised that we're moving the header
entirely to discuss the new license. We checked this carefully with the
Foundation's lawyer and we believe this is the correct approach.

Essentially, all code in the project is now made available by the LLVM
project under our new license, so you will see that the license headers
include that license only. Some of our contributors have contributed
code under our old license, and accordingly, we have retained a copy of
our old license notice in the top-level files in each project and
repository.

llvm-svn: 351636
2019-01-19 08:50:56 +00:00
Jonas Devlieghere
681a56eed2 [Support] Make error banner optional in logAllUnhandledErrors
In a lot of places an empty string was passed as the ErrorBanner to
logAllUnhandledErrors. This patch makes that argument optional to
simplify the call sites.

llvm-svn: 346604
2018-11-11 01:46:03 +00:00
Alexandre Ganea
01b65a3d2b [Error] Reintroduce type validation in createFileError()
This prevents from using ErrorSuccess as an argument to createFileError().

Differential Revision: https://reviews.llvm.org/D51490

llvm-svn: 341689
2018-09-07 18:32:59 +00:00
Alexandre Ganea
370eeaa8fa More build fix for r341064.
llvm-svn: 341070
2018-08-30 14:05:49 +00:00
Alexandre Ganea
7644b9b0eb [Error] Add FileError helper; upgrade StringError behavior
FileError is meant to encapsulate both an Error and a file name/path. It should be used in cases where an Error occurs deep down the call chain, and we want to return it to the caller along with the file name.

StringError was updated to display the error messages in different ways. These can be:

1. display the error_code message, and convert to the same error_code (ECError behavior)
2. display an arbitrary string, and convert to a provided error_code (current StringError behavior)
3. display both an error_code message and a string, in this order; and convert to the same error_code

These behaviors can be triggered depending on the constructor. The goal is to use StringError as a base class, when a library needs to provide a explicit Error type.

Differential Revision: https://reviews.llvm.org/D50807

llvm-svn: 341064
2018-08-30 13:10:42 +00:00
Lang Hames
3302570b39 [Support] Add a basic C API for llvm::Error.
Summary:
The C-API supports consuming errors, converting an error to a string error
message, and querying an error's type. Other LLVM C APIs that wish to use
llvm::Error can supply error-type-id checkers and custom
error-to-structured-type converters for any custom errors they provide.

Reviewers: bogner, zturner, labath, dblaikie

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D50716

llvm-svn: 339802
2018-08-15 18:42:11 +00:00
Victor Leschuk
c6c6491aff [Support] Introduce createStringError helper function
The function in question is copy-pasted lots of times in DWARF-related classes.
Thus it will make sense to place its implementation into the Support library.

Reviewed by: lhames

Differential Revision: https://reviews.llvm.org/D49824

llvm-svn: 337995
2018-07-26 02:21:40 +00:00
Sam McCall
7525249e1e [Support] Make support types more easily printable.
Summary:
Error's new operator<< is the first way to print an error without consuming it.

formatv() can now print objects with an operator<< that works with raw_ostream.

Reviewers: bkramer

Subscribers: mgorny, llvm-commits

Differential Revision: https://reviews.llvm.org/D48966

llvm-svn: 336412
2018-07-06 05:45:45 +00:00
Pavel Labath
1eb8f92f83 [Testing/Support] Make Failed() matcher work with abstract error types
Failed<ErrorInfoBase>() did not compile, because it was attempting to
create a copy of the Error object when passing it to the nested matcher,
which was not possible because ErrorInfoBase is abstract.

This commit fixes the problem by making sure we pass the ErrorInfo
object by reference, which also improves the handling of non-abstract
objects, as we avoid potentially slicing an object during the copy.

llvm-svn: 329703
2018-04-10 14:11:53 +00:00
Pavel Labath
fa2992679a [Testing/Support]: Better matching of Error failure states
Summary:
The existing Failed() matcher only allowed asserting that the operation
failed, but it was not possible to verify any details of the returned
error.

This patch adds two new matchers, which make this possible:
- Failed<InfoT>() verifies that the operation failed with a single error
  of a given type.
- Failed<InfoT>(M) additionally check that the contained error info
  object is matched by the nested matcher M.

To make these work, I've changed the implementation of the ErrorHolder
class. Now, instead of just storing the string representation of the
Error, it fetches the ErrorInfo objects and stores then as a list of
shared pointers. This way, ErrorHolder remains copyable, while still
retaining the full information contained in the Error object.

In case the Error object contains two or more errors, the new matchers
will fail to match, instead of trying to match all (or any) of the
individual ErrorInfo objects. This seemed to be the most sensible
behavior for when one wants to match exact error details, but I could be
convinced otherwise...

Reviewers: zturner, lhames

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D44925

llvm-svn: 329288
2018-04-05 14:32:10 +00:00
Pavel Labath
9fcf6e8c4e [Testing/Support] Make the HasValue matcher composable
Summary:
This makes it possible to run an arbitrary matcher on the value
contained within the Expected<T> object.

To do this, I've needed to fully spell out the matcher, instead of using
the shorthand MATCHER_P macro.

The slight gotcha here is that standard template deduction will fail if
one tries to match HasValue(47) against an Expected<int &> -- the
workaround is to use HasValue(testing::Eq(47)).

The explanations produced by this matcher have changed a bit, since now
we delegate to the nested matcher to print the value. Since these don't
put quotes around the value, I've changed our PrintTo methods to match.

Reviewers: zturner

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D41065

llvm-svn: 320561
2017-12-13 10:00:38 +00:00
Pavel Labath
2fdb544e39 [Testing/Support] Make matchers work with Expected<T&>
Summary:
This did not work because the ExpectedHolder was trying to hold the
value in an Optional<T*>. Instead of trying to mimic the behavior of
Expected and try to make ExpectedHolder work with references and
non-references, I simply store the reference to the Expected object in
the holder.

I also add a bunch of tests for these matchers, which have helped me
flesh out some problems in my initial implementation of this patch, and
uncovered the fact that we are not consistent in quoting our values in
the matcher output (which I also fix).

Reviewers: zturner, chandlerc

Subscribers: mgorny, llvm-commits

Differential Revision: https://reviews.llvm.org/D40904

llvm-svn: 320025
2017-12-07 10:54:23 +00:00
Lang Hames
72b8cc251f [Error] Add an optional error message to cantFail.
cantFail is the moral equivalent of an assertion that the wrapped call must
return a success value. This patch allows clients to include an associated
error message (the same way they would for an assertion for llvm_unreachable).

If the error message is not specified it will default to: "Failure value
returned from cantFail wrapped call".

llvm-svn: 312066
2017-08-29 23:29:09 +00:00
Lang Hames
ed191215a4 [Error] Add a handleExpected utility.
handleExpected is similar to handleErrors, but takes an Expected<T> as its first
input value and a fallback functor as its second, followed by an arbitary list
of error handlers (equivalent to the handler list of handleErrors). If the first
input value is a success value then it is returned from handleErrors
unmodified. Otherwise the contained error(s) are passed to handleErrors, along
with the handlers. If handleErrors returns success (indicating that all errors
have been handled) then handleExpected runs the fallback functor and returns its
result. If handleErrors returns a failure value then the failure value is
returned and the fallback functor is never run.

This simplifies the process of re-trying operations that return Expected values.
Without this utility such retry logic is cumbersome as the internal Error must
be explicitly extracted from the Expected value, inspected to see if its
handleable and then consumed:

enum FooStrategy { Aggressive, Conservative };
Expected<Foo> tryFoo(FooStrategy S);

Expected<Foo> Result;
(void)!!Result; // "Check" Result so that it can be safely overwritten.
if (auto ValOrErr = tryFoo(Aggressive))
  Result = std::move(ValOrErr);
else {
  auto Err = ValOrErr.takeError();
  if (Err.isA<HandleableError>()) {
    consumeError(std::move(Err));
    Result = tryFoo(Conservative);
  } else
    return std::move(Err);
}

with handleExpected, this can be re-written as:

auto Result =
  handleExpected(
    tryFoo(Aggressive),
    []() { return tryFoo(Conservative); },
    [](HandleableError&) { /* discard to handle */ });

llvm-svn: 311870
2017-08-28 03:36:46 +00:00
Stephen Hines
7bc4971ffd Fix two (three) more issues with unchecked Error.
Summary:
If assertions are disabled, but LLVM_ABI_BREAKING_CHANGES is enabled,
this will cause an issue with an unchecked Success. Switching to
consumeError() is the correct way to bypass the check. This patch also
includes disabling 2 tests that can't work without assertions enabled,
since llvm_unreachable() with NDEBUG won't crash.

Reviewers: llvm-commits, lhames

Reviewed By: lhames

Subscribers: lhames, pirama

Differential Revision: https://reviews.llvm.org/D36729

llvm-svn: 311739
2017-08-25 00:48:21 +00:00
Lang Hames
3fcb68baa6 [Support] Rewrite handleAllErrors in terms of cantFail.
This just switches handleAllErrors from using custom assertions that all errors
have been handled to using cantFail. This change involves moving some of the
class and function definitions around though.

llvm-svn: 311631
2017-08-24 05:35:27 +00:00
Hiroshi Inoue
6818cb9b48 fix typos in comments; NFC
llvm-svn: 307626
2017-07-11 06:04:59 +00:00
Lang Hames
0b0a2db0f4 Add a cantFail overload for Expected-reference (Expected<T&>) types.
llvm-svn: 305863
2017-06-20 22:18:02 +00:00
Lang Hames
99fe4e4838 [Support][Error] Add a 'cantFail' utility function for known-safe calls to
fallible functions.

Some fallible functions (those returning Error or Expected<T>) may only fail
for a subset of their inputs. For example, a "safe" square root function will
succeed for all finite positive inputs:

  Expected<double> safeSqrt(double d) {
    if (d < 0 && !isnan(d) && !isinf(d))
      return make_error<...>("Cannot sqrt -ve values, nans or infs");
    return sqrt(d);
  }

At a safe callsite for such a function, checking the error return value is
redundant:

  if (auto ValOrErr = safeSqrt(42.0)) {
    // use *ValOrErr.
  } else
    llvm_unreachable("safeSqrt should always succeed for +ve values");

The cantFail function wraps this check and extracts the contained value,
simplifying control flow:

  double Result = cantFail(safeSqrt(42.0));

This function should be used with care: it is a programmatic error to wrap a
call with cantFail if it can in fact fail. For debug builds this will
result in llvm_unreachable being called. For release builds the behavior is
undefined.

Use of this function is likely to be rare in library code, but more common
for tool and unit-test code where inputs and mock functions may be known to be
safe.

llvm-svn: 296384
2017-02-27 21:09:47 +00:00
Mehdi Amini
795ba2efa7 Fix macro check for ABI breacking check: should use #if instead of #ifndef
llvm-svn: 288265
2016-11-30 19:08:41 +00:00
Mehdi Amini
0242771a6d Change Error unittest to use the LLVM_ENABLE_ABI_BREAKING_CHECKS instead of NDEBUG
This is consistent with the header (after r288087) and fixes the
test for the configuration:
  -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_ABI_BREAKING_CHECKS=FORCE_OFF

llvm-svn: 288196
2016-11-29 20:45:48 +00:00
Mehdi Amini
71e37b10ff Prevent at compile time converting from Error::success() to Expected<T>
This would trigger an assertion at runtime otherwise.

Differential Revision: https://reviews.llvm.org/D26482

llvm-svn: 286562
2016-11-11 04:29:25 +00:00
Mehdi Amini
3d0dd0ec2c Make the Error class constructor protected
This is forcing to use Error::success(), which is in a wide majority
of cases a lot more readable.

Differential Revision: https://reviews.llvm.org/D26481

llvm-svn: 286561
2016-11-11 04:28:40 +00:00
Lang Hames
3bf43acb9a [Support] Make ErrorAsOutParameter take an Error* rather than an Error&.
This allows ErrorAsOutParameter to work better with "optional" errors. For
example, consider a function where for certain input values it is known that
the function can't fail. This can now be written as:

Result foo(Arg X, Error *Err) {
  ErrorAsOutParameter EAO(Err);

  if (<Error Condition>) {
    if (Err)
      *Err = <report error>;
    else
      llvm_unreachable("Unexpected failure!");
  }
}

Rather than having to construct an ErrorAsOutParameter under every conditional
where Err is known to be non-null.

llvm-svn: 276430
2016-07-22 16:11:25 +00:00
Lang Hames
ea10bd5e79 [Support] Fix a bug in ErrorList::join / joinErrors.
When concatenating two error lists the ErrorList::join method (which is called
by joinErrors) was failing to set the checked bit on the second error, leading
to a 'failure to check error' assertion.

llvm-svn: 274249
2016-06-30 17:43:06 +00:00
Lang Hames
ddc9000626 [Support] Rename unconvertibleErrorCode to inconvertibleErrorCode.
Based on a totally scientific, 30 second google search "in-" appears to be the
preferred prefix.

llvm-svn: 270950
2016-05-27 01:54:25 +00:00
Lang Hames
776aaf18f4 [Support] Add a StringError convenience class to Error.h
StringError can be used to represent Errors that aren't recoverable based on
the error type, but that have a useful error message that can be reported to
the user or logged.

llvm-svn: 270948
2016-05-27 01:37:32 +00:00
Vedant Kumar
a650a4c26e [Support] Add a free toString function for Error
toString() consumes an Error and returns a string representation of its
contents. This commit also adds a message() method to ErrorInfoBase for
convenience.

Differential Revision: http://reviews.llvm.org/D19883

llvm-svn: 268465
2016-05-03 23:32:31 +00:00
Lang Hames
ed38574ae4 [Support] Fix latent bugs in Expected and ExitOnError that were preventing them
from working with reference types.

llvm-svn: 267448
2016-04-25 19:21:57 +00:00
Lang Hames
9e445cd6a2 [Support] Add a checked flag to Expected<T>, require checks before access or
destruction.

This makes the Expected<T> class behave like Error, even when in success mode.
Expected<T> values must be checked to see whether they contain an error prior
to being dereferenced, assigned to, or destructed.

llvm-svn: 265446
2016-04-05 19:57:03 +00:00
Lang Hames
a11110fd25 [Support] Switch to RAII helper for error-as-out-parameter idiom.
As discussed on the llvm-commits thread for r264467.

llvm-svn: 264479
2016-03-25 23:54:32 +00:00
Lang Hames
6c897febd8 [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.

llvm-svn: 264467
2016-03-25 21:56:35 +00:00
Reid Kleckner
57ae7f9db2 Try to fix ODR violation of ErrorInfo::ID
This implements my suggestion to Lang.

llvm-svn: 264360
2016-03-24 23:49:34 +00:00
NAKAMURA Takumi
5fba946e7d ErrorTest.cpp: Move instantiations out of anonymous namespace. gcc didn't complain.
llvm-svn: 264297
2016-03-24 15:40:46 +00:00
NAKAMURA Takumi
9a58a11846 Define ErrorInfo::ID explicitly.
llvm-svn: 264293
2016-03-24 15:26:43 +00:00
NAKAMURA Takumi
2d8ab09777 ErrorTest.cpp: Fix an expression, possibly typo.
llvm-svn: 264290
2016-03-24 15:19:22 +00:00
Lang Hames
fc3b132a68 [Support] Add conversions between Expected<T> and ErrorOr<T>.
More utilities to help with std::error_code -> Error transitions.

llvm-svn: 264238
2016-03-24 02:00:10 +00:00
Lang Hames
34b790d0e7 [Support] Make all Errors convertible to std::error_code.
This is a temporary crutch to enable code that currently uses std::error_code
to be incrementally moved over to Error. Requiring all Error instances be
convertible enables clients to call errorToErrorCode on any error (not just
ECErrors created by conversion *from* an error_code).

This patch also moves code for Error from ErrorHandling.cpp into a new
Error.cpp file.

llvm-svn: 264221
2016-03-23 23:57:28 +00:00
Lang Hames
aee22c683f [Support] Refactor Error unit tests to avoid duplicating work.
Suggested by Dave Blaikie in review for r263749. Thanks Dave!

llvm-svn: 263768
2016-03-18 00:12:37 +00:00
Lang Hames
034e76c90d [Support] Add ExitOnError utility to support tools that use the exit-on-error
idiom.

Most LLVM tool code exits immediately when an error is encountered and prints an
error message to stderr. The ExitOnError class supports this by providing two
call operators - one for Errors, and one for Expected<T>s. Calls to code that
can return Errors (or Expected<T>s) can use these calls to bail out on error,
and otherwise continue as if the operation had succeeded. E.g.

Error foo();
Expected<int> bar();

int main(int argc, char *argv[]) {
  ExitOnError ExitOnErr;

  ExitOnErr.setBanner(std::string("Error in ") + argv[0] + ":");

  // Exit if foo returns an error. No need to manually check error return.
  ExitOnErr(foo());

  // Exit if bar returns an error, otherwise unwrap the contained int and
  // continue.
  int X = ExitOnErr(bar());

  // ...

  return 0;
}

llvm-svn: 263749
2016-03-17 21:28:49 +00:00
Lang Hames
ffbf7496e2 [Support] Make Error::isA<T>() works on success values.
llvm-svn: 263745
2016-03-17 20:35:00 +00:00
Lang Hames
99892f21dc [Support] Update Error unit test to remove implementation specific behaviour.
llvm-svn: 263610
2016-03-16 01:20:54 +00:00
Lang Hames
69d7550bd6 [Support] Add the 'Error' class for structured error handling.
This patch introduces the Error classs for lightweight, structured,
recoverable error handling. It includes utilities for creating, manipulating
and handling errors. The scheme is similar to exceptions, in that errors are
described with user-defined types. Unlike exceptions however, errors are
represented as ordinary return types in the API (similar to the way
std::error_code is used).

For usage notes see the LLVM programmer's manual, and the Error.h header.
Usage examples can be found in unittests/Support/ErrorTest.cpp.

Many thanks to David Blaikie, Mehdi Amini, Kevin Enderby and others on the
llvm-dev and llvm-commits lists for lots of discussion and review.

llvm-svn: 263609
2016-03-16 01:02:46 +00:00