aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Ballman <aaron@aaronballman.com>2024-06-24 15:08:16 -0400
committerAaron Ballman <aaron@aaronballman.com>2024-06-24 15:09:20 -0400
commit2ae09052477e1a966afbc5482d88585f95694c53 (patch)
tree94d952e55cbae84f33a9a7c64357a6e2185d4019
parentd6a3bd1325c5c54ef59e8a612451757c86186355 (diff)
downloadllvm-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.c57
-rw-r--r--clang/www/c_status.html2
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>