From a2d88a803d347084c27545d9a2727055a4ab77be Mon Sep 17 00:00:00 2001 From: gitoleg Date: Sat, 23 Sep 2023 14:40:14 +0300 Subject: [PATCH 1/8] [CIR][IR] Relax get_member verifier for incomplete types --- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 48fe9bc43c1b..14cddccc46af 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -2398,6 +2398,15 @@ LogicalResult MemCpyOp::verify() { return mlir::success(); } +static bool isIncompleteType(mlir::Type typ) { + if (auto ptr = typ.dyn_cast()) + return isIncompleteType(ptr.getPointee()); + else if (auto rec = typ.dyn_cast()) + return !rec.getBody(); + + return false; +} + //===----------------------------------------------------------------------===// // GetMemberOp Definitions //===----------------------------------------------------------------------===// @@ -2410,7 +2419,7 @@ LogicalResult GetMemberOp::verify() { // FIXME: currently we bypass typechecking of incomplete types due to errors // in the codegen process. This should be removed once the codegen is fixed. - if (!recordTy.getBody()) + if (isIncompleteType(recordTy)) return mlir::success(); if (recordTy.getMembers().size() <= getIndex()) @@ -2418,8 +2427,9 @@ LogicalResult GetMemberOp::verify() { // FIXME(cir): member type check is disabled for classes as the codegen for // these still need to be patched. - if (!recordTy.isClass() && - recordTy.getMembers()[getIndex()] != getResultTy().getPointee()) + if (!recordTy.isClass() + && !isIncompleteType(recordTy.getMembers()[getIndex()]) + && recordTy.getMembers()[getIndex()] != getResultTy().getPointee()) return emitError() << "member type mismatch"; return mlir::success(); From 8c2dcd8627336f9a0bad1f9ae3e9f0142d75ea2d Mon Sep 17 00:00:00 2001 From: gitoleg Date: Tue, 26 Sep 2023 13:03:29 +0300 Subject: [PATCH 2/8] added a small test --- clang/test/CIR/CodeGen/struct.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/clang/test/CIR/CodeGen/struct.c b/clang/test/CIR/CodeGen/struct.c index 5df517c3cbcb..79978d0c839e 100644 --- a/clang/test/CIR/CodeGen/struct.c +++ b/clang/test/CIR/CodeGen/struct.c @@ -12,11 +12,18 @@ struct Foo { struct Bar z; }; +// Recursive type +typedef struct Node { + struct Node* next; +} NodeStru; + void baz(void) { struct Bar b; - struct Foo f; + struct Foo f; } +// CHECK-DAG: !ty_22Node22 = !cir.struct +// CHECK-DAG: !ty_22Node221 = !cir.struct} #cir.record.decl.ast> // CHECK-DAG: !ty_22Bar22 = !cir.struct // CHECK-DAG: !ty_22Foo22 = !cir.struct // CHECK-DAG: module {{.*}} { @@ -78,3 +85,8 @@ struct Bar shouldGenerateAndAccessStructArrays(void) { // CHECK-DAG: %[[#DARR:]] = cir.cast(array_to_ptrdecay, %{{.+}} : !cir.ptr>), !cir.ptr // CHECK-DAG: %[[#ELT:]] = cir.ptr_stride(%[[#DARR]] : !cir.ptr, %[[#STRIDE]] : !s32i), !cir.ptr // CHECK-DAG: cir.copy %[[#ELT]] to %{{.+}} : !cir.ptr + +// CHECK-DAG: cir.func @useRecuriveType +void useRecuriveType(NodeStru* a) { + a->next = 0; +} \ No newline at end of file From 85e95a5ca6722ec885a736e3b18bd7c7b8cb1e42 Mon Sep 17 00:00:00 2001 From: gitoleg Date: Tue, 26 Sep 2023 13:12:14 +0300 Subject: [PATCH 3/8] refactor a bit --- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 14cddccc46af..d24bcfd12906 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -2403,7 +2403,6 @@ static bool isIncompleteType(mlir::Type typ) { return isIncompleteType(ptr.getPointee()); else if (auto rec = typ.dyn_cast()) return !rec.getBody(); - return false; } @@ -2427,9 +2426,12 @@ LogicalResult GetMemberOp::verify() { // FIXME(cir): member type check is disabled for classes as the codegen for // these still need to be patched. - if (!recordTy.isClass() - && !isIncompleteType(recordTy.getMembers()[getIndex()]) - && recordTy.getMembers()[getIndex()] != getResultTy().getPointee()) + // Also we bypass the typechecking for the fields of incomplete types. + bool haveToSkipMemberTypeMismatch = + recordTy.isClass() || isIncompleteType(recordTy.getMembers()[getIndex()]); + + if (!haveToSkipMemberTypeMismatch + && recordTy.getMembers()[getIndex()] != getResultTy().getPointee()) return emitError() << "member type mismatch"; return mlir::success(); From 02605d6533c9ab15b1cab56bbd11cf96bdc4aa84 Mon Sep 17 00:00:00 2001 From: gitoleg Date: Tue, 26 Sep 2023 13:26:52 +0300 Subject: [PATCH 4/8] minor changes --- clang/test/CIR/CodeGen/struct.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/test/CIR/CodeGen/struct.c b/clang/test/CIR/CodeGen/struct.c index 79978d0c839e..03b0a85cb271 100644 --- a/clang/test/CIR/CodeGen/struct.c +++ b/clang/test/CIR/CodeGen/struct.c @@ -13,13 +13,13 @@ struct Foo { }; // Recursive type -typedef struct Node { +typedef struct Node { struct Node* next; } NodeStru; void baz(void) { struct Bar b; - struct Foo f; + struct Foo f; } // CHECK-DAG: !ty_22Node22 = !cir.struct @@ -87,6 +87,6 @@ struct Bar shouldGenerateAndAccessStructArrays(void) { // CHECK-DAG: cir.copy %[[#ELT]] to %{{.+}} : !cir.ptr // CHECK-DAG: cir.func @useRecuriveType -void useRecuriveType(NodeStru* a) { +void useRecuriveType(NodeStru* a) { a->next = 0; -} \ No newline at end of file +} From 51fcefa7af9efaca707ae185555c4dd7c6303d26 Mon Sep 17 00:00:00 2001 From: gitoleg Date: Tue, 26 Sep 2023 13:35:57 +0300 Subject: [PATCH 5/8] updated test --- clang/test/CIR/CodeGen/struct.c | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/test/CIR/CodeGen/struct.c b/clang/test/CIR/CodeGen/struct.c index 03b0a85cb271..9078d4f0a452 100644 --- a/clang/test/CIR/CodeGen/struct.c +++ b/clang/test/CIR/CodeGen/struct.c @@ -87,6 +87,7 @@ struct Bar shouldGenerateAndAccessStructArrays(void) { // CHECK-DAG: cir.copy %[[#ELT]] to %{{.+}} : !cir.ptr // CHECK-DAG: cir.func @useRecuriveType +// CHECK-DAG: cir.get_member {{%.}}[0] {name = "next"} : !cir.ptr -> !cir.ptr> void useRecuriveType(NodeStru* a) { a->next = 0; } From 12a23c7391c41ea56ce6e63e070b09700752f21c Mon Sep 17 00:00:00 2001 From: gitoleg Date: Wed, 27 Sep 2023 09:35:52 +0300 Subject: [PATCH 6/8] minor fixes after review --- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 4 ++-- clang/test/CIR/CodeGen/struct.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index d24bcfd12906..b6918f1b4cfa 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -2427,10 +2427,10 @@ LogicalResult GetMemberOp::verify() { // FIXME(cir): member type check is disabled for classes as the codegen for // these still need to be patched. // Also we bypass the typechecking for the fields of incomplete types. - bool haveToSkipMemberTypeMismatch = + bool shouldSkipMemberTypeMismatch = recordTy.isClass() || isIncompleteType(recordTy.getMembers()[getIndex()]); - if (!haveToSkipMemberTypeMismatch + if (!shouldSkipMemberTypeMismatch && recordTy.getMembers()[getIndex()] != getResultTy().getPointee()) return emitError() << "member type mismatch"; diff --git a/clang/test/CIR/CodeGen/struct.c b/clang/test/CIR/CodeGen/struct.c index 9078d4f0a452..b3f19d8cb759 100644 --- a/clang/test/CIR/CodeGen/struct.c +++ b/clang/test/CIR/CodeGen/struct.c @@ -14,7 +14,7 @@ struct Foo { // Recursive type typedef struct Node { - struct Node* next; + struct Node* next; } NodeStru; void baz(void) { From 961f9e57514795f4e2052755ae0c103c276b3327 Mon Sep 17 00:00:00 2001 From: gitoleg Date: Wed, 27 Sep 2023 09:38:34 +0300 Subject: [PATCH 7/8] one more fix --- clang/test/CIR/CodeGen/struct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/CIR/CodeGen/struct.c b/clang/test/CIR/CodeGen/struct.c index b3f19d8cb759..cdc9be3cf8a9 100644 --- a/clang/test/CIR/CodeGen/struct.c +++ b/clang/test/CIR/CodeGen/struct.c @@ -89,5 +89,5 @@ struct Bar shouldGenerateAndAccessStructArrays(void) { // CHECK-DAG: cir.func @useRecuriveType // CHECK-DAG: cir.get_member {{%.}}[0] {name = "next"} : !cir.ptr -> !cir.ptr> void useRecuriveType(NodeStru* a) { - a->next = 0; + a->next = 0; } From d336ddad73346304256542b6a46d54079c90a046 Mon Sep 17 00:00:00 2001 From: gitoleg Date: Wed, 27 Sep 2023 10:27:05 +0300 Subject: [PATCH 8/8] typo fixed --- clang/test/CIR/CodeGen/struct.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/CIR/CodeGen/struct.c b/clang/test/CIR/CodeGen/struct.c index cdc9be3cf8a9..47680ab4486d 100644 --- a/clang/test/CIR/CodeGen/struct.c +++ b/clang/test/CIR/CodeGen/struct.c @@ -86,8 +86,8 @@ struct Bar shouldGenerateAndAccessStructArrays(void) { // CHECK-DAG: %[[#ELT:]] = cir.ptr_stride(%[[#DARR]] : !cir.ptr, %[[#STRIDE]] : !s32i), !cir.ptr // CHECK-DAG: cir.copy %[[#ELT]] to %{{.+}} : !cir.ptr -// CHECK-DAG: cir.func @useRecuriveType +// CHECK-DAG: cir.func @useRecursiveType // CHECK-DAG: cir.get_member {{%.}}[0] {name = "next"} : !cir.ptr -> !cir.ptr> -void useRecuriveType(NodeStru* a) { +void useRecursiveType(NodeStru* a) { a->next = 0; }