C++: Test for constant static initializer

This commit is contained in:
Jonas Jensen
2020-03-06 13:54:35 +01:00
parent 3ae1aada37
commit 02f0b89a0d
3 changed files with 370 additions and 0 deletions

View File

@@ -8349,3 +8349,184 @@ perf-regression.cpp:
# 12| Type = [IntType] int
# 12| Value = [Literal] 0
# 12| ValueCategory = prvalue
struct_init.cpp:
# 1| [TopLevelFunction] int handler1(void*)
# 1| params:
# 1| 0: [Parameter] p
# 1| Type = [VoidPointerType] void *
# 2| [TopLevelFunction] int handler2(void*)
# 2| params:
# 2| 0: [Parameter] p
# 2| Type = [VoidPointerType] void *
# 4| [CopyAssignmentOperator] Info& Info::operator=(Info const&)
# 4| params:
#-----| 0: [Parameter] p#0
#-----| Type = [LValueReferenceType] const Info &
# 4| [MoveAssignmentOperator] Info& Info::operator=(Info&&)
# 4| params:
#-----| 0: [Parameter] p#0
#-----| Type = [RValueReferenceType] Info &&
# 16| [TopLevelFunction] void let_info_escape(Info*)
# 16| params:
# 16| 0: [Parameter] info
# 16| Type = [PointerType] Info *
# 16| body: [Block] { ... }
# 17| 0: [ExprStmt] ExprStmt
# 17| 0: [AssignExpr] ... = ...
# 17| Type = [PointerType] Info *
# 17| ValueCategory = lvalue
# 17| 0: [VariableAccess] global_pointer
# 17| Type = [PointerType] Info *
# 17| ValueCategory = lvalue
# 17| 1: [VariableAccess] info
# 17| Type = [PointerType] Info *
# 17| ValueCategory = prvalue(load)
# 18| 1: [ReturnStmt] return ...
# 20| [TopLevelFunction] void declare_static_infos()
# 20| params:
# 20| body: [Block] { ... }
# 21| 0: [DeclStmt] declaration
# 21| 0: [VariableDeclarationEntry] definition of static_infos
# 21| Type = [ArrayType] Info[]
# 21| init: [Initializer] initializer for static_infos
# 21| expr: [ArrayAggregateLiteral] {...}
# 21| Type = [ArrayType] Info[2]
# 21| ValueCategory = prvalue
# 22| [0]: [ClassAggregateLiteral] {...}
# 22| Type = [Struct] Info
# 22| ValueCategory = prvalue
# 22| .name: [ArrayToPointerConversion] array to pointer conversion
# 22| Type = [PointerType] const char *
# 22| ValueCategory = prvalue
# 22| expr: 1
# 22| Type = [ArrayType] const char[2]
# 22| Value = [StringLiteral] "1"
# 22| ValueCategory = lvalue
# 22| .handler: [FunctionAccess] handler1
# 22| Type = [FunctionPointerType] ..(*)(..)
# 22| ValueCategory = prvalue(load)
# 23| [1]: [ClassAggregateLiteral] {...}
# 23| Type = [Struct] Info
# 23| ValueCategory = prvalue
# 23| .name: [ArrayToPointerConversion] array to pointer conversion
# 23| Type = [PointerType] const char *
# 23| ValueCategory = prvalue
# 23| expr: 2
# 23| Type = [ArrayType] const char[2]
# 23| Value = [StringLiteral] "2"
# 23| ValueCategory = lvalue
# 23| .handler: [AddressOfExpr] & ...
# 23| Type = [FunctionPointerType] ..(*)(..)
# 23| ValueCategory = prvalue
# 23| 0: [FunctionAccess] handler2
# 23| Type = [RoutineType] ..()(..)
# 23| ValueCategory = lvalue
# 25| 1: [ExprStmt] ExprStmt
# 25| 0: [FunctionCall] call to let_info_escape
# 25| Type = [VoidType] void
# 25| ValueCategory = prvalue
# 25| 0: [ArrayToPointerConversion] array to pointer conversion
# 25| Type = [PointerType] Info *
# 25| ValueCategory = prvalue
# 25| expr: [VariableAccess] static_infos
# 25| Type = [ArrayType] Info[2]
# 25| ValueCategory = lvalue
# 26| 2: [ReturnStmt] return ...
# 28| [TopLevelFunction] void declare_local_infos()
# 28| params:
# 28| body: [Block] { ... }
# 29| 0: [DeclStmt] declaration
# 29| 0: [VariableDeclarationEntry] definition of local_infos
# 29| Type = [ArrayType] Info[]
# 29| init: [Initializer] initializer for local_infos
# 29| expr: [ArrayAggregateLiteral] {...}
# 29| Type = [ArrayType] Info[2]
# 29| ValueCategory = prvalue
# 30| [0]: [ClassAggregateLiteral] {...}
# 30| Type = [Struct] Info
# 30| ValueCategory = prvalue
# 30| .name: [ArrayToPointerConversion] array to pointer conversion
# 30| Type = [PointerType] const char *
# 30| ValueCategory = prvalue
# 30| expr: 1
# 30| Type = [ArrayType] const char[2]
# 30| Value = [StringLiteral] "1"
# 30| ValueCategory = lvalue
# 30| .handler: [FunctionAccess] handler1
# 30| Type = [FunctionPointerType] ..(*)(..)
# 30| ValueCategory = prvalue(load)
# 31| [1]: [ClassAggregateLiteral] {...}
# 31| Type = [Struct] Info
# 31| ValueCategory = prvalue
# 31| .name: [ArrayToPointerConversion] array to pointer conversion
# 31| Type = [PointerType] const char *
# 31| ValueCategory = prvalue
# 31| expr: 2
# 31| Type = [ArrayType] const char[2]
# 31| Value = [StringLiteral] "2"
# 31| ValueCategory = lvalue
# 31| .handler: [AddressOfExpr] & ...
# 31| Type = [FunctionPointerType] ..(*)(..)
# 31| ValueCategory = prvalue
# 31| 0: [FunctionAccess] handler2
# 31| Type = [RoutineType] ..()(..)
# 31| ValueCategory = lvalue
# 33| 1: [ExprStmt] ExprStmt
# 33| 0: [FunctionCall] call to let_info_escape
# 33| Type = [VoidType] void
# 33| ValueCategory = prvalue
# 33| 0: [ArrayToPointerConversion] array to pointer conversion
# 33| Type = [PointerType] Info *
# 33| ValueCategory = prvalue
# 33| expr: [VariableAccess] local_infos
# 33| Type = [ArrayType] Info[2]
# 33| ValueCategory = lvalue
# 34| 2: [ReturnStmt] return ...
# 36| [TopLevelFunction] void declare_static_runtime_infos(char const*)
# 36| params:
# 36| 0: [Parameter] name1
# 36| Type = [PointerType] const char *
# 36| body: [Block] { ... }
# 37| 0: [DeclStmt] declaration
# 37| 0: [VariableDeclarationEntry] definition of static_infos
# 37| Type = [ArrayType] Info[]
# 37| init: [Initializer] initializer for static_infos
# 37| expr: [ArrayAggregateLiteral] {...}
# 37| Type = [ArrayType] Info[2]
# 37| ValueCategory = prvalue
# 38| [0]: [ClassAggregateLiteral] {...}
# 38| Type = [Struct] Info
# 38| ValueCategory = prvalue
# 38| .name: [VariableAccess] name1
# 38| Type = [PointerType] const char *
# 38| ValueCategory = prvalue(load)
# 38| .handler: [FunctionAccess] handler1
# 38| Type = [FunctionPointerType] ..(*)(..)
# 38| ValueCategory = prvalue(load)
# 39| [1]: [ClassAggregateLiteral] {...}
# 39| Type = [Struct] Info
# 39| ValueCategory = prvalue
# 39| .name: [ArrayToPointerConversion] array to pointer conversion
# 39| Type = [PointerType] const char *
# 39| ValueCategory = prvalue
# 39| expr: 2
# 39| Type = [ArrayType] const char[2]
# 39| Value = [StringLiteral] "2"
# 39| ValueCategory = lvalue
# 39| .handler: [AddressOfExpr] & ...
# 39| Type = [FunctionPointerType] ..(*)(..)
# 39| ValueCategory = prvalue
# 39| 0: [FunctionAccess] handler2
# 39| Type = [RoutineType] ..()(..)
# 39| ValueCategory = lvalue
# 41| 1: [ExprStmt] ExprStmt
# 41| 0: [FunctionCall] call to let_info_escape
# 41| Type = [VoidType] void
# 41| ValueCategory = prvalue
# 41| 0: [ArrayToPointerConversion] array to pointer conversion
# 41| Type = [PointerType] Info *
# 41| ValueCategory = prvalue
# 41| expr: [VariableAccess] static_infos
# 41| Type = [ArrayType] Info[2]
# 41| ValueCategory = lvalue
# 42| 2: [ReturnStmt] return ...

