Skip to content

Commit 2942be5

Browse files
pfultz2amai2012
authored andcommitted
Add more tests for valueFlowUninit (#2124)
1 parent a501f65 commit 2942be5

2 files changed

Lines changed: 279 additions & 1 deletion

File tree

lib/valueflow.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2510,7 +2510,7 @@ static bool valueFlowForward(Token * const startToken,
25102510
return false;
25112511
}
25122512

2513-
else if (indentlevel <= 0 && Token::Match(tok2, "return|throw"))
2513+
else if (indentlevel <= 0 && Token::Match(tok2, "return|throw|setjmp|longjmp"))
25142514
returnStatement = true;
25152515

25162516
else if (returnStatement && tok2->str() == ";")

test/testuninitvar.cpp

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3991,6 +3991,284 @@ class TestUninitVar : public TestFixture {
39913991
" int x[] = {a,2};\n"
39923992
"}");
39933993
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
3994+
3995+
valueFlowUninit("void foo()\n"
3996+
"{\n"
3997+
" int x;\n"
3998+
" int *y = &x;\n"
3999+
"}");
4000+
ASSERT_EQUALS("", errout.str());
4001+
4002+
valueFlowUninit("void foo()\n"
4003+
"{\n"
4004+
" int *x;\n"
4005+
" int *&y = x;\n"
4006+
"}");
4007+
ASSERT_EQUALS("", errout.str());
4008+
4009+
valueFlowUninit("void foo()\n"
4010+
"{\n"
4011+
" int x = xyz::x;\n"
4012+
"}");
4013+
ASSERT_EQUALS("", errout.str());
4014+
4015+
valueFlowUninit("void f()\n"
4016+
"{\n"
4017+
" extern int a;\n"
4018+
" a++;\n"
4019+
"}");
4020+
ASSERT_EQUALS("", errout.str());
4021+
4022+
valueFlowUninit("static void foo()\n"
4023+
"{\n"
4024+
" int x, y;\n"
4025+
" x = (y = 10);\n"
4026+
" int z = y * 2;\n"
4027+
"}");
4028+
ASSERT_EQUALS("", errout.str());
4029+
4030+
valueFlowUninit("static void foo() {\n"
4031+
" int x, y;\n"
4032+
" x = ((y) = 10);\n"
4033+
"}");
4034+
ASSERT_EQUALS("", errout.str());
4035+
4036+
valueFlowUninit("static void foo()\n"
4037+
"{\n"
4038+
" Foo p;\n"
4039+
" p.abcd();\n"
4040+
"}");
4041+
ASSERT_EQUALS("", errout.str());
4042+
4043+
valueFlowUninit("static void foo()\n"
4044+
"{\n"
4045+
" Foo p;\n"
4046+
" int x = p.abcd();\n"
4047+
"}");
4048+
ASSERT_EQUALS("", errout.str());
4049+
4050+
// Unknown types
4051+
{
4052+
valueFlowUninit("void a()\n"
4053+
"{\n"
4054+
" A ret;\n"
4055+
" return ret;\n"
4056+
"}");
4057+
ASSERT_EQUALS("", errout.str());
4058+
4059+
// #3916 - avoid false positive
4060+
valueFlowUninit("void f(float x) {\n"
4061+
" union lf { long l; float f; } u_lf;\n"
4062+
" float hx = (u_lf.f = (x), u_lf.l);\n"
4063+
"}");
4064+
ASSERT_EQUALS("", errout.str());
4065+
}
4066+
4067+
valueFlowUninit("void a()\n"
4068+
"{\n"
4069+
" int x[10];\n"
4070+
" int *y = x;\n"
4071+
"}");
4072+
ASSERT_EQUALS("", errout.str());
4073+
4074+
valueFlowUninit("void a()\n"
4075+
"{\n"
4076+
" int x;\n"
4077+
" int *y = &x;\n"
4078+
" *y = 0;\n"
4079+
" x++;\n"
4080+
"}");
4081+
ASSERT_EQUALS("", errout.str());
4082+
4083+
valueFlowUninit("void a()\n"
4084+
"{\n"
4085+
" char x[10], y[10];\n"
4086+
" char *z = x;\n"
4087+
" memset(z, 0, sizeof(x));\n"
4088+
" memcpy(y, x, sizeof(x));\n"
4089+
"}");
4090+
ASSERT_EQUALS("", errout.str());
4091+
4092+
// Handling >> and <<
4093+
{
4094+
valueFlowUninit("int a() {\n"
4095+
" int ret;\n"
4096+
" std::cin >> ret;\n"
4097+
" ret++;\n"
4098+
"}");
4099+
ASSERT_EQUALS("", errout.str());
4100+
4101+
valueFlowUninit("void f(int b) {\n"
4102+
" int a;\n"
4103+
" std::cin >> b >> a;\n"
4104+
" return a;"
4105+
"}");
4106+
ASSERT_EQUALS("", errout.str());
4107+
4108+
valueFlowUninit("void foo() {\n" // #3707
4109+
" Node node;\n"
4110+
" int x;\n"
4111+
" node[\"abcd\"] >> x;\n"
4112+
"}");
4113+
ASSERT_EQUALS("", errout.str());
4114+
4115+
valueFlowUninit("int a(FArchive &arc) {\n"
4116+
" int *p;\n"
4117+
" arc << p;\n"
4118+
" return *p;\n"
4119+
"}");
4120+
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
4121+
4122+
// #4320
4123+
valueFlowUninit("void f() {\n"
4124+
" int a;\n"
4125+
" a << 1;\n"
4126+
" return a;\n"
4127+
"}");
4128+
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str());
4129+
4130+
}
4131+
4132+
valueFlowUninit("void a() {\n" // asm
4133+
" int x;\n"
4134+
" asm();\n"
4135+
" x++;\n"
4136+
"}");
4137+
ASSERT_EQUALS("", errout.str());
4138+
4139+
valueFlowUninit("void a()\n"
4140+
"{\n"
4141+
" int x[10];\n"
4142+
" struct xyz xyz1 = { .x = x };\n"
4143+
"}");
4144+
ASSERT_EQUALS("", errout.str());
4145+
4146+
valueFlowUninit("void foo()\n"
4147+
"{\n"
4148+
" char *buf = malloc(100);\n"
4149+
" struct ABC *abc = buf;\n"
4150+
"}");
4151+
ASSERT_EQUALS("", errout.str());
4152+
4153+
valueFlowUninit("class Fred {\n"
4154+
"public:\n"
4155+
" FILE *f;\n"
4156+
" ~Fred();\n"
4157+
"}\n"
4158+
"Fred::~Fred()\n"
4159+
"{\n"
4160+
" fclose(f);\n"
4161+
"}");
4162+
ASSERT_EQUALS("", errout.str());
4163+
4164+
valueFlowUninit("void f()\n"
4165+
"{\n"
4166+
" int c;\n"
4167+
" ab(sizeof(xyz), &c);\n"
4168+
" if (c);\n"
4169+
"}");
4170+
ASSERT_EQUALS("", errout.str());
4171+
4172+
valueFlowUninit("void f()\n"
4173+
"{\n"
4174+
" int c;\n"
4175+
" a = (f2(&c));\n"
4176+
" c++;\n"
4177+
"}");
4178+
ASSERT_EQUALS("", errout.str());
4179+
4180+
// goto/setjmp/longjmp..
4181+
valueFlowUninit("void foo(int x)\n"
4182+
"{\n"
4183+
" long b;\n"
4184+
" if (g()) {\n"
4185+
" b =2;\n"
4186+
" goto found;\n"
4187+
" }\n"
4188+
"\n"
4189+
" return;\n"
4190+
"\n"
4191+
"found:\n"
4192+
" int a = b;\n"
4193+
"}");
4194+
ASSERT_EQUALS("", errout.str());
4195+
4196+
valueFlowUninit("int foo()\n"
4197+
"{\n"
4198+
" jmp_buf env;\n"
4199+
" int a;\n"
4200+
" int val = setjmp(env);\n"
4201+
" if(val)\n"
4202+
" return a;\n"
4203+
" a = 1;\n"
4204+
" longjmp(env, 1);\n"
4205+
"}");
4206+
ASSERT_EQUALS("", errout.str());
4207+
4208+
// macro_for..
4209+
valueFlowUninit("int foo()\n"
4210+
"{\n"
4211+
" int retval;\n"
4212+
" if (condition) {\n"
4213+
" for12(1,2) { }\n"
4214+
" retval = 1;\n"
4215+
" }\n"
4216+
" else\n"
4217+
" retval = 2;\n"
4218+
" return retval;\n"
4219+
"}");
4220+
ASSERT_EQUALS("", errout.str());
4221+
4222+
valueFlowUninit("int foo()\n"
4223+
"{\n"
4224+
" int i;\n"
4225+
" goto exit;\n"
4226+
" i++;\n"
4227+
"exit:\n"
4228+
"}");
4229+
ASSERT_EQUALS("", errout.str());
4230+
4231+
valueFlowUninit("int foo() {\n"
4232+
" int x,y=0;\n"
4233+
"again:\n"
4234+
" if (y) return x;\n"
4235+
" x = a;\n"
4236+
" y = 1;\n"
4237+
" goto again;\n"
4238+
"}");
4239+
ASSERT_EQUALS("", errout.str());
4240+
4241+
// #4040 - False positive
4242+
valueFlowUninit("int f(int x) {\n"
4243+
" int iter;\n"
4244+
" {\n"
4245+
" union\n"
4246+
" {\n"
4247+
" int asInt;\n"
4248+
" double asDouble;\n"
4249+
" };\n"
4250+
"\n"
4251+
" iter = x;\n"
4252+
" }\n"
4253+
" return 1 + iter;\n"
4254+
"}");
4255+
ASSERT_EQUALS("", errout.str());
4256+
4257+
// C++11 style initialization
4258+
valueFlowUninit("int f() {\n"
4259+
" int i = 0;\n"
4260+
" int j{ i };\n"
4261+
" return j;\n"
4262+
"}");
4263+
ASSERT_EQUALS("", errout.str());
4264+
4265+
// Ticket #5646
4266+
valueFlowUninit("float foo() {\n"
4267+
" float source[2] = {3.1, 3.1};\n"
4268+
" float (*sink)[2] = &source;\n"
4269+
" return (*sink)[0];\n"
4270+
"}");
4271+
ASSERT_EQUALS("", errout.str());
39944272
}
39954273

39964274
void uninitvar_ipa() {

0 commit comments

Comments
 (0)