Skip to content

Commit

Permalink
More test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
dwblaikie committed Nov 12, 2024
1 parent 28b4f07 commit 7bda9ba
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 87 deletions.
117 changes: 117 additions & 0 deletions toolchain/check/testdata/class/virtual_modifiers.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,26 @@ fn F() {
var v: Modifiers.Base = {};
}

// --- init_member.carbon

package InitMember;

base class Base {
var m: i32;

virtual fn F();
}

fn F() {
var i: i32 = 3;
// TODO: These should initialize element1 (.m), not element0 (the vptr)
var b1: Base = {.m = i};
var b2: Base = {.m = 3};

// This one is good, though.
b1.m = 4;
}

// CHECK:STDOUT: --- modifiers.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
Expand Down Expand Up @@ -246,3 +266,100 @@ fn F() {
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- init_member.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %Base: type = class_type @Base [template]
// CHECK:STDOUT: %Int32.type: type = fn_type @Int32 [template]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [template]
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
// CHECK:STDOUT: %.1: type = unbound_element_type %Base, i32 [template]
// CHECK:STDOUT: %F.type.1: type = fn_type @F.1 [template]
// CHECK:STDOUT: %F.1: %F.type.1 = struct_value () [template]
// CHECK:STDOUT: %.2: type = ptr_type <vtable> [template]
// CHECK:STDOUT: %.3: type = struct_type {.<vptr>: %.2, .m: i32} [template]
// CHECK:STDOUT: %.4: <witness> = complete_type_witness %.3 [template]
// CHECK:STDOUT: %F.type.2: type = fn_type @F.2 [template]
// CHECK:STDOUT: %F.2: %F.type.2 = struct_value () [template]
// CHECK:STDOUT: %.5: i32 = int_value 3 [template]
// CHECK:STDOUT: %.6: type = ptr_type %.3 [template]
// CHECK:STDOUT: %.7: type = struct_type {.m: i32} [template]
// CHECK:STDOUT: %.8: i32 = int_value 4 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [template] {
// CHECK:STDOUT: .Int32 = %import_ref
// CHECK:STDOUT: import Core//prelude
// CHECK:STDOUT: import Core//prelude/...
// CHECK:STDOUT: }
// CHECK:STDOUT: %import_ref: %Int32.type = import_ref Core//prelude/types, inst+15, loaded [template = constants.%Int32]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {
// CHECK:STDOUT: .Core = imports.%Core
// CHECK:STDOUT: .Base = %Base.decl
// CHECK:STDOUT: .F = %F.decl
// CHECK:STDOUT: }
// CHECK:STDOUT: %Core.import = import Core
// CHECK:STDOUT: %Base.decl: type = class_decl @Base [template = constants.%Base] {} {}
// CHECK:STDOUT: %F.decl: %F.type.2 = fn_decl @F.2 [template = constants.%F.2] {} {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @Base {
// CHECK:STDOUT: %int.make_type_32: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc5_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
// CHECK:STDOUT: %.loc5_10.2: type = converted %int.make_type_32, %.loc5_10.1 [template = i32]
// CHECK:STDOUT: %.loc5_8: %.1 = field_decl m, element1 [template]
// CHECK:STDOUT: %F.decl: %F.type.1 = fn_decl @F.1 [template = constants.%F.1] {} {}
// CHECK:STDOUT: %.loc8: <witness> = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Base
// CHECK:STDOUT: .m = %.loc5_8
// CHECK:STDOUT: .F = %F.decl
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
// CHECK:STDOUT:
// CHECK:STDOUT: virtual fn @F.1();
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F.2() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %int.make_type_32: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc11_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
// CHECK:STDOUT: %.loc11_10.2: type = converted %int.make_type_32, %.loc11_10.1 [template = i32]
// CHECK:STDOUT: %i.var: ref i32 = var i
// CHECK:STDOUT: %i: ref i32 = bind_name i, %i.var
// CHECK:STDOUT: %.loc11_16: i32 = int_value 3 [template = constants.%.5]
// CHECK:STDOUT: assign %i.var, %.loc11_16
// CHECK:STDOUT: %Base.ref.loc13: type = name_ref Base, file.%Base.decl [template = constants.%Base]
// CHECK:STDOUT: %b1.var: ref %Base = var b1
// CHECK:STDOUT: %b1: ref %Base = bind_name b1, %b1.var
// CHECK:STDOUT: %i.ref: ref i32 = name_ref i, %i
// CHECK:STDOUT: %.loc13_25.1: %.7 = struct_literal (%i.ref)
// CHECK:STDOUT: %.loc13_24: i32 = bind_value %i.ref
// CHECK:STDOUT: %.loc13_25.2: ref i32 = class_element_access %b1.var, element0
// CHECK:STDOUT: %.loc13_25.3: init i32 = initialize_from %.loc13_24 to %.loc13_25.2
// CHECK:STDOUT: %.loc13_25.4: init %Base = class_init (<error>, %.loc13_25.3), %b1.var
// CHECK:STDOUT: %.loc13_26: init %Base = converted %.loc13_25.1, %.loc13_25.4
// CHECK:STDOUT: assign %b1.var, %.loc13_26
// CHECK:STDOUT: %Base.ref.loc14: type = name_ref Base, file.%Base.decl [template = constants.%Base]
// CHECK:STDOUT: %b2.var: ref %Base = var b2
// CHECK:STDOUT: %b2: ref %Base = bind_name b2, %b2.var
// CHECK:STDOUT: %.loc14_24: i32 = int_value 3 [template = constants.%.5]
// CHECK:STDOUT: %.loc14_25.1: %.7 = struct_literal (%.loc14_24)
// CHECK:STDOUT: %.loc14_25.2: ref i32 = class_element_access %b2.var, element0
// CHECK:STDOUT: %.loc14_25.3: init i32 = initialize_from %.loc14_24 to %.loc14_25.2 [template = constants.%.5]
// CHECK:STDOUT: %.loc14_25.4: init %Base = class_init (<error>, %.loc14_25.3), %b2.var [template = <error>]
// CHECK:STDOUT: %.loc14_26: init %Base = converted %.loc14_25.1, %.loc14_25.4 [template = <error>]
// CHECK:STDOUT: assign %b2.var, %.loc14_26
// CHECK:STDOUT: %b1.ref: ref %Base = name_ref b1, %b1
// CHECK:STDOUT: %m.ref: %.1 = name_ref m, @Base.%.loc5_8 [template = @Base.%.loc5_8]
// CHECK:STDOUT: %.loc20_5: ref i32 = class_element_access %b1.ref, element1
// CHECK:STDOUT: %.loc20_10: i32 = int_value 4 [template = constants.%.8]
// CHECK:STDOUT: assign %.loc20_5, %.loc20_10
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
90 changes: 3 additions & 87 deletions toolchain/lower/testdata/class/virtual.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -52,93 +52,9 @@ base class Base {

fn Fn() {
var i: i32 = 3;
// TODO: make `i` initialize `m` here (it currently initializes the vptr instead)
var v: Base = {.m = i};
// var v: Base = {.m = 3}; // crashes
// TODO: fix crash here
// var v: Base = {.m = 3};
v.m = 5;
}

// CHECK:STDOUT: ; ModuleID = 'classes.carbon'
// CHECK:STDOUT: source_filename = "classes.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: declare void @_CFn.Intermediate.Classes()
// CHECK:STDOUT:
// CHECK:STDOUT: declare void @_CFn.Derived.Classes()
// CHECK:STDOUT:
// CHECK:STDOUT: !llvm.module.flags = !{!0, !1}
// CHECK:STDOUT: !llvm.dbg.cu = !{!2}
// CHECK:STDOUT:
// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
// CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
// CHECK:STDOUT: !3 = !DIFile(filename: "classes.carbon", directory: "")
// CHECK:STDOUT: ; ModuleID = 'create.carbon'
// CHECK:STDOUT: source_filename = "create.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: define void @_CCreate.Create() !dbg !4 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %b.var = alloca {}, align 8, !dbg !7
// CHECK:STDOUT: %i.var = alloca { ptr, {} }, align 8, !dbg !8
// CHECK:STDOUT: %d.var = alloca { { ptr, {} } }, align 8, !dbg !9
// CHECK:STDOUT: ret void, !dbg !10
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: define void @_CUse.Create(ptr %v) !dbg !11 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: call void @_CFn.Intermediate.Classes(), !dbg !12
// CHECK:STDOUT: ret void, !dbg !13
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: declare void @_CFn.Intermediate.Classes()
// CHECK:STDOUT:
// CHECK:STDOUT: !llvm.module.flags = !{!0, !1}
// CHECK:STDOUT: !llvm.dbg.cu = !{!2}
// CHECK:STDOUT:
// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
// CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
// CHECK:STDOUT: !3 = !DIFile(filename: "create.carbon", directory: "")
// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Create", linkageName: "_CCreate.Create", scope: null, file: !3, line: 6, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
// CHECK:STDOUT: !6 = !{}
// CHECK:STDOUT: !7 = !DILocation(line: 7, column: 7, scope: !4)
// CHECK:STDOUT: !8 = !DILocation(line: 8, column: 7, scope: !4)
// CHECK:STDOUT: !9 = !DILocation(line: 9, column: 7, scope: !4)
// CHECK:STDOUT: !10 = !DILocation(line: 6, column: 1, scope: !4)
// CHECK:STDOUT: !11 = distinct !DISubprogram(name: "Use", linkageName: "_CUse.Create", scope: null, file: !3, line: 12, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !12 = !DILocation(line: 13, column: 3, scope: !11)
// CHECK:STDOUT: !13 = !DILocation(line: 12, column: 1, scope: !11)
// CHECK:STDOUT: ; ModuleID = 'member_init.carbon'
// CHECK:STDOUT: source_filename = "member_init.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: declare void @_CFn.Base.MemberInit()
// CHECK:STDOUT:
// CHECK:STDOUT: define void @_CFn.MemberInit() !dbg !4 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %i.var = alloca i32, align 4, !dbg !7
// CHECK:STDOUT: store i32 3, ptr %i.var, align 4, !dbg !8
// CHECK:STDOUT: %v.var = alloca { ptr, i32 }, align 8, !dbg !9
// CHECK:STDOUT: %.loc11_23 = load i32, ptr %i.var, align 4, !dbg !10
// CHECK:STDOUT: %.loc11_24.2.vptr = getelementptr inbounds nuw { ptr, i32 }, ptr %v.var, i32 0, i32 0, !dbg !11
// CHECK:STDOUT: store i32 %.loc11_23, ptr %.loc11_24.2.vptr, align 4, !dbg !11
// CHECK:STDOUT: %.loc13_4.m = getelementptr inbounds nuw { ptr, i32 }, ptr %v.var, i32 0, i32 1, !dbg !12
// CHECK:STDOUT: store i32 5, ptr %.loc13_4.m, align 4, !dbg !12
// CHECK:STDOUT: ret void, !dbg !13
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: !llvm.module.flags = !{!0, !1}
// CHECK:STDOUT: !llvm.dbg.cu = !{!2}
// CHECK:STDOUT:
// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
// CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
// CHECK:STDOUT: !3 = !DIFile(filename: "member_init.carbon", directory: "")
// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Fn", linkageName: "_CFn.MemberInit", scope: null, file: !3, line: 9, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
// CHECK:STDOUT: !6 = !{}
// CHECK:STDOUT: !7 = !DILocation(line: 10, column: 7, scope: !4)
// CHECK:STDOUT: !8 = !DILocation(line: 10, column: 3, scope: !4)
// CHECK:STDOUT: !9 = !DILocation(line: 11, column: 7, scope: !4)
// CHECK:STDOUT: !10 = !DILocation(line: 11, column: 23, scope: !4)
// CHECK:STDOUT: !11 = !DILocation(line: 11, column: 17, scope: !4)
// CHECK:STDOUT: !12 = !DILocation(line: 13, column: 3, scope: !4)
// CHECK:STDOUT: !13 = !DILocation(line: 9, column: 1, scope: !4)

0 comments on commit 7bda9ba

Please sign in to comment.