@@ -92,7 +92,16 @@ Using the `ownership_returns`, `ownership_takes`, and `ownership_holds` attribut
92
92
93
93
#### Example usage
94
94
95
- GCC ` malloc ` , ` malloc ( ` _ ` deallocator ` _ ` ) ` , and ` malloc ( ` _ ` deallocator ` _ , _ ` ptr-index ` _ ` ) ` :
95
+ GCC ` malloc ` , ` malloc ( ` _ ` deallocator ` _ ` ) ` , and ` malloc ( ` _ ` deallocator ` _ , _ ` ptr-index ` _ ` ) ` in C++11 / C23 attribute syntax:
96
+
97
+ ~~~ c
98
+ void my_free (void * ptr);
99
+
100
+ // Denotes that my_malloc will return with a dynamically allocated piece of memory which must be freed using my_free.
101
+ void * my_malloc(size_t size) [[ gnu::malloc]] [[ gnu::malloc(my_free, 1)]] ;
102
+ ~~~
103
+
104
+ In `__attribute__` keyword syntax:
96
105
97
106
~~~c
98
107
void my_free(void *ptr);
@@ -103,7 +112,20 @@ void *my_malloc(size_t size) __attribute__ ((malloc, malloc (my_free, 1)));
103
112
104
113
Note that to benefit both from the associated optimizations and improved detection of memory errors functions should be marked with _ both_ the form of the attribute without arguments and the form of the attribute with one or two arguments. [[ Extended example at Compiler Explorer] ( https://godbolt.org/z/bc97ahbnd )]
105
114
106
- Clang `ownership_returns`, `ownership_takes`, and `ownership_holds`:
115
+ Clang ` ownership_returns ` , ` ownership_takes ` , and ` ownership_holds ` in C++11 / C23 attribute syntax:
116
+
117
+ ~~~ c
118
+ // Denotes that my_malloc will return with a pointer to storage labeled as "my_allocation".
119
+ void * my_malloc (size_t size) [[ gnu::malloc]] [[ clang::ownership_returns(my_allocation)]] ;
120
+
121
+ // Denotes that my_free will deallocate storage pointed to by ptr that has been labeled "my_allocation".
122
+ voidmy_free(void * ptr) [[ clang::ownership_takes(my_allocation, 1)]] ;
123
+
124
+ // Denotes that my_hold will take over the ownership of storage pointed to by ptr that has been labeled "my_allocation".
125
+ void my_hold(void * ptr) [[ clang::ownership_holds(my_allocation, 1)]] ;
126
+ ~~~
127
+
128
+ In `__attribute__` keyword syntax:
107
129
108
130
~~~c
109
131
// Denotes that my_malloc will return with a pointer to storage of labeled as "my_allocation" .
@@ -141,6 +163,21 @@ In Clang, the size information hints provided via `alloc_size` attribute only af
141
163
142
164
#### Example usage
143
165
166
+ In C++11 / C23 attribute syntax:
167
+
168
+ ~~~ c
169
+ // Denotes that my_malloc will return with a pointer to storage capable of holding up to size bytes.
170
+ void * my_malloc (size_t size) [[ gnu::alloc_size(1)]] ;
171
+
172
+ // Denotes that my_realloc will return with a pointer to storage capable of holding up to size bytes.
173
+ void * my_realloc(void* ptr, size_t size) [[ gnu::alloc_size(2)]] ;
174
+
175
+ // Denotes that my_calloc will return with a pointer to storage capable of holding up to n * size bytes.
176
+ void * my_calloc(size_t n, size_t size) [[ gnu::alloc_size(1, 2)]] ;
177
+ ~~~
178
+
179
+ In `__attribute__` keyword syntax:
180
+
144
181
~~~c
145
182
// Denotes that my_malloc will return with a pointer to storage capable of holding up to size bytes.
146
183
void *my_malloc(size_t size) __attribute__((alloc_size(1)));
@@ -197,6 +234,33 @@ In the `read_only` and `read_write` access modes the object referenced by the po
197
234
198
235
### Example usage
199
236
237
+ In C++11 / C23 attribute syntax:
238
+
239
+ ~~~ c
240
+ // Denotes that puts performs read-only access on the memory pointed to by ptr.
241
+ int puts (const char* ptr) [[ gnu::access(read_only, 1)]] ;
242
+
243
+ // Denotes that strcat performs read-write access on the memory pointed to by destination and read-only access on the memory pointed to by source.
244
+ char* strcat (char* destination, const char* source) [[ gnu::access(read_write, 1)]] [[ gnu::access(read_only, 2)]] ;
245
+
246
+ // Denotes that strcpy performs write-only access on the memory pointed to by destination and read-only access on the memory pointed to by source.
247
+ char* strcpy (char* destination, const char* source) [[ gnu::access(write_only, 1)]] [[ gnu::access(read_only, 2)]] ;
248
+
249
+ // Denotes that fgets performs write-only access up to n characters on the memory pointed to by buff and read-write access on the memory pointed to by stream.
250
+ int] fgets (char* buff, int n, FILE* stream) [[ gnu::access(write_only, 1, 2)]] [[ gnu::access(read_write, 3)] ;
251
+
252
+ // Denotes that print_buffer performs read-only access up to size characters on memory pointed to by buffer.
253
+ void print_buffer(const char * buffer, size_t size) [[ gnu::access(read_only, 1, 2)]] ;
254
+
255
+ // Denotes that fill_buffer performs write-only access up to size characters on memory pointed to by buffer.
256
+ void fill_buffer(char * buffer, size_t size) [[ gnu::access(write_only, 1, 2)]] ;
257
+
258
+ // Denotes that to_uppercase performs read-write access up to size characters on memory pointed to by buffer.
259
+ void to_uppercase(char * buffer, size_t size) [[ gnu::access(read_write, 1, 2)]] ;
260
+ ~~~
261
+
262
+ In `__attribute__` keyword syntax:
263
+
200
264
~~~c
201
265
// Denotes that puts performs read-only access on the memory pointed to by ptr.
202
266
int puts (const char* ptr) __attribute__ ((access (read_only, 1)));
@@ -250,6 +314,21 @@ The `fd_arg_write(`_`fd-index`_`)` form is like `fd_arg` but also requires that
250
314
251
315
#### Example usage
252
316
317
+ In C++11 / C23 attribute syntax:
318
+
319
+ ~~~ c
320
+ // Denotes that use_file expects fd to be a valid and open file descriptor
321
+ void use_file (int fd) [[ gnu::fd_arg(1)]] ;
322
+
323
+ // Denotes that write_to_file expects fd to be a valid, open, and writable file descriptor
324
+ void write_to_file (int fd, void * src, size_t size) [[ gnu::fd_arg_write(1)]] ;
325
+
326
+ // Denotes that read_from_file expects fd to be a valid, open, and readable file descriptor
327
+ void read_from_file (int fd, void * dst, size_t size) [[ gnu::fd_arg_read(1)]] ;
328
+ ~~~
329
+
330
+ In `__attribute__` keyword syntax:
331
+
253
332
~~~c
254
333
// Denotes that use_file expects fd to be a valid and open file descriptor
255
334
void use_file (int fd) __attribute__ ((fd_arg (1)));
@@ -281,6 +360,22 @@ Users should be careful not to assume that registers saved by the calling functi
281
360
282
361
#### Example usage
283
362
363
+ In C++11 / C23 attribute syntax:
364
+
365
+ ~~~ c
366
+ // Denotes that fatal will never return
367
+ void fatal () [[noreturn]];
368
+
369
+ void
370
+ fatal (...)
371
+ {
372
+ ... /* Print error message. * / ...
373
+ exit (1);
374
+ }
375
+ ~~~
376
+
377
+ In `__attribute__` keyword syntax:
378
+
284
379
~~~c
285
380
// Denotes that fatal will never return
286
381
void fatal () __attribute__ ((noreturn));
@@ -331,6 +426,15 @@ Prior to GCC 14.1.0 the GCC analyzer's _taint mode_ had to be explicitly enabled
331
426
332
427
### Example usage
333
428
429
+ In C++11 / C23 attribute syntax:
430
+
431
+ ~~~ c
432
+ // Marks arguments to do_with_untrusted as requiring sanitization
433
+ void do_with_untrusted_input (int untrusted_input) [[ gnu::tainted_args]] ;
434
+ ~~~
435
+
436
+ In `__attribute__` keyword syntax:
437
+
334
438
~~~c
335
439
// Marks arguments to do_with_untrusted as requiring sanitization
336
440
void do_with_untrusted_input(int untrusted_input) __attribute__ ((tainted_args));
0 commit comments