Making gcc warn about dead code pertaining to out of scope variable.

vijay nag vijunag@gmail.com
Wed Sep 25 07:09:00 GMT 2013


Hello,

I recently upgraded to GCC-4.7.2 and it has unabashedly exposed
various bugs in the code base which the old gcc compiler simply
couldn't.  I'm little concerned about breakage/regressions caused by
subtle GCC optimizations.

Let me describe the problem that I have been observing.  I have pasted
the code snippet at the end of this mail so that it can be easily
reproduced.

The below macro declares/defines two local block variables local_addr
and remote_addr.  At higher optimization level i.e. at -O2, gcc seems
to be eliminating the call to memset(dead-code) for it knows for sure
that __remote_addr has reached the end of its scope, however at
optimization level -O0 I do see a call to memcpy.  The code below is
surely buggy, however I was wondering if there is any option to make
GCC emit warnings on encountering such code. That way it will help us
identify and fix  several such incantations in our large code base.

#define FILL_TRANSPORT_INFO(_params)  \
do { \
  _ip_addr_t _local_addr;                                           \
  _ip_addr_t _remote_addr;                                          \
  _ZERO_VARIABLE(_local_addr);                                          \
  _ZERO_VARIABLE(_remote_addr);                                          \
  (_local_addr).ip_ver = SNX_IPV4_VERSION; \
  (_local_addr)._ip_addr_t_u.ipv4 = 283725;\
  memcpy(&(_remote_addr), &((_params)->addr), sizeof(_ip_addr_t));\
  (_params)->local_addr =  &_local_addr;\
  (_params)->remote_addr = &_remote_addr;\
} while(0);



#include <stdio.h>
#include <string.h>

typedef unsigned int u_int;

#define _MAX_IP_LEN   50
#define _IPV4_VERSION  4
#define _IPV6_VERSION  6
#define _IPV4V6_VERSION  10
#define _IPV6_BYTES 16

typedef struct {
  int ip_ver;
  union {
    u_int ipv4;
    u_int ipv6[4];
  } _ip_addr_t_u;
}_ip_addr_t;


#define SN_ZERO_VARIABLE(var) \
  memset(&(var), 0, sizeof(var));

typedef struct sn_ip_params {
  _ip_addr_t addr;
  _ip_addr_t *local_addr;
  _ip_addr_t *remote_addr;
} _ip_params;

#define FILL_TRANSPORT_INFO(_params)  \
do { \
  _ip_addr_t _local_addr;                                           \
  _ip_addr_t _remote_addr;                                          \
  _ZERO_VARIABLE(_local_addr);                                          \
  _ZERO_VARIABLE(_remote_addr);                                          \
  (_local_addr).ip_ver = _IPV4_VERSION; \
  (_local_addr)._ip_addr_t_u.ipv4 = 283725;\
  memcpy(&(_remote_addr), &((_params)->addr), sizeof(_ip_addr_t));\
  (_params)->local_addr =  &_local_addr;\
  (_params)->remote_addr = &_remote_addr;\
} while(0);

int main()
{
   _ip_params params;

   params.addr.ip_ver = _IPV4_VERSION;
   params.addr._ip_addr_t_u.ipv4 = 283725;

   FILL_TRANSPORT_INFO(&params);

   if (_IPV4_VERSION != params.local_addr->ip_ver) {
     fprintf(stderr, "Initialization failed\n");
   } else {
     fprintf(stderr, "IPV4 value = %d\n", params.local_addr->_ip_addr_t_u.ipv4);
   }

   return 0;
}

Binary at -O2 : i686-pc-linux-gnu -g -O2 gcc_test.c -std=c99 -pedantic
-Wall -Werror -o gcc_test
./gcc_test
Initialization failed

Binary at -O0: i686-pc-linux-gnu -g -OO gcc_test.c -std=c99 -pedantic
-Wall -Werror -o gcc_test
./gcc_test
IPV4 value = 283725



More information about the Gcc-help mailing list