Skip to content

Commit e37d52f

Browse files
committed
warn about suspicious casts of incomplete classes, do not warn about cast from derived pointer to base pointer
1 parent 0bcd04e commit e37d52f

2 files changed

Lines changed: 41 additions & 17 deletions

File tree

lib/checkother.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,9 +317,19 @@ void CheckOther::warningOldStylePointerCast()
317317
continue;
318318
if (!tok->valueType() || !from->valueType())
319319
continue;
320-
if (tok->valueType()->type == from->valueType()->type &&
320+
if (tok->valueType()->typeScope != nullptr &&
321321
tok->valueType()->typeScope == from->valueType()->typeScope)
322322
continue;
323+
if (tok->valueType()->type == from->valueType()->type &&
324+
tok->valueType()->isPrimitive())
325+
continue;
326+
// cast from derived object to base object is safe..
327+
if (tok->valueType()->typeScope && from->valueType()->typeScope) {
328+
const Type* fromType = from->valueType()->typeScope->definedType;
329+
const Type* toType = tok->valueType()->typeScope->definedType;
330+
if (fromType && toType && fromType->isDerivedFrom(toType->name()))
331+
continue;
332+
}
323333
const bool refcast = (tok->valueType()->reference != Reference::None);
324334
if (!refcast && tok->valueType()->pointer == 0)
325335
continue;

test/testother.cpp

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1912,37 +1912,51 @@ class TestOther : public TestFixture {
19121912
}
19131913

19141914
void oldStylePointerCast() {
1915+
checkOldStylePointerCast("class Base{};\n"
1916+
"class Derived: public Base {};\n"
1917+
"void foo(Base* base)\n"
1918+
"{\n"
1919+
" Derived * d = (Derived *) base;\n"
1920+
"}");
1921+
ASSERT_EQUALS("[test.cpp:5:19]: (style) C-style pointer casting [cstyleCast]\n", errout_str());
1922+
19151923
checkOldStylePointerCast("class Base{};\n"
19161924
"class Derived: public Base {};\n"
19171925
"void foo(Derived* derived)\n"
19181926
"{\n"
19191927
" Base * b = (Base *) derived;\n"
19201928
"}");
1921-
ASSERT_EQUALS("[test.cpp:5:16]: (style) C-style pointer casting [cstyleCast]\n", errout_str());
1929+
ASSERT_EQUALS("", errout_str()); // <- cast from derived to base is safe
1930+
1931+
checkOldStylePointerCast("void foo(Base* base)\n"
1932+
"{\n"
1933+
" Derived * d = (Derived *) base;\n"
1934+
"}");
1935+
ASSERT_EQUALS("[test.cpp:3:19]: (style) C-style pointer casting [cstyleCast]\n", errout_str());
19221936

19231937
checkOldStylePointerCast("class Base{};\n"
19241938
"class Derived: public Base {};\n"
1925-
"void foo(Derived* derived)\n"
1939+
"void foo(Base* base)\n"
19261940
"{\n"
1927-
" Base * b = (const Base *) derived;\n"
1941+
" Derived * d = (const Derived *) base;\n"
19281942
"}");
1929-
ASSERT_EQUALS("[test.cpp:5:16]: (style) C-style pointer casting [cstyleCast]\n", errout_str());
1943+
ASSERT_EQUALS("[test.cpp:5:19]: (style) C-style pointer casting [cstyleCast]\n", errout_str());
19301944

19311945
checkOldStylePointerCast("class Base{};\n"
19321946
"class Derived: public Base {};\n"
19331947
"void foo()\n"
19341948
"{\n"
1935-
" Base * b = (Base *) ( new Derived() );\n"
1949+
" Derived * d = (const Derived *) ( new Base() );\n"
19361950
"}");
1937-
ASSERT_EQUALS("[test.cpp:5:16]: (style) C-style pointer casting [cstyleCast]\n", errout_str());
1951+
ASSERT_EQUALS("[test.cpp:5:19]: (style) C-style pointer casting [cstyleCast]\n", errout_str());
19381952

19391953
checkOldStylePointerCast("class Base{};\n"
19401954
"class Derived: public Base {};\n"
19411955
"void foo()\n"
19421956
"{\n"
1943-
" Base * b = (Base *) new Derived();\n"
1957+
" Derived * d = (const Derived *) new Base();\n"
19441958
"}");
1945-
ASSERT_EQUALS("[test.cpp:5:16]: (style) C-style pointer casting [cstyleCast]\n", errout_str());
1959+
ASSERT_EQUALS("[test.cpp:5:19]: (style) C-style pointer casting [cstyleCast]\n", errout_str());
19461960

19471961
checkOldStylePointerCast("class Base{};\n"
19481962
"void foo()\n"
@@ -2071,12 +2085,12 @@ class TestOther : public TestFixture {
20712085
// #5210
20722086
checkOldStylePointerCast("class Base {};\n"
20732087
"class Derived: public Base {};\n"
2074-
"void f(Derived** d1, Derived*** d2) {\n"
2075-
" Base** p1 = (Base**)d1;\n"
2076-
" Base*** p2 = (Base***)d2;\n"
2088+
"void f(Base** b1, Base*** b2) {\n"
2089+
" Derived** p1 = (Derived**)b1;\n"
2090+
" Derived*** p2 = (Derived***)b2;\n"
20772091
"}\n");
2078-
ASSERT_EQUALS("[test.cpp:4:17]: (style) C-style pointer casting [cstyleCast]\n"
2079-
"[test.cpp:5:18]: (style) C-style pointer casting [cstyleCast]\n",
2092+
ASSERT_EQUALS("[test.cpp:4:20]: (style) C-style pointer casting [cstyleCast]\n"
2093+
"[test.cpp:5:21]: (style) C-style pointer casting [cstyleCast]\n",
20802094
errout_str());
20812095

20822096
// #12446
@@ -2095,10 +2109,10 @@ class TestOther : public TestFixture {
20952109
// #12447
20962110
checkOldStylePointerCast("class Base {};\n"
20972111
"class Derived: public Base {};\n"
2098-
"void f(const Derived& derived) {\n"
2099-
" Base& b = (Base&)derived;\n"
2112+
"void f(const Base& base) {\n"
2113+
" d = (const Derived&)base;\n"
21002114
"}\n");
2101-
ASSERT_EQUALS("[test.cpp:4:13]: (style) C-style reference casting [cstyleCast]\n", errout_str());
2115+
ASSERT_EQUALS("[test.cpp:4:7]: (style) C-style reference casting [cstyleCast]\n", errout_str());
21022116

21032117
// #11430
21042118
checkOldStylePointerCast("struct B {\n"

0 commit comments

Comments
 (0)