View File

@@ -6272,3 +6272,150 @@ perf-regression.cpp:
# 9| v9_7(void) = UnmodeledUse : mu*
# 9| v9_8(void) = AliasedUse : ~mu9_4
# 9| v9_9(void) = ExitFunction :
struct_init.cpp:
# 16| void let_info_escape(Info*)
# 16| Block 0
# 16| v16_1(void) = EnterFunction :
# 16| mu16_2(unknown) = AliasedDefinition :
# 16| mu16_3(unknown) = InitializeNonLocal :
# 16| mu16_4(unknown) = UnmodeledDefinition :
# 16| r16_5(glval<Info *>) = VariableAddress[info] :
# 16| mu16_6(Info *) = InitializeParameter[info] : &:r16_5
# 16| r16_7(Info *) = Load : &:r16_5, ~mu16_6
# 16| mu16_8(unknown) = InitializeIndirection[info] : &:r16_7
# 17| r17_1(glval<Info *>) = VariableAddress[info] :
# 17| r17_2(Info *) = Load : &:r17_1, ~mu16_4
# 17| r17_3(glval<Info *>) = VariableAddress[global_pointer] :
# 17| mu17_4(Info *) = Store : &:r17_3, r17_2
# 18| v18_1(void) = NoOp :
# 16| v16_9(void) = ReturnIndirection : &:r16_7, ~mu16_4
# 16| v16_10(void) = ReturnVoid :
# 16| v16_11(void) = UnmodeledUse : mu*
# 16| v16_12(void) = AliasedUse : ~mu16_4
# 16| v16_13(void) = ExitFunction :
# 20| void declare_static_infos()
# 20| Block 0
# 20| v20_1(void) = EnterFunction :
# 20| mu20_2(unknown) = AliasedDefinition :
# 20| mu20_3(unknown) = InitializeNonLocal :
# 20| mu20_4(unknown) = UnmodeledDefinition :
# 21| r21_1(glval<Info[2]>) = VariableAddress[static_infos] :
# 21| mu21_2(Info[2]) = Uninitialized[static_infos] : &:r21_1
# 21| r21_3(int) = Constant[0] :
# 21| r21_4(glval<Info>) = PointerAdd[16] : r21_1, r21_3
# 22| r22_1(glval<char *>) = FieldAddress[name] : r21_4
# 22| r22_2(glval<char[2]>) = StringConstant["1"] :
# 22| r22_3(char *) = Convert : r22_2
# 22| mu22_4(char *) = Store : &:r22_1, r22_3
# 22| r22_5(glval<..(*)(..)>) = FieldAddress[handler] : r21_4
# 22| r22_6(..(*)(..)) = FunctionAddress[handler1] :
# 22| mu22_7(..(*)(..)) = Store : &:r22_5, r22_6
# 21| r21_5(int) = Constant[1] :
# 21| r21_6(glval<Info>) = PointerAdd[16] : r21_1, r21_5
# 23| r23_1(glval<char *>) = FieldAddress[name] : r21_6
# 23| r23_2(glval<char[2]>) = StringConstant["2"] :
# 23| r23_3(char *) = Convert : r23_2
# 23| mu23_4(char *) = Store : &:r23_1, r23_3
# 23| r23_5(glval<..(*)(..)>) = FieldAddress[handler] : r21_6
# 23| r23_6(glval<..()(..)>) = FunctionAddress[handler2] :
# 23| r23_7(..(*)(..)) = CopyValue : r23_6
# 23| mu23_8(..(*)(..)) = Store : &:r23_5, r23_7
# 25| r25_1(glval<unknown>) = FunctionAddress[let_info_escape] :
# 25| r25_2(glval<Info[2]>) = VariableAddress[static_infos] :
# 25| r25_3(Info *) = Convert : r25_2
# 25| v25_4(void) = Call : func:r25_1, 0:r25_3
# 25| mu25_5(unknown) = ^CallSideEffect : ~mu20_4
# 25| v25_6(void) = ^BufferReadSideEffect[0] : &:r25_3, ~mu20_4
# 25| mu25_7(unknown) = ^BufferMayWriteSideEffect[0] : &:r25_3
# 26| v26_1(void) = NoOp :
# 20| v20_5(void) = ReturnVoid :
# 20| v20_6(void) = UnmodeledUse : mu*
# 20| v20_7(void) = AliasedUse : ~mu20_4
# 20| v20_8(void) = ExitFunction :
# 28| void declare_local_infos()
# 28| Block 0
# 28| v28_1(void) = EnterFunction :
# 28| mu28_2(unknown) = AliasedDefinition :
# 28| mu28_3(unknown) = InitializeNonLocal :
# 28| mu28_4(unknown) = UnmodeledDefinition :
# 29| r29_1(glval<Info[2]>) = VariableAddress[local_infos] :
# 29| mu29_2(Info[2]) = Uninitialized[local_infos] : &:r29_1
# 29| r29_3(int) = Constant[0] :
# 29| r29_4(glval<Info>) = PointerAdd[16] : r29_1, r29_3
# 30| r30_1(glval<char *>) = FieldAddress[name] : r29_4
# 30| r30_2(glval<char[2]>) = StringConstant["1"] :
# 30| r30_3(char *) = Convert : r30_2
# 30| mu30_4(char *) = Store : &:r30_1, r30_3
# 30| r30_5(glval<..(*)(..)>) = FieldAddress[handler] : r29_4
# 30| r30_6(..(*)(..)) = FunctionAddress[handler1] :
# 30| mu30_7(..(*)(..)) = Store : &:r30_5, r30_6
# 29| r29_5(int) = Constant[1] :
# 29| r29_6(glval<Info>) = PointerAdd[16] : r29_1, r29_5
# 31| r31_1(glval<char *>) = FieldAddress[name] : r29_6
# 31| r31_2(glval<char[2]>) = StringConstant["2"] :
# 31| r31_3(char *) = Convert : r31_2
# 31| mu31_4(char *) = Store : &:r31_1, r31_3
# 31| r31_5(glval<..(*)(..)>) = FieldAddress[handler] : r29_6
# 31| r31_6(glval<..()(..)>) = FunctionAddress[handler2] :
# 31| r31_7(..(*)(..)) = CopyValue : r31_6
# 31| mu31_8(..(*)(..)) = Store : &:r31_5, r31_7
# 33| r33_1(glval<unknown>) = FunctionAddress[let_info_escape] :
# 33| r33_2(glval<Info[2]>) = VariableAddress[local_infos] :
# 33| r33_3(Info *) = Convert : r33_2
# 33| v33_4(void) = Call : func:r33_1, 0:r33_3
# 33| mu33_5(unknown) = ^CallSideEffect : ~mu28_4
# 33| v33_6(void) = ^BufferReadSideEffect[0] : &:r33_3, ~mu28_4
# 33| mu33_7(unknown) = ^BufferMayWriteSideEffect[0] : &:r33_3
# 34| v34_1(void) = NoOp :
# 28| v28_5(void) = ReturnVoid :
# 28| v28_6(void) = UnmodeledUse : mu*
# 28| v28_7(void) = AliasedUse : ~mu28_4
# 28| v28_8(void) = ExitFunction :
# 36| void declare_static_runtime_infos(char const*)
# 36| Block 0
# 36| v36_1(void) = EnterFunction :
# 36| mu36_2(unknown) = AliasedDefinition :
# 36| mu36_3(unknown) = InitializeNonLocal :
# 36| mu36_4(unknown) = UnmodeledDefinition :
# 36| r36_5(glval<char *>) = VariableAddress[name1] :
# 36| mu36_6(char *) = InitializeParameter[name1] : &:r36_5
# 36| r36_7(char *) = Load : &:r36_5, ~mu36_6
# 36| mu36_8(unknown) = InitializeIndirection[name1] : &:r36_7
# 37| r37_1(glval<Info[2]>) = VariableAddress[static_infos] :
# 37| mu37_2(Info[2]) = Uninitialized[static_infos] : &:r37_1
# 37| r37_3(int) = Constant[0] :
# 37| r37_4(glval<Info>) = PointerAdd[16] : r37_1, r37_3
# 38| r38_1(glval<char *>) = FieldAddress[name] : r37_4
# 38| r38_2(glval<char *>) = VariableAddress[name1] :
# 38| r38_3(char *) = Load : &:r38_2, ~mu36_4
# 38| mu38_4(char *) = Store : &:r38_1, r38_3
# 38| r38_5(glval<..(*)(..)>) = FieldAddress[handler] : r37_4
# 38| r38_6(..(*)(..)) = FunctionAddress[handler1] :
# 38| mu38_7(..(*)(..)) = Store : &:r38_5, r38_6
# 37| r37_5(int) = Constant[1] :
# 37| r37_6(glval<Info>) = PointerAdd[16] : r37_1, r37_5
# 39| r39_1(glval<char *>) = FieldAddress[name] : r37_6
# 39| r39_2(glval<char[2]>) = StringConstant["2"] :
# 39| r39_3(char *) = Convert : r39_2
# 39| mu39_4(char *) = Store : &:r39_1, r39_3
# 39| r39_5(glval<..(*)(..)>) = FieldAddress[handler] : r37_6
# 39| r39_6(glval<..()(..)>) = FunctionAddress[handler2] :
# 39| r39_7(..(*)(..)) = CopyValue : r39_6
# 39| mu39_8(..(*)(..)) = Store : &:r39_5, r39_7
# 41| r41_1(glval<unknown>) = FunctionAddress[let_info_escape] :
# 41| r41_2(glval<Info[2]>) = VariableAddress[static_infos] :
# 41| r41_3(Info *) = Convert : r41_2
# 41| v41_4(void) = Call : func:r41_1, 0:r41_3
# 41| mu41_5(unknown) = ^CallSideEffect : ~mu36_4
# 41| v41_6(void) = ^BufferReadSideEffect[0] : &:r41_3, ~mu36_4
# 41| mu41_7(unknown) = ^BufferMayWriteSideEffect[0] : &:r41_3
# 42| v42_1(void) = NoOp :
# 36| v36_9(void) = ReturnIndirection : &:r36_7, ~mu36_4
# 36| v36_10(void) = ReturnVoid :
# 36| v36_11(void) = UnmodeledUse : mu*
# 36| v36_12(void) = AliasedUse : ~mu36_4
# 36| v36_13(void) = ExitFunction :

View File

@@ -0,0 +1,42 @@
int handler1(void *p);
int handler2(void *p);
struct Info {
const char *name;
int (*handler)(void *);
};
static Info infos_in_file[] = {
{ "1", handler1 },
{ "3", &handler2 },
};
Info *global_pointer;
void let_info_escape(Info *info) {
global_pointer = info;
}
void declare_static_infos() {
static Info static_infos[] = {
{ "1", handler1 },
{ "2", &handler2 },
};
let_info_escape(static_infos);
}
void declare_local_infos() {
Info local_infos[] = {
{ "1", handler1 },
{ "2", &handler2 },
};
let_info_escape(local_infos);
}
void declare_static_runtime_infos(const char *name1) {
static Info static_infos[] = {
{ name1, handler1 },
{ "2", &handler2 },
};
let_info_escape(static_infos);
}