diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 7e0ef7d15213..d46a643edf3f 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -2461,12 +2461,17 @@ LogicalResult GetMemberOp::verify() { if (!recordTy) return emitError() << "expected pointer to a record type"; + // 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()) + return mlir::success(); + if (recordTy.getMembers().size() <= getIndex()) return emitError() << "member index out of bounds"; - // FIXME(cir): Member type check is disabled for classes and incomplete types - // as the codegen for these still need to be patched. - if (!recordTy.isClass() && !recordTy.getBody() && + // 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()) return emitError() << "member type mismatch"; diff --git a/clang/test/CIR/IR/getmember.cir b/clang/test/CIR/IR/getmember.cir new file mode 100644 index 000000000000..932e4a5b29f5 --- /dev/null +++ b/clang/test/CIR/IR/getmember.cir @@ -0,0 +1,31 @@ +// RUN: cir-opt %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s + +!u16i = !cir.int +!u32i = !cir.int + +!ty_22Class22 = !cir.struct +!ty_22Incomplete22 = !cir.struct +!ty_22Struct22 = !cir.struct + +module { + cir.func @shouldGetStructMember(%arg0 : !cir.ptr) { + // CHECK: cir.get_member %arg0[1] {name = "test"} : !cir.ptr -> !cir.ptr + %0 = cir.get_member %arg0[1] {name = "test"} : !cir.ptr -> !cir.ptr + cir.return + } + + // FIXME: remove bypass once codegen for CIR records is patched. + cir.func @shouldBypassMemberIndexCheckForIncompleteRecords(%arg0 : !cir.ptr) { + // CHECK: cir.get_member %arg0[1] {name = "test"} : !cir.ptr -> !cir.ptr + %0 = cir.get_member %arg0[1] {name = "test"} : !cir.ptr -> !cir.ptr + cir.return + } + + // FIXME: remove bypass once codegen for CIR class records is patched. + cir.func @shouldBypassMemberTypeCheckForClassRecords(%arg0 : !cir.ptr) { + // CHECK: cir.get_member %arg0[1] {name = "test"} : !cir.ptr -> !cir.ptr> + %0 = cir.get_member %arg0[1] {name = "test"} : !cir.ptr -> !cir.ptr> + cir.return + } +} diff --git a/clang/test/CIR/IR/invalid.cir b/clang/test/CIR/IR/invalid.cir index 0ca97dbbcc27..cd5d709e57a4 100644 --- a/clang/test/CIR/IR/invalid.cir +++ b/clang/test/CIR/IR/invalid.cir @@ -522,3 +522,29 @@ module { cir.throw(%11 : !cir.ptr>) // expected-error {{'type_info' symbol attribute missing}} } } + +// ----- + +!u16i = !cir.int +!u32i = !cir.int +!struct = !cir.struct +module { + cir.func @memeber_index_out_of_bounds(%arg0 : !cir.ptr) { + // expected-error@+1 {{member index out of bounds}} + %0 = cir.get_member %arg0[2] {name = "test"} : !cir.ptr -> !cir.ptr + cir.return + } +} + +// ----- + +!u16i = !cir.int +!u32i = !cir.int +!struct = !cir.struct +module { + cir.func @memeber_type_mismatch(%arg0 : !cir.ptr) { + // expected-error@+1 {{member type mismatch}} + %0 = cir.get_member %arg0[0] {name = "test"} : !cir.ptr -> !cir.ptr + cir.return + } +}