Slicing¶
ID: cpp/slicingKind: problemSecurity severity: Severity: warningPrecision: highTags: - reliability - correctness - typesQuery suites: - cpp-security-and-quality.qls
Click to see the query in the CodeQL repository
This query finds assignments of a non-reference instance of a derived type to a variable of the base type where the derived type has more fields than the base. These assignments slice off all the fields added by the derived type, and can cause unexpected state when accessed as the derived type.
Recommendation¶
Change the type of the variable at the left-hand side of the assignment to the subclass.
Example¶
staticintidctr=0;//Basic connection with idclassConnection{public:intconnId;virtualvoidprint_info(){cout<<"id: "<<connId<<"\n";}Connection(){connId=idctr++;}};//Adds counters, and an overriding print_infoclassMeteredConnection:publicConnection{public:inttxCtr;intrxCtr;MeteredConnection(){txCtr=0;rxCtr=0;}virtualvoidprint_info(){cout<<"id: "<<connId<<"\n"<<"tx/rx: "<<txCtr<<"/"<<rxCtr<<"\n";}};intmain(intargc,char*argv[]){Connectionconn;MeteredConnectionm_conn;Connectioncurr_conn=conn;curr_conn.print_info();curr_conn=m_conn;//Wrong: Derived MetricConnection assigned to Connection//variable, will slice off the counters and the overriding print_infocurr_conn.print_info();//Will not print the counters.Connection*curr_pconn=&conn;curr_pconn->print_info();curr_pconn=&m_conn;//Correct: Pointer assigned to address of the MetricConnection.//Counters and virtual functions remain intact.curr_pconn->print_info();//Will call the correct method MeteredConnection::print_info}
References¶
Wikipedia:Object slicing.
DevX.com:Slicing in C++.