@@ -263,8 +263,176 @@ almost never be stored or mentioned directly. They are intended solely for use
263
263
when defining a function which should be able to efficiently accept concatenated
264
264
strings.
265
265
266
+ .. _error_apis :
267
+
268
+ Error handling
269
+ --------------
270
+
271
+ Proper error handling helps us identify bugs in our code, and helps end-users
272
+ understand errors in their tool usage. Errors fall into two broad categories:
273
+ *programmatic * and *recoverable *, with different strategies for handling and
274
+ reporting.
275
+
276
+ Programmatic Errors
277
+ ^^^^^^^^^^^^^^^^^^^
278
+
279
+ Programmatic errors are violations of program invariants or API contracts, and
280
+ represent bugs within the program itself. Our aim is to document invariants, and
281
+ to abort quickly at the point of failure (providing some basic diagnostic) when
282
+ invariants are broken at runtime.
283
+
284
+ The fundamental tools for handling programmatic errors are assertions and the
285
+ llvm_unreachable function. Assertions are used to express invariant conditions,
286
+ and should include a message describing the invariant:
287
+
288
+ .. code-block :: c++
289
+
290
+ assert(isPhysReg(R) && "All virt regs should have been allocated already.");
291
+
292
+ The llvm_unreachable function can be used to document areas of control flow
293
+ that should never be entered if the program invariants hold:
294
+
295
+ .. code-block :: c++
296
+
297
+ enum { Foo, Bar, Baz } X = foo();
298
+
299
+ switch (X) {
300
+ case Foo: /* Handle Foo */; break;
301
+ case Bar: / * Handle Bar */; break;
302
+ default:
303
+ llvm_unreachable("X should be Foo or Bar here");
304
+ }
305
+
306
+ Recoverable Errors
307
+ ^^^^^^^^^^^^^^^^^^
308
+
309
+ Recoverable errors represent an error in the program's environment, for example
310
+ a resource failure (a missing file, a dropped network connection, etc.), or
311
+ malformed input. These errors should be detected and communicated to a level of
312
+ the program where they can be handled appropriately. Handling the error may be
313
+ as simple as reporting the issue to the user, or it may involve attempts at
314
+ recovery.
315
+
316
+ Recoverable errors are modeled using LLVM's ``Error `` scheme. This scheme
317
+ represents errors using function return values, similar to classic C integer
318
+ error codes, or C++'s ``std::error_code ``. However, the ``Error `` class is
319
+ actually a lightweight wrapper for user-defined error types, allowing arbitrary
320
+ information to be attached to describe the error. This is similar to the way C++
321
+ exceptions allow throwing of user-defined types.
322
+
323
+ Success values are created by calling ``Error::success() ``:
324
+
325
+ .. code-block :: c++
326
+
327
+ Error foo() {
328
+ // Do something.
329
+ // Return success.
330
+ return Error::success();
331
+ }
332
+
333
+ Success values are very cheap to construct and return - they have minimal
334
+ impact on program performance.
335
+
336
+ Failure values are constructed using ``make_error<T> ``, where ``T `` is any class
337
+ that inherits from the ErrorInfo utility:
338
+
339
+ .. code-block :: c++
340
+
341
+ class MyError : public ErrorInfo<MyError> {
342
+ public:
343
+ MyError(std::string Msg) : Msg(Msg) {}
344
+ void log(OStream &OS) const override { OS << "MyError - " << Msg; }
345
+ private:
346
+ std::string Msg;
347
+ };
348
+
349
+ Error bar() {
350
+ if (checkErrorCondition)
351
+ return make_error<MyError>("Error condition detected");
352
+
353
+ // No error - proceed with bar.
354
+
355
+ // Return success value.
356
+ return Error::success();
357
+ }
358
+
359
+ For functions that can fail but need to return a value the ``Expected<T> ``
360
+ utility can be used. Values of this type can be constructed with either a
361
+ ``T ``, or a ``Error ``. Values are implicitly convertible to boolean: true
362
+ for success, false for error. If success, the ``T `` value can be accessed via
363
+ the dereference operator. If failure, the ``Error `` value can be extracted
364
+ using the ``takeError() `` method:
365
+
366
+ .. code-block :: c++
367
+
368
+ Expected<float> parseAndSquareRoot(IStream &IS) {
369
+ float f;
370
+ OS >> f;
371
+ if (f < 0)
372
+ return make_error<FloatingPointError>(...);
373
+ return sqrt(f);
374
+ }
375
+
376
+ Error foo(IStream &IS) {
377
+ if (auto SqrtOrErr = parseAndSquartRoot(IS)) {
378
+ float Sqrt = *SqrtOrErr;
379
+ // ...
380
+ } else
381
+ return SqrtOrErr.takeError();
382
+ }
383
+
384
+ All Error instances, whether success or failure, must be either checked or
385
+ moved from (via std::move or a return) before they are destructed. Accidentally
386
+ discarding an unchecked error will cause a program abort at the point where the
387
+ unchecked value's destructor is run, making it easy to identify and fix
388
+ violations of this rule.
389
+
390
+ Success values are considered checked once they have been tested (by invoking
391
+ the boolean conversion operator):
392
+
393
+ .. code-block :: c++
394
+
395
+ if (auto Err = canFail(...))
396
+ return Err; // Failure value - move error to caller.
397
+
398
+ // Safe to continue: Err was checked.
399
+
400
+ In contrast, the following code will always cause an abort, regardless of the
401
+ return value of ``foo ``:
402
+
403
+ .. code-block :: c++
404
+
405
+ canFail();
406
+ // Program will always abort here, even if canFail() returns Success, since
407
+ // the value is not checked.
408
+
409
+ Failure values are considered checked once a handler for the error type has
410
+ been activated:
411
+
412
+ .. code-block :: c++
413
+
414
+ auto Err = canFail(...);
415
+ if (auto Err2 =
416
+ handleErrors(std::move(Err),
417
+ [](std::unique_ptr<MyError> M) {
418
+ // Try to handle 'M'. If successful, return a success value from
419
+ // the handler.
420
+ if (tryToHandle(M))
421
+ return Error::success();
422
+
423
+ // We failed to handle 'M' - return it from the handler.
424
+ // This value will be passed back from catchErrors and
425
+ // wind up in Err2, where it will be returned from this function.
426
+ return Error(std::move(M));
427
+ })))
428
+ return Err2;
429
+
430
+
266
431
.. _function_apis :
267
432
433
+ More information on Error and its related utilities can be found in the
434
+ Error.h header file.
435
+
268
436
Passing functions and other callable objects
269
437
--------------------------------------------
270
438
0 commit comments