diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2024-06-24 15:08:16 -0400 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2024-06-24 15:09:20 -0400 |
commit | 2ae09052477e1a966afbc5482d88585f95694c53 (patch) | |
tree | 94d952e55cbae84f33a9a7c64357a6e2185d4019 | |
parent | d6a3bd1325c5c54ef59e8a612451757c86186355 (diff) | |
download | llvm-2ae09052477e1a966afbc5482d88585f95694c53.zip llvm-2ae09052477e1a966afbc5482d88585f95694c53.tar.gz llvm-2ae09052477e1a966afbc5482d88585f95694c53.tar.bz2 |
[C23] Claim we do not conform to N2819
This paper clarified the lifetime of compound literal objects in odd
scopes, such as use at function prototype scope.
We do not currently implement this paper, as the new test demonstrates.
-rw-r--r-- | clang/test/C/C2x/n2819.c | 57 | ||||
-rw-r--r-- | clang/www/c_status.html | 2 |
2 files changed, 58 insertions, 1 deletions
diff --git a/clang/test/C/C2x/n2819.c b/clang/test/C/C2x/n2819.c new file mode 100644 index 0000000..c428fbb --- /dev/null +++ b/clang/test/C/C2x/n2819.c @@ -0,0 +1,57 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 3 +// RUN: %clang_cc1 -triple=x86_64 -emit-llvm -o - -std=c23 %s | FileCheck %s + +/* WG14 N2819: No + * Disambiguate the storage class of some compound literals + */ + +int *escaped; +// CHECK-LABEL: define dso_local i32 @f( +// CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 +// CHECK-NEXT: store ptr [[TMP0]], ptr @escaped, align 8 +// CHECK-NEXT: ret i32 1 +// +int f(int *ptr) { escaped = ptr; return 1; } + +// CHECK-LABEL: define dso_local i32 @g( +// CHECK-SAME: ptr noundef [[PARA:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[PARA_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[PARA]], ptr [[PARA_ADDR]], align 8 +// CHECK-NEXT: [[CALL:%.*]] = call i32 @f(ptr noundef @.compoundliteral) +// CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[CALL]] to i64 +// CHECK-NEXT: ret i32 0 +// +// FIXME: notice the we are using the global .compoundliteral object, not +// allocating a new object on each call to g(). That's what was clarified by +// N2819. +int g(char *para [f(( int [27]) { 0 })]) { + return 0; +} + +// CHECK-LABEL: define dso_local i32 @main( +// CHECK-SAME: ) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK-NEXT: [[CALL:%.*]] = call i32 @g(ptr noundef null) +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr @escaped, align 8 +// CHECK-NEXT: store i32 12, ptr [[TMP0]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr @escaped, align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[TMP1]], align 4 +// CHECK-NEXT: ret i32 [[TMP2]] +// +int main() { + // Sets 'escaped' to the address of the array created by the compound literal. + g(nullptr); + + // The lifetime of that object should have ended when g() returned, so this + // should be a use-after-free. + *escaped = 12; + return *escaped; +} + diff --git a/clang/www/c_status.html b/clang/www/c_status.html index 434c9e2..25656c0 100644 --- a/clang/www/c_status.html +++ b/clang/www/c_status.html @@ -1025,7 +1025,7 @@ conforms by not defining the <code>__STDC_IEC_559_COMPLEX__</code> macro. <tr> <td>Disambiguate the storage class of some compound literals</td> <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2819.pdf">N2819</a></td> - <td class="unknown" align="center">Unknown</td> + <td class="none" align="center">No</td> </tr> <tr> <td>Add annotations for unreachable control flow v2</td> |