mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
121 lines
2.7 KiB
C++
121 lines
2.7 KiB
C++
|
|
int ymlSource();
|
|
void ymlSink(int value);
|
|
int ymlStepManual(int value);
|
|
int ymlStepGenerated(int value);
|
|
int ymlStepManual_with_body(int value1, int value2) { return value2; }
|
|
int ymlStepGenerated_with_body(int value, int value2) { return value2; }
|
|
|
|
void test() {
|
|
int x = ymlSource();
|
|
|
|
ymlSink(0);
|
|
|
|
ymlSink(x); // $ ir
|
|
|
|
// ymlStepManual is manually modeled so we should always use the model
|
|
int y = ymlStepManual(x);
|
|
ymlSink(y); // $ ir
|
|
|
|
// ymlStepGenerated is modeled by the model generator so we should use the model only if there is no body
|
|
int z = ymlStepGenerated(x);
|
|
ymlSink(z); // $ ir
|
|
|
|
// ymlStepManual_with_body is manually modeled so we should always use the model
|
|
int y2 = ymlStepManual_with_body(x, 0);
|
|
ymlSink(y2); // $ ir
|
|
|
|
int y3 = ymlStepManual_with_body(0, x);
|
|
ymlSink(y3); // clean
|
|
|
|
// ymlStepGenerated_with_body is modeled by the model generator so we should use the model only if there is no body
|
|
int z2 = ymlStepGenerated_with_body(0, x);
|
|
ymlSink(z2); // $ ir
|
|
|
|
int z3 = ymlStepGenerated_with_body(x, 0);
|
|
ymlSink(z3); // clean
|
|
}
|
|
|
|
struct S {
|
|
int x;
|
|
};
|
|
|
|
using pthread_t = unsigned long;
|
|
using pthread_attr_t = void*;
|
|
|
|
void *myThreadFunction(void *arg) {
|
|
S* s = (S *)arg;
|
|
ymlSink(s->x); // $ ir
|
|
return nullptr;
|
|
}
|
|
|
|
int pthread_create(pthread_t *thread, const pthread_attr_t * attr, void *(*start_routine)(void*), void *arg);
|
|
|
|
int test_pthread_create() {
|
|
S s;
|
|
s.x = ymlSource();
|
|
|
|
pthread_t threadId;
|
|
pthread_create(&threadId, nullptr, myThreadFunction, (void *)&s);
|
|
}
|
|
|
|
template<typename F>
|
|
void callWithArgument(F f, int x);
|
|
|
|
struct StructWithOperatorCall_has_constructor {
|
|
StructWithOperatorCall_has_constructor();
|
|
|
|
void operator()(int y) {
|
|
ymlSink(y); // $ ir
|
|
}
|
|
};
|
|
|
|
struct StructWithOperatorCall_no_constructor {
|
|
void operator()(int y) {
|
|
ymlSink(y); // $ ir
|
|
}
|
|
};
|
|
|
|
struct StructWithOperatorCall_has_constructor_2 {
|
|
StructWithOperatorCall_has_constructor_2();
|
|
|
|
void operator()(int y) {
|
|
ymlSink(y); // $ ir
|
|
}
|
|
};
|
|
|
|
struct StructWithOperatorCall_no_constructor_2 {
|
|
void operator()(int y) {
|
|
ymlSink(y); // $ ir
|
|
}
|
|
};
|
|
|
|
void test_callWithArgument() {
|
|
int x = ymlSource();
|
|
{
|
|
StructWithOperatorCall_has_constructor func;
|
|
callWithArgument(func, x);
|
|
}
|
|
{
|
|
StructWithOperatorCall_no_constructor func;
|
|
callWithArgument(func, x);
|
|
}
|
|
callWithArgument(StructWithOperatorCall_has_constructor_2(), x);
|
|
callWithArgument(StructWithOperatorCall_no_constructor_2(), x);
|
|
}
|
|
|
|
template<int N, typename T>
|
|
T callWithNonTypeTemplate(const T&);
|
|
|
|
template<typename T, int N>
|
|
T callWithNonTypeTemplate(const T&);
|
|
|
|
void test_callWithNonTypeTemplate() {
|
|
int x = ymlSource();
|
|
int y1 = callWithNonTypeTemplate<10, int>(x);
|
|
ymlSink(y1); // $ MISSING: ir
|
|
|
|
int y2 = callWithNonTypeTemplate<int, 10>(x);
|
|
ymlSink(y2); // $ ir
|
|
}
|