You are on page 1of 25

Cppcheck

PVS-Studio
:
: 22.05.2012
PVS-Studio PVS-Studio
(free, open source) Cppcheck.
id Software: Doom 3, Quake 3: Arena, Wolfenstein:
Enemy Territory. , .
" ", .
.

.
, , ,
( , ).
:
. "-"
, ,
. . -
command line , - (
). - , - .
(Windows, Linux) (x86, AMR) ...
, ,
,
(, AV-Comparatives). ,
, Gartner (Magic Quadrant for Static Application Security Testing),
. , .

Cppcheck
Cppcheck , , Daniel Marjamki ,
. , .
free, , ,
.
C/C++ PVS-Studio.
, ,
: " PVS-Studio Cppcheck?".
:

, , ... (
"");
;
"" "" . -.

, .
PVS-Studio Cppcheck, , ,
.
, ,
. ,
.


PVS-Studio 4.61 Cppcheck 1.54 id Software
GitHub: Doom 3, Quake 3: Arena, Wolfenstein: Enemy Territory. ,
. () . ,
. ,
.. .
:
1. . - ,
Cppcheck , PVS-Studio ,
.vcproj.
2. - , , ,
. ,
, , - .
, PVS-Studio Cppcheck,
, . Trial-
PVS-Studio , . Cppcheck
. ,
.

