Notes on bugs found by PVS-Studio in the Blender source code:
http://www.gamasutra.com/blogs/AndreyKarpov/20120423/169021/Analyzing_the_Blender_project_with_PVSStudio.php

#define  DEFAULT_STREAM  \
  m[dC] = RAC(ccel,dC); \
  \
  if((!nbored & CFBnd)) { \
  \
  ....


No one has implemented this yet :-(
http://d.puremagic.com/issues/show_bug.cgi?id=5409

---------------------------

void tcd_malloc_decode(....) {
  ...
  x0 = j == 0 ? tilec->x0 :
    int_min(x0, (unsigned int) tilec->x0);
  y0 = j == 0 ? tilec->y0 :
    int_min(y0, (unsigned int) tilec->x0);
  x1 = j == 0 ? tilec->x1 :
    int_max(x1, (unsigned int) tilec->x1);
  y1 = j == 0 ? tilec->y1 :
    int_max(y1, (unsigned int) tilec->y1);
  ...
}



This code was most likely created through the Copy-Paste technology and the programmer forgot to change the name of one variable during
editing. This is the correct code:

y0 = j == 0 ? tilec->y0 :
  int_min(y0, (unsigned int) tilec->y0);


To avoid such mistakes maybe the IDE has to offer a way to create such nearly-repeated lines of code, maybe writing a pattern like this:

  $ = j == 0 ? tilec->$ :
    int_min($, (unsigned int) tilec->$);

And then giving a list like [x0, y0, x1, y1] to fill it four times.
Dynamic languages are maybe able to do the same.

Or in D with something like:

foreach (s; TypeTuple!("x0", "y0", "x1", "y1")) {
    mixin("  $ = j == 0 ? tilec->$ :
int_min($, (unsigned int) tilec->$);".replace("$", s));

But it's not very readable, and replace() doesn't care if $ is present inside strings, where it must not be replaced.

-------------------------------

#define cpack(x) \
  glColor3ub( ((x)&0xFF), (((x)>>8)&0xFF), (((x)>>16)&0xFF) )
static void star_stuff_init_func(void)
{
  cpack(-1);
  glPointSize(1.0);
  glBegin(GL_POINTS);
}

PVS-Studio's warning: V610 Unspecified behavior.
Check the shift operator '>>. The left operand '(- 1)' is
negative. bf_editor_space_view3d view3d_draw.c 101

According to the C++ language standard, right shift of
a negative value leads to unspecified behavior. In practice
this method is often used but you shouldn't do that: it
cannot be guaranteed that the code will always work as
intended.

I suggest rewriting this code in the following way:

cpack(UINT_MAX);


Assigning -1 to an unsigned integer is a garbage way to code, expecially in D where uint.max/typeof(T).max are available with no need for imports.

-------------------------------

This kind of error is common:

static bool pi_next_rpcl(opj_pi_iterator_t * pi) {
  ...
  if ((res->pw==0)||(res->pw==0)) continue;
  ...
}

PVS-Studio's warning: V501 There are identical
sub-expressions to the left and to the right of
the '||' operator: (res->pw == 0) || (res->pw == 0)
extern_openjpeg pi.c 219


{
  ...
  if ((size_t(lhs0+alignedStart)%sizeof(LhsPacket))==0)
    for (Index i = alignedStart;i(&lhs0[i]),
                       ptmp0, pload(&res[i])));
  else
    for (Index i = alignedStart;i(&lhs0[i]),
                       ptmp0, pload(&res[i])));
  ...
}

PVS-Studio's warning: V523 The 'then' statement
is equivalent to the 'else' statement.

-------------------------------

I have also seen code that is essentially:

size_t x = ...;
if (x < 0) { ... }

It was not a way to disable code. And in D you have /+...+/ and version(none){...}.

Bye,
bearophile

Reply via email to