Skip to content

Commit 2d5f048

Browse files
committed
update examples
1 parent 11b7358 commit 2d5f048

File tree

9 files changed

+29
-122
lines changed

9 files changed

+29
-122
lines changed

README.md

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
# Nullsafe C: An experimental C/C++ compiler
22

3-
[![Test Null-Safety](https://github.com/cs01/llvm-project/actions/workflows/test-null-safety.yml/badge.svg)](https://github.com/cs01/llvm-project/actions/workflows/test-null-safety.yml)
3+
[![Test Null-Safety](https://github.com/cs01/llvm-project/actions/workflows/test-null-safety.yml/badge.svg)](https://github.com/cs01/llvm-project/actions/workflows/test-null-safety.yml)    [![Try Online](https://img.shields.io/badge/try-online-brightgreen)](https://cs01.github.io/llvm-project/)
4+
5+
> **Try it online:** [Interactive Playground](https://cs01.github.io/llvm-project/) - See null-safety warnings in real-time
46
57
Nullsafe C adds NULL checks to catch errors at compile-time. It is 100% compatible with existing C codebases and can be used incrementally to identify safety issues at compile-time.
68

79
This provides the following benefits:
8-
* This makes the code safer by reducing the number of potential runtime null dereferences
9-
* Improves developer experience by shifting errors left
10-
* Makes the code more readable
11-
* Adds type errors that other more modern languages have (Rust, TypeScript, Kotlin)
12-
13-
**Try it online:** [Interactive Playground](https://cs01.github.io/llvm-project/) - See null-safety warnings in real-time in your browser!
10+
* Catches errors at compile-time rather than runtime, reducing crashes
11+
* Improves developer experience by shifting errors left and showing issues in the IDE as you code
12+
* Makes code more readable and maintainable, including annotations with `_Nonnull`
13+
* Adds type checking that more modern languages have (Rust, TypeScript, Kotlin)
1414

1515
Nullsafe C treats all pointers as potentially null ('nullable') unless it is certain they are not. It does this in two ways.
1616

@@ -20,14 +20,18 @@ The second is by using Clang's [`Nullability`](https://clang.llvm.org/docs/Attri
2020

2121
If using a compiler other than clang, you can add `#define _Nonnull` as a no-op. You will not get the same compile checks as with Nullsafe C (clang fork), but the compillation will still succeed without error.
2222

23+
When a function is called, it will reset any type refinements, assuming there may be side effects. If the variable is marked `const` in the function signature the type narrowing is maintained, because it is guaranteed to not be made null within the function.
24+
25+
Note that this does not change any of the generated code. There are no performance impacts, it strictly does compile-time checks.
26+
2327
## Examples
2428

2529
```c
2630
void unsafe(int *data) {
2731
*data = 42; // warning: dereferencing nullable pointer of type 'int * _Nullable'
2832
}
2933
```
30-
[Try it in the interactive playground](https://cs01.github.io/llvm-project/?code=dm9pZCB1bnNhZmUoaW50ICpkYXRhKSB7CiAgKmRhdGEgPSA0MjsgLy8gd2FybmluZzogZGVyZWZlcmVuY2luZyBudWxsYWJsZSBwb2ludGVyIG9mIHR5cGUgJ2ludCAqIF9OdWxsYWJsZScKfQ%3D%3D)
34+
*[Try it in the interactive playground](https://cs01.github.io/llvm-project/?code=dm9pZCB1bnNhZmUoaW50ICpkYXRhKSB7CiAgKmRhdGEgPSA0MjsgLy8gd2FybmluZzogZGVyZWZlcmVuY2luZyBudWxsYWJsZSBwb2ludGVyIG9mIHR5cGUgJ2ludCAqIF9OdWxsYWJsZScKfQ%3D%3D)*
3135
3236
Type narrowing:
3337
```c
@@ -37,15 +41,15 @@ void safe(int *data) {
3741
}
3842
}
3943
```
40-
[Try it in the interactive playground](https://cs01.github.io/llvm-project/?code=dm9pZCBzYWZlKGludCAqZGF0YSkgewogIGlmIChkYXRhKSB7CiAgICAqZGF0YSA9IDQyOyAvLyBPSyAtIGRhdGEgaXMgbm9uLW51bGwgaGVyZQogIH0KfQ%3D%3D)
44+
*[Try it in the interactive playground](https://cs01.github.io/llvm-project/?code=dm9pZCBzYWZlKGludCAqZGF0YSkgewogIGlmIChkYXRhKSB7CiAgICAqZGF0YSA9IDQyOyAvLyBPSyAtIGRhdGEgaXMgbm9uLW51bGwgaGVyZQogIH0KfQ%3D%3D)*
4145

4246
Anontated with `_Nonnull`:
4347
```c
4448
void safe_typed(int *_Nonnull data) {
4549
*data = 42; // OK - we know data is not null so we can derefernce it
4650
}
4751
```
48-
[Try it in the interactive playground](https://cs01.github.io/llvm-project/?code=dm9pZCBzYWZlX3R5cGVkKGludCAqX05vbm51bGwgZGF0YSkgewogICpkYXRhID0gNDI7IC8vIE9LIC0gd2Uga25vdyBkYXRhIGlzIG5vdCBudWxsIHNvIHdlIGNhbiBkZXJlZmVybmNlIGl0Cn0%3D)
52+
*[Try it in the interactive playground](https://cs01.github.io/llvm-project/?code=dm9pZCBzYWZlX3R5cGVkKGludCAqX05vbm51bGwgZGF0YSkgewogICpkYXRhID0gNDI7IC8vIE9LIC0gd2Uga25vdyBkYXRhIGlzIG5vdCBudWxsIHNvIHdlIGNhbiBkZXJlZmVybmNlIGl0Cn0%3D)*
4953
5054
5155
## Installation
@@ -78,7 +82,7 @@ Each release includes:
7882

7983
Once installed, configure your editor to use the null-safe `clangd`. Install the `clangd` extension from llvm and set the path to the clangd binary you just downloaded.
8084

81-
**VSCode:**
85+
**VS Code:**
8286
```json
8387
// settings.json
8488
{
@@ -107,11 +111,11 @@ Do not that this is not a comprehensive solution, since Null pointer dereference
107111
| Double-free | ❌ Unsafe | ❌ Unsafe |
108112
| Uninitialized memory | ❌ Unsafe | ❌ Unsafe |
109113

110-
Although this doesn't fix all memory safety issues, it catches Null pointer dereferences for free.
114+
Although this doesn't fix all memory safety issues, it catches Null pointer dereferences for free. For additional memory safety, consider a language other than C.
111115

112116
### Why you still might want to try this
113117

114-
While Null-Safe Clang doesn't solve all memory safety issues, null pointer dereferences are a significant problem:
118+
While Null-Safe Clang doesn't solve all memory safety issues in C, null pointer dereferences are a significant problem:
115119

116120
- Many memory safety bugs involve null pointer dereferences
117121
- Easier to adopt than rewriting in Rust (100% compatible with existing C code)
@@ -124,11 +128,11 @@ While Null-Safe Clang doesn't solve all memory safety issues, null pointer deref
124128
Basic usage (warnings enabled by default):
125129
```bash
126130
# Warnings for nullable dereferences
127-
clang mycode.c
131+
clang -fsyntax-only mycode.c
128132
# Treat nullability issues as errors
129-
clang -Werror=nullability mycode.c
133+
clang -fsyntax-only -Werror=nullability mycode.c
130134
# Turn off nullability checking
131-
clang -fno-strict-nullability mycode.c
135+
clang -fsyntax-only -fno-strict-nullability mycode.c
132136
```
133137

134138

nullsafe-playground/examples/cjson-escape.c

Lines changed: 0 additions & 30 deletions
This file was deleted.

nullsafe-playground/examples/dereference-context.c

Lines changed: 0 additions & 6 deletions
This file was deleted.

nullsafe-playground/examples/loop-narrowing.c

Lines changed: 0 additions & 6 deletions
This file was deleted.

nullsafe-playground/examples/nonnull-annotation.c

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,7 @@ void process(int* _Nonnull data) {
22
*data = 42;
33
}
44

5-
void example(int* _Nullable x, int* _Nonnull y) {
6-
process(x);
7-
process(y);
5+
void example(int* x, int* _Nonnull y) {
6+
process(x); // error
7+
process(y); // OK
88
}
9-
10-
void deref_twice_unsafe(int* _Nullable * _Nullable pp) {
11-
**pp = 42;
12-
}
13-
14-
void deref_twice_safe(int* _Nullable * _Nullable pp) {
15-
if (pp && *pp) {
16-
**pp = 42;
17-
}
18-
}
19-
20-
void deref_twice_partial(int* _Nullable * _Nullable pp) {
21-
if (pp) {
22-
**pp = 42;
23-
}
24-
}

nullsafe-playground/examples/null-check.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,3 @@ void safe(int *data) {
77
*data = 42; // OK - data is non-null here
88
}
99
}
10-
11-
void safe_typed(int *_Nonnull data) {
12-
*data = 42; // OK - data is known to be non-null by the compiler
13-
}

nullsafe-playground/examples/pure-function.c

Lines changed: 0 additions & 8 deletions
This file was deleted.

nullsafe-playground/examples/redis-sds.c

Lines changed: 0 additions & 20 deletions
This file was deleted.

nullsafe-playground/index.html

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -564,20 +564,13 @@ <h1>Nullsafe C Playground</h1>
564564
</button>
565565

566566
<select id="examplesSelect" class="examples-select" title="Load example code to see Nullsafe C in action">
567-
<option value="null-check" selected>1. Basic Null Check</option>
568-
<option value="early-return">2. Early Return Pattern</option>
569-
<option value="pure-function">3. Const Functions Preserve Narrowing</option>
570-
<option value="function-invalidates">4. Function Invalidates Narrowing</option>
567+
<option value="null-check" selected>1. Raw pointer Dereference</option>
568+
<option value="early-return">2. Early Return</option>
569+
<option value="and-pattern">3. AND Pattern Narrowing</option>
570+
<option value="else-branch">4. Else Branch Narrowing</option>
571571
<option value="nonnull-annotation">5. _Nonnull Annotations</option>
572-
<option value="multi-level">6. Multi-Level Pointers</option>
573-
<option value="and-pattern">7. AND Pattern Narrowing</option>
574-
<option value="else-branch">8. Else Branch Narrowing</option>
575-
<option value="loop-narrowing">9. Loop Condition Narrowing</option>
576-
<option value="dereference-context">10. Null Check Before Deref</option>
577-
<optgroup label="Real-World Bugs">
578-
<option value="redis-sds">11. Redis: sdssetlen() pointer arithmetic</option>
579-
<option value="cjson-escape">12. cJSON: print_string_ptr() escaping</option>
580-
</optgroup>
572+
<option value="function-invalidates">6. Function Invalidates Narrowing</option>
573+
<option value="multi-level">7. Multi-Level Pointers</option>
581574
</select>
582575

583576
<button id="shareBtn" class="btn btn-secondary" title="Copy a shareable link with your code to clipboard">

0 commit comments

Comments
 (0)