Skip to content

Commit 4263e7b

Browse files
authored
Merge pull request swiftlang#31362 from hlopko/static-vars
[CxxInterop] Add tests for static variables
2 parents e21439b + 6e50c91 commit 4263e7b

File tree

6 files changed

+304
-0
lines changed

6 files changed

+304
-0
lines changed

test/Interop/Cxx/static/Inputs/module.modulemap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
module StaticVar {
2+
header "static-var.h"
3+
}
4+
15
module StaticLocalVar {
26
header "static-local-var.h"
37
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
int makeStaticVar() { return 64; }
2+
int makeStaticConst() { return 128; }
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
static int staticVar = 2;
2+
inline void setStaticVarFromCxx(int newVal) { staticVar = newVal; }
3+
inline int getStaticVarFromCxx() { return staticVar; }
4+
5+
inline int inlineMakeStaticVar() { return 8; }
6+
static int staticVarInlineInit = inlineMakeStaticVar();
7+
8+
int makeStaticVar();
9+
static int staticVarInit = makeStaticVar();
10+
11+
static const int staticConst = 4;
12+
13+
inline int inlineMakeStaticConst() { return 16; }
14+
static const int staticConstInlineInit = inlineMakeStaticConst();
15+
16+
int makeStaticConst();
17+
static const int staticConstInit = makeStaticConst();
18+
19+
constexpr int makeStaticConstexpr() { return 32; }
20+
static constexpr int staticConstexpr = makeStaticConstexpr();
21+
22+
class NonTrivial {
23+
public:
24+
explicit NonTrivial() : val(-1) {}
25+
explicit NonTrivial(int val) : val(val) {}
26+
constexpr NonTrivial(int val, int val2) : val(val + val2) {}
27+
int val;
28+
};
29+
30+
static NonTrivial staticNonTrivial = NonTrivial(1024);
31+
inline void setstaticNonTrivialFromCxx(int newVal) {
32+
staticNonTrivial = NonTrivial(newVal);
33+
}
34+
inline NonTrivial *getstaticNonTrivialFromCxx() { return &staticNonTrivial; }
35+
36+
static const NonTrivial staticConstNonTrivial = NonTrivial(2048);
37+
inline const NonTrivial *getstaticConstNonTrivialFromCxx() {
38+
return &staticConstNonTrivial;
39+
}
40+
41+
static constexpr NonTrivial staticConstexprNonTrivial = NonTrivial(4096, 4096);
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// RUN: %target-swift-emit-ir -I %S/Inputs -enable-cxx-interop %s | %FileCheck %s
2+
3+
import StaticVar
4+
5+
public func initStaticVars() -> CInt {
6+
return staticVar + staticVarInit + staticVarInlineInit + staticConst + staticConstInit
7+
+ staticConstInlineInit + staticConstexpr + staticNonTrivial.val + staticConstNonTrivial.val
8+
+ staticConstexprNonTrivial.val
9+
}
10+
11+
// CHECK: @{{_ZL9staticVar|staticVar}} = internal global i32 2, align 4
12+
// CHECK: @{{_ZL13staticVarInit|staticVarInit}} = internal global i32 0, align 4
13+
// CHECK: @{{_ZL19staticVarInlineInit|staticVarInlineInit}} = internal global i32 0, align 4
14+
// CHECK: @{{_ZL11staticConst|staticConst}} = internal constant i32 4, align 4
15+
// CHECK: @{{_ZL15staticConstInit|staticConstInit}} = internal global i32 0, align 4
16+
// CHECK: @{{_ZL21staticConstInlineInit|staticConstInlineInit}} = internal global i32 0, align 4
17+
// CHECK: @{{_ZL15staticConstexpr|staticConstexpr}} = internal constant i32 32, align 4
18+
// CHECK: @{{_ZL16staticNonTrivial|staticNonTrivial}} = internal global %class.NonTrivial zeroinitializer, align 4
19+
// CHECK: @{{_ZL21staticConstNonTrivial|staticConstNonTrivial}} = internal global %class.NonTrivial zeroinitializer, align 4
20+
// CHECK: @{{_ZL25staticConstexprNonTrivial|staticConstexprNonTrivial}} = internal constant %class.NonTrivial { i32 8192 }, align 4
21+
22+
// CHECK: define internal void @{{__cxx_global_var_init|"\?\?__EstaticVarInit@@YAXXZ"}}()
23+
// CHECK: %call = call i32 @{{_Z13makeStaticVarv|"\?makeStaticVar@@YAHXZ"}}()
24+
// CHECK: store i32 %call, i32* @{{_ZL13staticVarInit|staticVarInit}}, align 4
25+
26+
// CHECK: declare{{( dso_local)?}} i32 @{{_Z13makeStaticVarv|"\?makeStaticVar@@YAHXZ"}}()
27+
28+
// CHECK: define internal void @{{__cxx_global_var_init.1|"\?\?__EstaticVarInlineInit@@YAXXZ"}}()
29+
// CHECK: %call = call i32 @{{_Z19inlineMakeStaticVarv|"\?inlineMakeStaticVar@@YAHXZ"}}()
30+
// CHECK: store i32 %call, i32* @{{_ZL19staticVarInlineInit|staticVarInlineInit}}, align 4
31+
32+
// CHECK: define linkonce_odr{{( dso_local)?}} i32 @{{_Z19inlineMakeStaticVarv|"\?inlineMakeStaticVar@@YAHXZ"}}()
33+
// CHECK: ret i32 8
34+
35+
// CHECK: define internal void @{{__cxx_global_var_init.2|"\?\?__EstaticConstInit@@YAXXZ"}}()
36+
// CHECK: %call = call i32 @{{_Z15makeStaticConstv|"\?makeStaticConst@@YAHXZ"}}()
37+
// CHECK: store i32 %call, i32* @{{_ZL15staticConstInit|staticConstInit}}, align 4
38+
39+
// CHECK: declare{{( dso_local)?}} i32 @{{_Z15makeStaticConstv|"\?makeStaticConst@@YAHXZ"}}()
40+
41+
// CHECK: define internal void @{{__cxx_global_var_init.3|"\?\?__EstaticConstInlineInit@@YAXXZ"}}()
42+
// CHECK: %call = call i32 @{{_Z21inlineMakeStaticConstv|"\?inlineMakeStaticConst@@YAHXZ"}}()
43+
// CHECK: store i32 %call, i32* @{{_ZL21staticConstInlineInit|staticConstInlineInit}}, align 4
44+
45+
// CHECK: define linkonce_odr{{( dso_local)?}} i32 @{{_Z21inlineMakeStaticConstv|"\?inlineMakeStaticConst@@YAHXZ"}}()
46+
// CHECK: ret i32 16
47+
48+
// CHECK: define internal void @{{__cxx_global_var_init.4|"\?\?__EstaticNonTrivial@@YAXXZ"}}()
49+
// CHECK: call {{void @_ZN10NonTrivialC[12]Ei\(%class.NonTrivial\* @_ZL16staticNonTrivial, i32 1024\)|%class.NonTrivial\* @"\?\?0NonTrivial@@QEAA@H@Z"\(%class.NonTrivial\* @staticNonTrivial, i32 1024\)}}
50+
51+
// CHECK: define internal void @{{__cxx_global_var_init.5|"\?\?__EstaticConstNonTrivial@@YAXXZ"}}()
52+
// CHECK: call {{void @_ZN10NonTrivialC[12]Ei\(%class.NonTrivial\* @_ZL21staticConstNonTrivial, i32 2048\)|%class.NonTrivial\* @"\?\?0NonTrivial@@QEAA@H@Z"\(%class.NonTrivial\* @staticConstNonTrivial, i32 2048\)}}
53+
54+
public func readStaticVar() -> CInt {
55+
return staticVar
56+
}
57+
58+
// CHECK: define {{(protected |dllexport )?}}swiftcc i32 @"$s4main13readStaticVars5Int32VyF"()
59+
// CHECK: [[VALUE:%.*]] = load i32, i32* getelementptr inbounds (%Ts5Int32V, %Ts5Int32V* bitcast (i32* @{{_ZL9staticVar|staticVar}} to %Ts5Int32V*), i32 0, i32 0), align 4
60+
// CHECK: ret i32 [[VALUE]]
61+
62+
public func writeStaticVar(_ v: CInt) {
63+
staticVar = v
64+
}
65+
66+
// CHECK: define {{(protected |dllexport )?}}swiftcc void @"$s4main14writeStaticVaryys5Int32VF"(i32 %0)
67+
// CHECK: store i32 %0, i32* getelementptr inbounds (%Ts5Int32V, %Ts5Int32V* bitcast (i32* @{{_ZL9staticVar|staticVar}} to %Ts5Int32V*), i32 0, i32 0), align 4
68+
69+
public func readStaticNonTrivial() -> NonTrivial {
70+
return staticNonTrivial
71+
}
72+
73+
// CHECK: define {{(protected |dllexport )?}}swiftcc i32 @"$s4main20readStaticNonTrivialSo0dE0VyF"()
74+
// CHECK: [[VALUE:%.*]] = load i32, i32* getelementptr inbounds (%TSo10NonTrivialV, %TSo10NonTrivialV* bitcast (%class.NonTrivial* @{{_ZL16staticNonTrivial|staticNonTrivial}} to %TSo10NonTrivialV*), i32 0, i32 0, i32 0), align 4
75+
// CHECK: ret i32 [[VALUE]]
76+
77+
public func writeStaticNonTrivial(_ i: NonTrivial) {
78+
staticNonTrivial = i
79+
}
80+
81+
// CHECK: define {{(protected |dllexport )?}}swiftcc void @"$s4main21writeStaticNonTrivialyySo0dE0VF"(i32 %0)
82+
// CHECK: store i32 %0, i32* getelementptr inbounds (%TSo10NonTrivialV, %TSo10NonTrivialV* bitcast (%class.NonTrivial* @{{_ZL16staticNonTrivial|staticNonTrivial}} to %TSo10NonTrivialV*), i32 0, i32 0, i32 0), align 4
83+
84+
func modifyInout(_ c: inout CInt) {
85+
c = 42
86+
}
87+
88+
public func passingVarAsInout() {
89+
modifyInout(&staticVar)
90+
}
91+
// CHECK: define {{(protected |dllexport )?}}swiftcc void @"$s4main17passingVarAsInoutyyF"()
92+
// CHECK: call swiftcc void @"$s4main11modifyInoutyys5Int32VzF"(%Ts5Int32V* nocapture dereferenceable(4) bitcast (i32* @{{_ZL9staticVar|staticVar}} to %Ts5Int32V*))
93+
94+
// CHECK: define internal void @_GLOBAL__sub_I__swift_imported_modules_()
95+
// CHECK: call void @{{__cxx_global_var_init|"\?\?__EstaticVarInit@@YAXXZ"}}()
96+
// CHECK: call void @{{__cxx_global_var_init.1|"\?\?__EstaticVarInlineInit@@YAXXZ"}}()
97+
// CHECK: call void @{{__cxx_global_var_init.2|"\?\?__EstaticConstInit@@YAXXZ"}}()
98+
// CHECK: call void @{{__cxx_global_var_init.3|"\?\?__EstaticConstInlineInit@@YAXXZ"}}()
99+
// CHECK: call void @{{__cxx_global_var_init.4|"\?\?__EstaticNonTrivial@@YAXXZ"}}()
100+
// CHECK: call void @{{__cxx_global_var_init.5|"\?\?__EstaticConstNonTrivial@@YAXXZ"}}()
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// RUN: %target-swift-emit-sil -I %S/Inputs -enable-cxx-interop %s | %FileCheck %s
2+
3+
import StaticVar
4+
5+
func initStaticVars() -> CInt {
6+
return staticVar + staticVarInit + staticVarInlineInit + staticConst + staticConstInit
7+
+ staticConstInlineInit + staticConstexpr + staticNonTrivial.val + staticConstNonTrivial.val
8+
+ staticConstexprNonTrivial.val
9+
}
10+
11+
// CHECK: sil_global @staticVar : $Int32
12+
// CHECK: sil_global @staticVarInit : $Int32
13+
// CHECK: sil_global @staticVarInlineInit : $Int32
14+
// CHECK: sil_global [let] @staticConst : $Int32
15+
// CHECK: sil_global [let] @staticConstInit : $Int32
16+
// CHECK: sil_global [let] @staticConstInlineInit : $Int32
17+
// CHECK: sil_global [let] @staticConstexpr : $Int32
18+
// CHECK: sil_global @staticNonTrivial : $NonTrivial
19+
// CHECK: sil_global [let] @staticConstNonTrivial : $NonTrivial
20+
// CHECK: sil_global [let] @staticConstexprNonTrivial : $NonTrivial
21+
22+
func readStaticVar() -> CInt {
23+
return staticVar
24+
}
25+
26+
// CHECK: sil hidden @$s4main13readStaticVars5Int32VyF : $@convention(thin) () -> Int32
27+
// CHECK: [[ADDR:%.*]] = global_addr @staticVar : $*Int32
28+
// CHECK: [[ACCESS:%.*]] = begin_access [read] [dynamic] [[ADDR]] : $*Int32
29+
// CHECK: [[VALUE:%.*]] = load [[ACCESS]] : $*Int32
30+
// CHECK: return [[VALUE]] : $Int32
31+
32+
func writeStaticVar(_ v: CInt) {
33+
staticVar = v
34+
}
35+
36+
// CHECK: sil hidden @$s4main14writeStaticVaryys5Int32VF : $@convention(thin) (Int32) -> ()
37+
// CHECK: [[ADDR:%.*]] = global_addr @staticVar : $*Int32
38+
// CHECK: [[ACCESS:%.*]] = begin_access [modify] [dynamic] [[ADDR]] : $*Int32
39+
// CHECK: store %0 to [[ACCESS]] : $*Int32
40+
41+
func readStaticNonTrivial() -> NonTrivial {
42+
return staticNonTrivial
43+
}
44+
45+
// CHECK: sil hidden @$s4main20readStaticNonTrivialSo0dE0VyF : $@convention(thin) () -> NonTrivial
46+
// CHECK: [[ADDR:%.*]] = global_addr @staticNonTrivial : $*NonTrivial
47+
// CHECK: [[ACCESS:%.*]] = begin_access [read] [dynamic] [[ADDR]] : $*NonTrivial
48+
// CHECK: [[VALUE:%.*]] = load [[ACCESS]] : $*NonTrivial
49+
// CHECK: return [[VALUE]] : $NonTrivial
50+
51+
func writeStaticNonTrivial(_ i: NonTrivial) {
52+
staticNonTrivial = i
53+
}
54+
55+
// CHECK: sil hidden @$s4main21writeStaticNonTrivialyySo0dE0VF : $@convention(thin) (NonTrivial) -> ()
56+
// CHECK: [[ADDR:%.*]] = global_addr @staticNonTrivial : $*NonTrivial
57+
// CHECK: [[ACCESS:%.*]] = begin_access [modify] [dynamic] [[ADDR]] : $*NonTrivial
58+
// CHECK: store %0 to [[ACCESS]] : $*NonTrivial
59+
60+
func modifyInout(_ c: inout CInt) {
61+
c = 42
62+
}
63+
64+
func passingVarAsInout() {
65+
modifyInout(&staticVar)
66+
}
67+
68+
// CHECK: sil hidden @$s4main17passingVarAsInoutyyF : $@convention(thin) () -> ()
69+
// CHECK: [[ADDR:%.*]] = global_addr @staticVar : $*Int32
70+
// CHECK: [[ACCESS:%.*]] = begin_access [modify] [dynamic] [[ADDR]] : $*Int32
71+
// CHECK: [[FUNC:%.*]] = function_ref @$s4main11modifyInoutyys5Int32VzF : $@convention(thin) (@inout Int32) -> ()
72+
// CHECK: apply [[FUNC]]([[ACCESS]]) : $@convention(thin) (@inout Int32) -> ()
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-clang -c %S/Inputs/static-var.cc -I %S/Inputs -o %t/static-var.o -std=c++17
3+
// RUN: %target-build-swift %s -I %S/Inputs -o %t/statics %t/static-var.o -Xfrontend -enable-cxx-interop -Xcc -std=c++17
4+
// RUN: %target-codesign %t/statics
5+
// RUN: %target-run %t/statics
6+
//
7+
// REQUIRES: executable_test
8+
9+
import StaticVar
10+
import StdlibUnittest
11+
12+
var StaticVarTestSuite = TestSuite("StaticVarTestSuite")
13+
14+
StaticVarTestSuite.test("static-int") {
15+
expectEqual(2, staticVar)
16+
}
17+
18+
StaticVarTestSuite.test("static-int-write-from-swift") {
19+
expectNotEqual(3, staticVar)
20+
staticVar = 3
21+
expectEqual(3, getStaticVarFromCxx())
22+
}
23+
24+
StaticVarTestSuite.test("static-int") {
25+
expectNotEqual(4, staticVar)
26+
setStaticVarFromCxx(4)
27+
expectEqual(4, staticVar)
28+
}
29+
30+
StaticVarTestSuite.test("static-int-inline-init") {
31+
expectEqual(8, staticVarInlineInit)
32+
}
33+
34+
StaticVarTestSuite.test("static-int-init") {
35+
expectEqual(64, staticVarInit)
36+
}
37+
38+
StaticVarTestSuite.test("static-const-int") {
39+
expectEqual(4, staticConst)
40+
}
41+
42+
StaticVarTestSuite.test("static-const-int-inline-init") {
43+
expectEqual(16, staticConstInlineInit)
44+
}
45+
46+
StaticVarTestSuite.test("static-const-int-init") {
47+
expectEqual(128, staticConstInit)
48+
}
49+
50+
StaticVarTestSuite.test("static-constexpr-int") {
51+
expectEqual(32, staticConstexpr)
52+
}
53+
54+
StaticVarTestSuite.test("static-non-trivial") {
55+
expectEqual(1024, staticNonTrivial.val)
56+
}
57+
58+
StaticVarTestSuite.test("static-non-trivial-address") {
59+
expectEqual(getstaticNonTrivialFromCxx(), &staticNonTrivial)
60+
}
61+
62+
StaticVarTestSuite.test("static-non-trivial-write-from-cxx") {
63+
expectNotEqual(1025, staticNonTrivial.val)
64+
setstaticNonTrivialFromCxx(1025)
65+
expectEqual(1025, staticNonTrivial.val)
66+
}
67+
68+
StaticVarTestSuite.test("static-non-trivial-write-from-swift") {
69+
expectNotEqual(1026, staticNonTrivial.val)
70+
//TODO: Delete `NonTrivial()` adn use `NonTrivial(int)` constructor once
71+
// apple/swift/pull/30630 is merged.
72+
staticNonTrivial = NonTrivial()
73+
staticNonTrivial.val = 1026
74+
expectEqual(1026, getstaticNonTrivialFromCxx().pointee.val)
75+
}
76+
77+
StaticVarTestSuite.test("static-const-non-trivial") {
78+
expectEqual(2048, staticConstNonTrivial.val)
79+
}
80+
81+
StaticVarTestSuite.test("static-constexpr-non-trivial") {
82+
expectEqual(8192, staticConstexprNonTrivial.val)
83+
}
84+
85+
runAllTests()

0 commit comments

Comments
 (0)