C++: Add an example with missing flow.

This commit is contained in:
Mathias Vorreiter Pedersen
2025-11-25 12:36:29 +00:00
parent 47ab307410
commit 2024f32e81
5 changed files with 39 additions and 0 deletions

View File

@@ -142,6 +142,7 @@ postWithInFlow
| simple.cpp:92:7:92:7 | i [post update] | PostUpdateNode should not be the target of local flow. |
| simple.cpp:118:7:118:7 | i [post update] | PostUpdateNode should not be the target of local flow. |
| simple.cpp:124:5:124:6 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
| simple.cpp:167:9:167:9 | x [post update] | PostUpdateNode should not be the target of local flow. |
viableImplInCallContextTooLarge
uniqueParameterNodeAtPosition
uniqueParameterNodePosition

View File

@@ -308,3 +308,5 @@ WARNING: module 'DataFlow' has been deprecated and may be removed in future (par
| simple.cpp:124:5:124:6 | * ... | AST only |
| simple.cpp:131:14:131:14 | a | IR only |
| simple.cpp:136:10:136:10 | a | IR only |
| simple.cpp:167:9:167:9 | x | AST only |
| simple.cpp:168:8:168:12 | u_int | IR only |

View File

@@ -670,6 +670,8 @@
| simple.cpp:131:14:131:14 | a |
| simple.cpp:135:20:135:20 | q |
| simple.cpp:136:10:136:10 | a |
| simple.cpp:167:3:167:7 | u_int |
| simple.cpp:168:8:168:12 | u_int |
| struct_init.c:15:8:15:9 | ab |
| struct_init.c:15:12:15:12 | a |
| struct_init.c:16:8:16:9 | ab |

View File

@@ -597,6 +597,8 @@ WARNING: module 'DataFlow' has been deprecated and may be removed in future (par
| simple.cpp:118:7:118:7 | i |
| simple.cpp:124:5:124:6 | * ... |
| simple.cpp:135:20:135:20 | q |
| simple.cpp:167:3:167:7 | u_int |
| simple.cpp:167:9:167:9 | x |
| struct_init.c:15:8:15:9 | ab |
| struct_init.c:15:12:15:12 | a |
| struct_init.c:16:8:16:9 | ab |

View File

@@ -136,4 +136,36 @@ void alias_with_fields(bool b) {
sink(a.i); // $ MISSING: ast,ir
}
template<typename T>
union U_with_two_instantiations_of_different_size {
int x;
T y;
};
struct LargeStruct {
int data[64];
};
void test_union_with_two_instantiations_of_different_sizes() {
// A union's fields is partitioned into "chunks" for field-flow in order to
// improve performance (so that a write to a field of a union does not flow
// to too many reads that don't happen at runtime). The partitioning is based
// the size of the types in the union. So a write to a field of size k only
// flows to a read of size k.
// Since field-flow is based on uninstantiated types a field can have
// multiple sizes if the union is instantiated with types of
// different sizes. So to compute the partition we pick the maximum size.
// Because of this there are `Content`s corresponding to the union
// `U_with_two_instantiations_of_different_size<T>`: The one for size
// `sizeof(int)`, and the one for size `sizeof(LargeStruct)` (because
// `LargeStruct` is larger than `int`). So the write to `x` writes to the
// `Content` for size `sizeof(int)`, and the read of `y` reads from the
// `Content` for size `sizeof(LargeStruct)`.
U_with_two_instantiations_of_different_size<int> u_int;
U_with_two_instantiations_of_different_size<LargeStruct> u_very_large;
u_int.x = user_input();
sink(u_int.y); // $ MISSING: ir
}
} // namespace Simple