@@ -92,7 +92,16 @@ Using the `ownership_returns`, `ownership_takes`, and `ownership_holds` attribut
9292
9393#### Example usage
9494
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:
96105
97106~~~c
98107void my_free(void *ptr);
@@ -103,7 +112,20 @@ void *my_malloc(size_t size) __attribute__ ((malloc, malloc (my_free, 1)));
103112
104113Note 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 )]
105114
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:
107129
108130~~~c
109131// 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
141163
142164#### Example usage
143165
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+
144181~~~c
145182// Denotes that my_malloc will return with a pointer to storage capable of holding up to size bytes.
146183void *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
197234
198235### Example usage
199236
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+
200264~~~c
201265// Denotes that puts performs read-only access on the memory pointed to by ptr.
202266int 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
250314
251315#### Example usage
252316
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+
253332~~~c
254333// Denotes that use_file expects fd to be a valid and open file descriptor
255334void 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
281360
282361#### Example usage
283362
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+
284379~~~c
285380// Denotes that fatal will never return
286381void fatal () __attribute__ ((noreturn));
@@ -331,6 +426,15 @@ Prior to GCC 14.1.0 the GCC analyzer's _taint mode_ had to be explicitly enabled
331426
332427### Example usage
333428
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+
334438~~~c
335439// Marks arguments to do_with_untrusted as requiring sanitization
336440void do_with_untrusted_input(int untrusted_input) __attribute__ ((tainted_args));
0 commit comments