ADDING SUPPORT FOR C++ CONTRACTS TO CLANG A CS PhD. student - - PowerPoint PPT Presentation

adding support for c contracts to clang
SMART_READER_LITE
LIVE PREVIEW

ADDING SUPPORT FOR C++ CONTRACTS TO CLANG A CS PhD. student - - PowerPoint PPT Presentation

and some thoughts around their application Javier Lpez-Gmez 8th April 2019 Computer Science and Engineering Department, University Carlos III of Madrid ADDING SUPPORT FOR C++ CONTRACTS TO CLANG A CS PhD. student (Computer Architecture


slide-1
SLIDE 1

ADDING SUPPORT FOR C++ CONTRACTS TO CLANG

…and some thoughts around their application

Javier López-Gómez 8th April 2019

Computer Science and Engineering Department, University Carlos III of Madrid

slide-2
SLIDE 2

Who am I?

A CS PhD. student (Computer Architecture and Technology Area) Spent some time hacking the Linux kernel, embedded software, electronics… (low-level stuff!) Now: working on Clang for the last year

1/27

slide-3
SLIDE 3

Agenda

1

Introduction

2

Background

3

Supporting the P0542R5 TS in Clang

4

CSV: an extension to TSan that uses contracts

5

Conclusion

2/27

slide-4
SLIDE 4

Agenda

1

Introduction

2

Background

3

Supporting the P0542R5 TS in Clang

4

CSV: an extension to TSan that uses contracts

5

Conclusion

3/27

slide-5
SLIDE 5

In C++17…

Compile-time: static_assert(…) Run-time: C89 assert(…) …or other (non-standard) user-defjned macro/function. But assert(…) is a macro which expands to nothing for a production build.

This might be improved!

4/27

slide-6
SLIDE 6

But in C++20 we might have…

Declaration (probably in a header fjle):

int f(int x) [[expects default: x > 0]] // low-cost precondition [[expects audit: sanity_chk(x)]] // high computational cost [[ensures ret: ret > 0]]; // postcondition

Defjnition (in .cpp fjle):

int f(int x) { … }

5/27

slide-7
SLIDE 7

Agenda

1

Introduction

2

Background

3

Supporting the P0542R5 TS in Clang

4

CSV: an extension to TSan that uses contracts

5

Conclusion

6/27

slide-8
SLIDE 8

The C++ contract TS (P0542R5) (1/5)

P0542R5: a proposal to support contracts in C++. Contract: the set of preconditions, postconditions and assertions associated to a function. Precondition: What are the expectations of the function? —Evaluated at function entry [[expects: …]] Postconditions: What must the function ensure upon termination? —Evaluated at function exit [[ensures: …]] Assertion:

7/27

slide-9
SLIDE 9

The C++ contract TS (P0542R5) (1/5)

P0542R5: a proposal to support contracts in C++. Contract: the set of preconditions, postconditions and assertions associated to a function. Precondition: What are the expectations of the function? —Evaluated at function entry [[expects: …]] Postconditions: What must the function ensure upon termination? —Evaluated at function exit [[ensures: …]] Assertion:

7/27

slide-10
SLIDE 10

The C++ contract TS (P0542R5) (1/5)

P0542R5: a proposal to support contracts in C++. Contract: the set of preconditions, postconditions and assertions associated to a function. Precondition: What are the expectations of the function? —Evaluated at function entry [[expects: …]] Postconditions: What must the function ensure upon termination? —Evaluated at function exit [[ensures: …]] Assertion:

7/27

slide-11
SLIDE 11

The C++ contract TS (P0542R5) (1/5)

P0542R5: a proposal to support contracts in C++. Contract: the set of preconditions, postconditions and assertions associated to a function. Precondition: What are the expectations of the function? —Evaluated at function entry [[expects: …]] Postconditions: What must the function ensure upon termination? —Evaluated at function exit [[ensures: …]] Assertion:

7/27

slide-12
SLIDE 12

The C++ contract TS (P0542R5) (1/5)

P0542R5: a proposal to support contracts in C++. Contract: the set of preconditions, postconditions and assertions associated to a function. Precondition: What are the expectations of the function? —Evaluated at function entry [[expects: …]] Postconditions: What must the function ensure upon termination? —Evaluated at function exit [[ensures: …]] Assertion: Do I need to defjne this?

7/27

slide-13
SLIDE 13

The C++ contract TS (P0542R5) (1/5)

P0542R5: a proposal to support contracts in C++. Contract: the set of preconditions, postconditions and assertions associated to a function. Precondition: What are the expectations of the function? —Evaluated at function entry [[expects: …]] Postconditions: What must the function ensure upon termination? —Evaluated at function exit [[ensures: …]] Assertion: Do I need to defjne this? A predicate that should hold at a specifjc location of the function body. [[assert: …]]

7/27

slide-14
SLIDE 14

The C++ contract TS (P0542R5) (2/5)

You can include an assertion level [[assert HERE: …]]…

  • axiom. Not evaluated at run-time (useful for static analysis/optimizer).

default/audit. Indicate the relative computational cost of the checks. A translation is carried out in a specifjc build level (off, default, audit).

8/27

slide-15
SLIDE 15

The C++ contract TS (P0542R5) (3/5)

ensures-only: an identifjer may be introduced [[ensures default HERE: …]] and can be used to refer to the return value of the function.

9/27

slide-16
SLIDE 16

The C++ contract TS (P0542R5) (4/5)

By default, a violated contract invokes std::terminate(). Alternatively, the user can specify a handler (per-translation). std::terminate() may optionally be called after return.

void (const std::contract_violation &); // the type of a handler class contract_violation { public: int line_number() const noexcept; string_view file_name() const noexcept; string_view function_name() const noexcept; string_view comment() const noexcept; string_view assertion_level() const noexcept; };

10/27

slide-17
SLIDE 17

The C++ contract TS (P0542R5) (4/5)

By default, a violated contract invokes std::terminate(). Alternatively, the user can specify a handler (per-translation). std::terminate() may optionally be called after return.

void (const std::contract_violation &); // the type of a handler class contract_violation { public: int line_number() const noexcept; string_view file_name() const noexcept; string_view function_name() const noexcept; string_view comment() const noexcept; string_view assertion_level() const noexcept; };

10/27

slide-18
SLIDE 18

The C++ contract TS (P0542R5) (5/5)

A contract… …has no observable effect on a correct program (except performance): UB if side-effects. …might be a convenient to provide additional information to the

  • ptimizer/3rd-party libraries.

11/27

slide-19
SLIDE 19

Agenda

1

Introduction

2

Background

3

Supporting the P0542R5 TS in Clang

4

CSV: an extension to TSan that uses contracts

5

Conclusion

12/27

slide-20
SLIDE 20

Required changes to the Clang FE (1/2)

xxx.cpp Lex

Parse Sema AST CodeGen

IR Figure 1: Patched Clang components

  • Parse. Updated due to the proposed grammar changes for contract attributes.
  • Sema. Most of the code is here (Decl injection, merging attributes, instantiation,

etc.)

  • AST. Small changes to the ASTContext and FunctionDecl classes.
  • CodeGen. Run-time checks code generation.

13/27

slide-21
SLIDE 21

Required changes to the Clang FE (2/2)

(1): copy the f FunctionDecl; the copy (g) owns the original body of f will be forced inline. (2): body of f replaced (synthesized): evaluates pre-conditions + calls g + evaluates post-conditions.

f

GenerateCode(f) … (2)

g

EmitGlobal(g) … (1)

Figure 2: CodeGen for functions that have pre/post-conditions

14/27

slide-22
SLIDE 22

Required changes to the Clang FE (3/3)

int f(int x) [[expects: x==2]]; … int f(int x) { return x; } define i32 @_Z1fi ( i32 returned %x) local_unnamed_addr #0 { entry: % cmp = icmp eq i32 %x, 2 br i1 %cmp, label %if.end, label %if.then if.then: tail call void @_ZSt9terminatev() #2 unreachable if.end: ret i32 2 } Figure 3: A function (+precondition) and its LLVM IR

15/27

slide-23
SLIDE 23

Applying the “p1290r0” fjx

ISSUE: Assuming contracts that were not checked was a source of UB. FIX: Do not assume unchecked contracts (except axiom (depending on the “axiom mode”) Added the -axiom-mode= command line option.

16/27

slide-24
SLIDE 24

Evaluation (1/2)

What? GNU libstdc++ std::basic_string How? Replaced the __glibcxx_assert macro by [[assert: …]] or [[expects: …]] and compared the run-time overhead (10000 iterations).

17/27

slide-25
SLIDE 25

Evaluation (2/2)

3600 3700 3800 3900 4000 4100 4200 4300 4400 4500 1000 2000 3000 4000 5000 6000 Time(milliseconds) String Size(characters) Benchmark 2(-O2) - Time Comparison No Contracts Version Contracts Version

Figure 4: Swap characters (-O2)

500 1000 1500 2000 2500 3000 3500 4000 4500 5000 1000 2000 3000 4000 5000 6000 Time(milliseconds) String Size(characters) Benchmark 6(-O2) - Time Comparison No Contracts Version Contracts Version

Figure 5: Find and replace 3-char substring in a random string (-O2)

18/27

slide-26
SLIDE 26

DEMO: a P0542R5-enabled Clang

Try it: http://fragata.arcos.inf.uc3m.es/ Open-sourced (GitHub)1: https://github.com/arcosuc3m/clang-contracts/

1To be rebased on top of the current development branch and submitted for code review.

19/27

slide-27
SLIDE 27

But wait, that’s not all!

C++ contracts may also be used as annotations for static analyzers (axiom) or to interface third party libraries. To prove this point, we built something on top of this…

20/27

slide-28
SLIDE 28

Agenda

1

Introduction

2

Background

3

Supporting the P0542R5 TS in Clang

4

CSV: an extension to TSan that uses contracts

5

Conclusion

21/27

slide-29
SLIDE 29

ISSUE: TSan and lock-free data structures

ISSUE: ThreadSanitizer reports false positives using a Boost lock-free SPSC queue (only 1 producer + 1 consumer). FIX: extend ThreadSanitizer to honour user-defjned data structure semantics (that use C++ contracts).

22/27

slide-30
SLIDE 30

CSV: a TSan extension (1/2)

Listing 1: Updated “boost/lockfree/spsc_queue.hpp” to use CSV

#include "csv.h" template <typename T, typename... Options> class [[csv::checked]] spsc_queue { private: [[csv::event_sets(init_events, prod_events, cons_events, nts_events)]]; public: … bool push(T const &) [[expects audit: !init_events.empty() && init_events.happens_before(csv::current_event())]] [[expects audit: !prod_events.concurrent(csv::current_event())]] [[csv::add_current(prod_events)]]; … }; 23/27

slide-31
SLIDE 31

CSV: a TSan extension (2/2)

================== WARNING: CSV: rule violation at …/spsc_queue.hpp:854 `!prod_events.concurrent(csv::current_event())` Stack trace: #0 __csv_violation_handler /home/…/tsan/rtl/tsan_csv.cc:45 (+0x4915f0) #1 boost::lockfree::spsc_queue<T>::push(T) <null> (+0x4b8f99) … Figure 6: If a rule is violated the user gets a descriptive trace

24/27

slide-32
SLIDE 32

Open Source: TSan—CSV patches

CSV is maintained as a branch (CSV-src) at the clang-contracts repository: https://github.com/arcosuc3m/clang-contracts/

25/27

slide-33
SLIDE 33

Agenda

1

Introduction

2

Background

3

Supporting the P0542R5 TS in Clang

4

CSV: an extension to TSan that uses contracts

5

Conclusion

26/27

slide-34
SLIDE 34

Conclusions

Support for contract-checking in C++… Helps to detect more programming errors (improves correctness). Run-time checking can be enabled/disabled (Safety—Run-time overhead). Q: Can I throw an exception/log violations? A: Use a violation handler! Portable and standard way of providing information to the optimizer/third party libraries. Few issues to be fjxed: P0542R5 Sec. 2.3, late-parsing, and contract inheritance.

27/27

slide-35
SLIDE 35

Conclusions

Support for contract-checking in C++… Helps to detect more programming errors (improves correctness). Run-time checking can be enabled/disabled (Safety—Run-time overhead). Q: Can I throw an exception/log violations? A: Use a violation handler! Portable and standard way of providing information to the optimizer/third party libraries. Few issues to be fjxed: P0542R5 Sec. 2.3, late-parsing, and contract inheritance.

27/27

slide-36
SLIDE 36

Conclusions

Support for contract-checking in C++… Helps to detect more programming errors (improves correctness). Run-time checking can be enabled/disabled (Safety—Run-time overhead). Q: Can I throw an exception/log violations? A: Use a violation handler! Portable and standard way of providing information to the optimizer/third party libraries. Few issues to be fjxed: P0542R5 Sec. 2.3, late-parsing, and contract inheritance.

27/27

slide-37
SLIDE 37

Conclusions

Support for contract-checking in C++… Helps to detect more programming errors (improves correctness). Run-time checking can be enabled/disabled (Safety—Run-time overhead). Q: Can I throw an exception/log violations? A: Use a violation handler! Portable and standard way of providing information to the optimizer/third party libraries. Few issues to be fjxed: P0542R5 Sec. 2.3, late-parsing, and contract inheritance.

27/27

slide-38
SLIDE 38

Conclusions

Support for contract-checking in C++… Helps to detect more programming errors (improves correctness). Run-time checking can be enabled/disabled (Safety—Run-time overhead). Q: Can I throw an exception/log violations? A: Use a violation handler! Portable and standard way of providing information to the optimizer/third party libraries. Few issues to be fjxed: P0542R5 Sec. 2.3, late-parsing, and contract inheritance.

27/27

slide-39
SLIDE 39

Thanks!

Thank you for listening!

¿?

https://github.com/arcosuc3m/clang-contracts/ 27/27