Doom 3 Cppcheck
1
..\..\[Build]\Doom3\id-Software-DOOM-3-a9c49da\neo\idlib\hashing\MD5.cpp(252):
Using size of pointer ctx instead of size of its data.
void MD5_Final( MD5_CTX *ctx, unsigned char digest[16] ) {
...
memset( ctx, 0, sizeof( ctx ) ); /* In case it's sensitive */
sizeof(*ctx).
.
2
..\..\[Build]\Doom3\id-Software-DOOM-3-a9c49da\neo\renderer\Image_init.cpp(2214)

Mismatching allocation and deallocation: sortIndex


void idImageManager::PrintMemInfo( MemInfo_t *mi ) {
int *sortIndex;
...
sortIndex = new int[images.Num()];
...
delete sortIndex;
, ,
. ( int) ,
, , .
delete [] sortIndex.
3
..\..\[Build]\Doom3\id-Software-DOOM-3-a9c49da\neo\renderer\MegaTexture.cpp(542)
Using size of pointer newBlock instead of size of its data.
void idMegaTexture::GenerateMegaMipMaps(
megaTextureHeader_t *header, idFile *outFile ) {
...
byte *newBlock = (byte *)_alloca( tileSize );
...
memset( newBlock, 0, sizeof( newBlock ) );
, 1 sizeof(*newBlock));
4
..\..\[Build]\Doom3\id-Software-DOOM-3-a9c49da\neo\sys\win32\win_shared.cpp(177)
memset() called to fill 0 bytes of '&'
void Sys_GetCurrentMemoryStatus( sysMemoryStats_t &stats ) {
...
memset( &statex, sizeof( statex ), 0 );
memset(&statex, 0, sizeof(
statex)). , .

Doom 3 PVS-Studio
1
V517 The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical error
presence. Check lines: 524, 533. anim_blend.cpp(524)
const char *idAnim::AddFrameCommand(
const idDeclModelDef *modelDef,
int framenum, idLexer &src, const idDict *def ) {
...
} else if ( token == "muzzle_flash" ) {
if( !src.ReadTokenOnLine( &token ) ) {
return "Unexpected end of line";
}
...
} else if ( token == "muzzle_flash" ) {
fc.type = FC_MUZZLEFLASH;
fc.string = new idStr( "" );
...
if . ,
.
2
V556 The values of different enum types are compared. af.cpp 895
class idDeclAF_Constraint {
...
declAFConstraintType_t type;
...
};

constraintType_t GetType( void ) const { return type; }

bool idAF::Load( idEntity *ent, const char *fileName ) {


...

if (
file->constraints[j]->name.Icmp(
constraint->GetName() ) == 0 &&
file->constraints[j]->type == constraint->GetType() )
{
...
, .. enum.
- , .
3
V528 It is odd that pointer to 'char' type is compared with the '\0' value.
Probably meant: *classname != '\0'. game_local.cpp 1250
const char *classname = mapEnt->epairs.GetString( "classname" );
if ( classname != '\0' ) {
FindEntityDef( classname, false );
}
classname, , .
, .
4
V528 It is odd that pointer to 'char' type is compared with the '\0' value.
Probably meant: *soundShaderName != '\0'. game_local.cpp 1619
soundShaderName = dict->GetString( "s_shader" );
if (soundShaderName != '\0' && dict->GetFloat("s_shakes") != 0.0f){
soundShader = declManager->FindSound( soundShaderName );
3 .
5
V514 Dividing sizeof a pointer 'sizeof (clientInPVS)' by another value. There is a probability of logical
error presence. game_network.cpp 686
void idGameLocal::ServerWriteSnapshot(
int clientNum, int sequence, idBitMsg &msg,
byte *clientInPVS, int numPVSClients ) {
...

memcpy( clientInPVS, snapshot->pvs,


( numPVSClients + 7 ) >> 3 );
LittleRevBytes( clientInPVS, sizeof( int ),
sizeof( clientInPVS ) / sizeof ( int ) );
}
. - clientInPVS
sizeof(clientInPVS)/sizeof(int) .
clientInPVS . .
sizeof(clientInPVS)/sizeof(int) 1 32-, 2
64- . .
6
V599 The destructor was not declared as a virtual one, although the 'BOBrick' class contains virtual
functions. gamebustoutwindow.cpp 509
class BOBrick {
...
virtual void WriteToSaveGame( idFile *savefile );
virtual void ReadFromSaveGame( idFile *savefile,
idGameBustOutWindow *game );
};

BOBrick *paddle;
void idGameBustOutWindow::ReadFromSaveGame( idFile *savefile ) {
idWindow::ReadFromSaveGame( savefile );
// Clear out existing paddle and entities from GUI load
delete paddle;
,
. ,
, .
7
V517 The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical error
presence. Check lines: 1931, 1933. gamessdwindow.cpp 1931
void idGameSSDWindow::FireWeapon(int key) {
...

} else
if(gameStats.levelStats.targetEnt->type == SSD_ENTITY_ASTRONAUT) {
HitAstronaut(static_cast<SSDAstronaut*>(
gameStats.levelStats.targetEnt), key);
} else
if(gameStats.levelStats.targetEnt->type == SSD_ENTITY_ASTRONAUT) {
.
.
8
V535 The variable 'i' is being used for this loop and for the outer loop. matrix.cpp 3128
bool idMatX::IsOrthonormal( const float epsilon ) const
{
for ( int i = 0; i < numRows; i++ ) {
...
for ( i = 1; i < numRows; i++ ) {
, i ,
.
9
V579 The memset function receives the pointer and its size as arguments. It is possibly a mistake.
Inspect the third argument. md5.cpp 252
void MD5_Final( MD5_CTX *ctx, unsigned char digest[16] ) {
...
memset( ctx, 0, sizeof( ctx ) ); /* In case it's sensitive */
sizeof(*ctx),
.
10
V579 The memset function receives the pointer and its size as arguments. It is possibly a mistake.
Inspect the third argument. model_ase.cpp 731
typedef struct {
...
} aseMesh_t;

aseMesh_t *currentMesh;
...
ase.currentMesh = &ase.currentObject->mesh;
memset( ase.currentMesh, 0, sizeof( ase.currentMesh ) );
, memset
, .
11
V532 Consider inspecting the statement of '*pointer++' pattern. Probably meant: '(*pointer)++'.
model_lwo.cpp 1251
int sgetI1( unsigned char **bp )
{
...
*bp++;

, . (*bp)++.
, .
12
V533 It is likely that a wrong variable is being incremented inside the 'for' operator. Consider reviewing
'j'. surface_polytope.cpp 65
void idSurface_Polytope::FromPlanes(
const idPlane *planes, const int numPlanes ) {
for ( j = 0; j < w.GetNumPoints(); j++ ) {
for ( k = 0; k < verts.Num(); j++ ) {
k, j.
.
13
V535 The variable 'i' is being used for this loop and for the outer loop. weapon.cpp 2533
const char *idWeapon::GetAmmoNameForNum( ammo_t ammonum )
{
...

for ( i = 0; i < 2; i++ ) {


...
for( i = 0; i < num; i++ ) {
.
14
V575 The 'memset' function processes '0' elements. Inspect the third argument. win_shared.cpp 177
void Sys_GetCurrentMemoryStatus( sysMemoryStats_t &stats ) {
...
memset( &statex, sizeof( statex ), 0 );
memset(&statex, 0, sizeof(
statex)). , .
15
V512 A call of the 'memset' function will lead to underflow of the buffer '& cluster'. aasfile.cpp 1312
void idAASFileLocal::DeleteClusters( void ) {
aasPortal_t portal;
aasCluster_t cluster;
...
// first portal is a dummy
memset( &portal, 0, sizeof( portal ) );
portals.Append( portal );

// first cluster is a dummy


memset( &cluster, 0, sizeof( portal ) );
clusters.Append( cluster );
}
. .
sizeof(portal) sizeof(cluster).
16
V579 The memset function receives the pointer and its size as arguments. It is possibly a mistake.
Inspect the third argument. megatexture.cpp 542
void idMegaTexture::GenerateMegaMipMaps(

megaTextureHeader_t *header, idFile *outFile ) {


...
byte *newBlock = (byte *)_alloca( tileSize );
...
memset( newBlock, 0, sizeof( newBlock ) );
sizeof(*newBlock), .
17
V564 The '&' operator is applied to bool type value. You've probably forgotten to include parentheses or
intended to use the '&&' operator. target.cpp 257
#define BIT( num ) ( 1 << ( num ) )
const int BUTTON_ATTACK = BIT(0);
void idTarget_WaitForButton::Think( void ) {
idPlayer *player;
...
if ( player && ( !player->oldButtons & BUTTON_ATTACK ) &&
( player->usercmd.buttons & BUTTON_ATTACK ) ) {
player->usercmd.buttons &= ~BUTTON_ATTACK;
- "!" ( , "&")
. , , , .

() Doom 3
Cppcheck: 4.
PVS-Studio: 17.
( Cppcheck, PVS-Studio): 3.
, .

Quake 3: Arena Cppcheck


1
..\..\[Build]\Quake3\id-Software-Quake-III-Arena-dbe4ddb\code\q3_ui\ui_servers2.c 580
Using sizeof with a numeric constant as function argument might not be what you intended.
static void ArenaServers_Remove( void )

{
...
memcpy( &g_arenaservers.favoriteaddresses[i],
&g_arenaservers.favoriteaddresses[i+1],
(g_arenaservers.numfavoriteaddresses - i 1)*
sizeof(MAX_ADDRESSLENGTH));
sizeof(MAX_ADDRESSLENGTH).
, . ,
MAX_ADDRESSLENGTH sizeof().
2
..\..\[Build]\Quake3\id-Software-Quake-III-Arena-dbe4ddb\code\qcommon\files.c 549
Memory leak: buf
static void FS_CopyFile( char *fromOSPath, char *toOSPath ) {
...
byte *buf;
...
buf = malloc( len );
if (fread( buf, 1, len, f ) != len)
Com_Error( ERR_FATAL, "Short read in FS_Copyfiles()\n" );
fclose( f );

if( FS_CreatePath( toOSPath ) ) {


return;
}
...
}
, buf
. , C++ .
3
..\..\[Build]\Quake3\id-Software-Quake-III-Arena-dbe4ddb\code\renderer\tr_shade_calc.c 628
Array 'invModulate[3]' index 3 out of bounds

void RB_CalcColorFromOneMinusEntity( unsigned char *dstColors )


{
...
unsigned char invModulate[3];
...
invModulate[0] = 255 - backEnd.currentEntity->e.shaderRGBA[0];
invModulate[1] = 255 - backEnd.currentEntity->e.shaderRGBA[1];
invModulate[2] = 255 - backEnd.currentEntity->e.shaderRGBA[2];
invModulate[3] = 255 - backEnd.currentEntity->e.shaderRGBA[3];
// this trashes alpha, but the AGEN block fixes it
.
4
..\..\[Build]\Quake3\id-Software-Quake-III-Arena-dbe4ddb\code\server\sv_rankings.c 947
Assert statement modifies 'j'.
assert( (j++) < 68 );
assert release- . , ,
j++ assert, debug-.
5
..\..\[Build]\Quake3\id-Software-Quake-III-Arena-dbe4ddb\code\splines\math_matrix.h 87
Using sizeof for array given as function argument returns the size of pointer.
ID_INLINE mat3_t::mat3_t( float src[ 3 ][ 3 ] ) {
memcpy( mat, src, sizeof( src ) );
}
sizeof
. src .
6
..\..\[Build]\Quake3\id-Software-Quake-III-Arena-dbe4ddb\lcc\src\2html.c 131
printf format string has 2 parameters but 3 are given
static void do_uid(int x) {
printf("<a href='#%d'>%d</a>", x, x, x);

}
printf , . ,
.

Quake 3: Arena PVS-Studio


1
V511 The sizeof() operator returns size of the pointer, and not of the array, in 'sizeof (src)' expression.
math_matrix.h 87
ID_INLINE mat3_t::mat3_t( float src[ 3 ][ 3 ] ) {
memcpy( mat, src, sizeof( src ) );
}
sizeof
.
2
V523 The 'then' statement is equivalent to the 'else' statement. be_aas_sample.c 864
int AAS_TraceAreas(vec3_t start, vec3_t end, int *areas,
vec3_t *points, int maxareas)
{
...
if (front < 0)
frac = (front)/(front-back);
else
frac = (front)/(front-back);
frac ,
. , -.
3
V568 It's odd that the argument of sizeof() operator is the '& itemInfo' expression. cg_weapons.c 849
void CG_RegisterItemVisuals( int itemNum ) {
...
itemInfo_t *itemInfo;
memset( itemInfo, 0, sizeof( &itemInfo ) );
memset , .

4
V557 Array overrun is possible. The 'sizeof (bs->teamleader)' index is pointing beyond array bound.
ai_cmd.c 1311
char teamleader[32];

//netname of the team leader

void BotMatch_StartTeamLeaderShip(
bot_state_t *bs, bot_match_t *match)
{
...
bs->teamleader[sizeof(bs->teamleader)] = '\0';
sizeof() - 1.
5
V557 Array overrun is possible. The value of 'i' index could reach 3. g_main.c 776
int numteamVotingClients[2];// set by CalculateRanks
typedef enum {
TEAM_FREE,
TEAM_RED,
TEAM_BLUE,
TEAM_SPECTATOR,
TEAM_NUM_TEAMS
} team_t;

void CalculateRanks( void ) {


...
for ( i = 0; i < TEAM_NUM_TEAMS; i++ ) {
level.numteamVotingClients[i] = 0;
}
, enum,
. - .
6

V579 The Com_Memset function receives the pointer and its size as arguments. It is possibly a mistake.
Inspect the third argument. cvar.c 763
void Cvar_Restart_f( void ) {
...
cvar_t

*var;

...
Com_Memset( var, 0, sizeof( var ) );
, . sizeof(*var).
7
V557 Array overrun is possible. The '3' index is pointing beyond array bound. tr_shade_calc.c 628
void RB_CalcColorFromOneMinusEntity( unsigned char *dstColors )
{
...
unsigned char invModulate[3];
...
invModulate[0] = 255 - backEnd.currentEntity->e.shaderRGBA[0];
invModulate[1] = 255 - backEnd.currentEntity->e.shaderRGBA[1];
invModulate[2] = 255 - backEnd.currentEntity->e.shaderRGBA[2];
invModulate[3] = 255 - backEnd.currentEntity->e.shaderRGBA[3];
// this trashes alpha, but the AGEN block fixes it
- , 4, 3.

() Quake 3:
Arena
Cppcheck: 6.
PVS-Studio: 7.
( Cppcheck, PVS-Studio): 2.
, .

Wolfenstein: Enemy Territory


Cppcheck
1

..\..\[Build]\Enemy Territory\id-Software-Enemy-Territory-40342a9\src\curl7.12.2\docs\examples\sepheaders.c 76
Resource leak: bodyfile
bodyfile = fopen( bodyfilename,"w" );
...
// no fclose for bodyfile
, . ,
examples, . .
2
..\..\[Build]\Enemy Territory\id-Software-Enemy-Territory-40342a9\src\curl-7.12.2\src\main.c 3765
Undefined behavior: variable is used as parameter and destination in s[n]printf().
sprintf( dirbuildup,"%s%s%s",dirbuildup, DIR_CHAR, tempdir );
. .
3
..\..\[Build]\Enemy Territory\id-Software-Enemy-Territory-40342a9\src\game\bg_animation.c 585
Using sizeof for array given as function argument returns the size of pointer.
void BG_ParseConditionBits( char **text_pp,
animStringItem_t *stringTable, int condIndex, int result[2] ) {
...
memset( result, 0, sizeof( result ) );
.
sizeof(), ( ),
"2 * sizeof(int)", .
4
..\..\[Build]\Enemy Territory\id-Software-Enemy-Territory-40342a9\src\game\bg_animation.c 776
Using size of pointer command instead of size of its data.
static void BG_ParseCommands( char **input,
animScriptItem_t *scriptItem, animModelInfo_t *animModelInfo,
animScriptData_t *scriptData )
{
...

// TTimo gcc: might be used uninitialized


animScriptCommand_t *command = NULL;
...
memset( command, 0, sizeof( command ) );
.
5
..\..\[Build]\Enemy Territory\id-Software-Enemy-Territory-40342a9\src\qcommon\cvar.c 905
Using size of pointer var instead of size of its data.
void Cvar_Restart_f( void ) {
cvar_t

*var;

...
memset( var, 0, sizeof( var ) );
.
6
..\..\[Build]\Enemy Territory\id-Software-Enemy-Territory-40342a9\src\splines\math_matrix.h 94
Using sizeof for array given as function argument returns the size of pointer.
ID_INLINE mat3_t::mat3_t( float src[ 3 ][ 3 ] ) {
memcpy( mat, src, sizeof( src ) );
}
sizeof
.
7
..\..\[Build]\Enemy Territory\id-Software-Enemy-Territory-40342a9\src\game\bg_pmove.c 4097
Redundant assignment of "fwdmove_knockback" in switch
switch ( pm->ps->weapon ) {
case WP_MOBILE_MG42:

fwdmove_knockback = 4000.f;

fwdmove_knockback = 400.f;
break;
case WP_PANZERFAUST:

fwdmove_knockback = 32000.f;

bckmove_knockback = 1200.f;

break;
case WP_FLAMETHROWER:

fwdmove_knockback = 2000.f;

bckmove_knockback = 40.f;
break;
}
WP_MOBILE_MG42 .
8
..\..\[Build]\Enemy Territory\id-Software-Enemy-Territory-40342a9\src\game\q_math.c 422
Array 'pnt[3]' index 3 out of bounds
typedef vec_t vec3_t[3];
void RotatePointAroundVertex( vec3_t pnt,
float rot_x, float rot_y, float rot_z, const vec3_t origin )
{
...
// rotate point
pnt[0] = ( tmp[3] * ( tmp[8] - tmp[9] ) + pnt[3] * tmp[2] );
pnt[3] .

Wolfenstein: Enemy Territory


PVS-Studio
1
V511 The sizeof() operator returns size of the pointer, and not of the array, in 'sizeof (src)' expression.
math_matrix.h 94
ID_INLINE mat3_t::mat3_t( float src[ 3 ][ 3 ] ) {
memcpy( mat, src, sizeof( src ) );
}
sizeof
.
2
V511 The sizeof() operator returns size of the pointer, and not of the array, in 'sizeof (result)' expression.
bg_animation.c 585

void BG_ParseConditionBits( char **text_pp,


animStringItem_t *stringTable, int condIndex, int result[2] )
{
...
memset( result, 0, sizeof( result ) );
.
sizeof(), ( ),
"2", .
3
V579 The memset function receives the pointer and its size as arguments. It is possibly a mistake.
Inspect the third argument. bg_animation.c 776
static void BG_ParseCommands( char **input,
animScriptItem_t *scriptItem, animModelInfo_t *animModelInfo,
animScriptData_t *scriptData )
{
// TTimo gcc: might be used uninitialized
animScriptCommand_t *command = NULL;
...
memset( command, 0, sizeof( command ) );
.
4
V564 The '&' operator is applied to bool type value. You've probably forgotten to include parentheses or
intended to use the '&&' operator. bg_pmove.c 3257
static void PM_Weapon( void ) {
...
if ( !pm->ps->pm_flags & PMF_LIMBO ) {
PM_CoolWeapons();
}
, ,
.
5

V523 The 'then' statement is equivalent to the 'else' statement. bg_pmove.c 4115
static void PM_Weapon( void ) {
...
if ( DotProduct( pml.forward, pm->ps->velocity ) > 0

{
VectorScale( pml.forward, -1.f * ( fwdmove_knockback / mass ),
kvel );

// -1 as we get knocked backwards

} else {
VectorScale( pml.forward, -1.f * ( fwdmove_knockback / mass ),
kvel );

// -1 as we get knocked backwards

}
. ,
.
6
V579 The memset function receives the pointer and its size as arguments. It is possibly a mistake.
Inspect the third argument. cg_character.c 308
static qboolean CG_CheckForExistingAnimModelInfo(
const char *animationGroup, const char *animationScript,
animModelInfo_t **animModelInfo )
{
...
memset( *animModelInfo, 0, sizeof( *animModelInfo ) );
, ,
.
7
V519 The 'backColor[2]' variable is assigned values twice successively. Perhaps this is a mistake. Check
lines: 3180, 3181. cg_draw.c 3181
typedef vec_t vec4_t[4];
static void CG_DrawObjectiveInfo( void ) {
...
vec4_t backColor;

backColor[0] = 0.2f;
backColor[1] = 0.2f;
backColor[2] = 0.2f;
backColor[2] = 1.f;
.
8
V556 The values of different enum types are compared: switch(ENUM_TYPE_A) { case ENUM_TYPE_B: ...
}. cg_newdraw.c 720
typedef enum {qfalse, qtrue}

qboolean;

qboolean eventHandling;
void CG_MouseEvent( int x, int y ) {
switch ( cgs.eventHandling ) {
case CGAME_EVENT_SPEAKEREDITOR:
case CGAME_EVENT_GAMEVIEW:
case CGAME_EVENT_CAMPAIGNBREIFING:
case CGAME_EVENT_FIRETEAMMSG:
switch case enum.
9
V568 It's odd that the argument of sizeof() operator is the '& itemInfo' expression. cg_weapons.c 1631
void CG_RegisterItemVisuals( int itemNum ) {
itemInfo_t *itemInfo;
...
memset( itemInfo, 0, sizeof( &itemInfo ) );
memset , .
10
V557 Array overrun is possible. The '3' index is pointing beyond array bound. q_math.c
typedef vec_t vec3_t[3];
void RotatePointAroundVertex( vec3_t pnt, float rot_x,
float rot_y, float rot_z, const vec3_t origin )
{

...
// rotate point
pnt[0] = ( tmp[3] * ( tmp[8] - tmp[9] ) + pnt[3] * tmp[2] );
pnt[3] .
11
V557 Array overrun is possible. The 'sizeof (bs->teamleader)' index is pointing beyond array bound.
ai_cmd.c 1037
char teamleader[32]; //netname of the team leader
...
bs->teamleader[sizeof( bs->teamleader )] = '\0';
sizeof() - 1.
12
V564 The '&' operator is applied to bool type value. You've probably forgotten to include parentheses or
intended to use the '&&' operator. ai_dmq3.c
if ( !g_entities[client].r.svFlags & SVF_BOT ) {
return;
}
- ,
.
13
V562 It's odd to compare 0 or 1 with a value of 2. ai_main.c 2659
if ( !level.clients[0].pers.connected == CON_CONNECTED ) {
return;
}
.
14
V557 Array overrun is possible. The value of 'i' index could reach 4. g_systemmsg.c 157
#define NUM_PLAYER_CLASSES

void G_CheckForNeededClasses( void ) {


qboolean playerClasses[NUM_PLAYER_CLASSES - 1][2];

...
for ( i = 0; i < NUM_PLAYER_CLASSES; i++ ) {
if ( !playerClasses[i][0] ) {
cnt++;
}
}
.
15
V557 Array overrun is possible. The '3' index is pointing beyond array bound. tr_shade_calc.c 679
void RB_CalcColorFromOneMinusEntity( unsigned char *dstColors ) {
...
unsigned char invModulate[3];
...
invModulate[0] = 255 - backEnd.currentEntity->e.shaderRGBA[0];
invModulate[1] = 255 - backEnd.currentEntity->e.shaderRGBA[1];
invModulate[2] = 255 - backEnd.currentEntity->e.shaderRGBA[2];
invModulate[3] = 255 - backEnd.currentEntity->e.shaderRGBA[3];
// this trashes alpha, but the AGEN block fixes it
.
16
V579 The memset function receives the pointer and its size as arguments. It is possibly a mistake.
Inspect the third argument. cvar.c 905
void Cvar_Restart_f( void ) {
cvar_t

*var;

...
memset( var, 0, sizeof( var ) );
, . sizeof(*var).
17
V519 The 'fwdmove_knockback' variable is assigned values twice successively. Perhaps this is a mistake.
Check lines: 4097, 4098. bg_pmove.c 4098

static void PM_Weapon( void ) {


...
if ( !( pm->ps->eFlags & EF_PRONE ) && (
pml.groundTrace.surfaceFlags & SURF_SLICK ) ) {
float fwdmove_knockback = 0.f;
float bckmove_knockback = 0.f;

switch ( pm->ps->weapon ) {
case WP_MOBILE_MG42:

fwdmove_knockback = 4000.f;

fwdmove_knockback = 400.f;
break;
case WP_PANZERFAUST:

fwdmove_knockback = 32000.f;

bckmove_knockback = 1200.f;
break;
case WP_FLAMETHROWER:

fwdmove_knockback = 2000.f;

bckmove_knockback = 40.f;
break;
}
WP_MOBILE_MG42 .

() Wolfenstein:
Enemy Territory
Cppcheck: 8.
PVS-Studio: 17.
( Cppcheck, PVS-Studio): 6.
, .


Doom 3
Cppcheck: 4.
PVS-Studio: 17.

( Cppcheck, PVS-Studio): 3.

Quake 3: Arena
Cppcheck: 6.
PVS-Studio: 7.
( Cppcheck, PVS-Studio): 2.

Wolfenstein: Enemy Territory


Cppcheck: 8.
PVS-Studio: 17.
( Cppcheck, PVS-Studio): 6.

, .

" "
. ,
. , .
. . ,
- . ? ,
: " Cppcheck?".


1.
2.
3.
4.

Cppcheck.
. Cppcheck.
PVS-Studio.
id Software on GitHub.