correctcomputation / checkedc-clang

This is the primary development repository for 3C, a tool for automatically converting legacy C code to the Checked C extension of C, which aims to enforce spatial memory safety. This repository is a fork of Checked C's.
14 stars 5 forks source link

Tool segfaults while handling initialization expressions. #148

Closed Machiry closed 4 years ago

Machiry commented 4 years ago

Consider the following code:

#include <sys/types.h> 
#include <sys/wait.h>

struct vsf_sysutil_wait_retval
{
  int syscall_retval;
  int exit_status;
};

struct vsf_sysutil_wait_retval vsf_sysutil_wait(void) {
    struct vsf_sysutil_wait_retval retval;
    int sys_ret = wait(&retval.exit_status);
    return retval;
}

Trying to convert the above file leads to the following exception:

`clang/lib/CConv/ConstraintResolver.cpp:475: std::set<ConstraintVariable*> ConstraintResolver::getExprConstraintVars(clang::Expr*): Assertion "InitlistExpr of type other than array or pointer in " "getExprConstraintVars" && ILE->getType()->isPointerType()' failed.

The init expression that causes the failure is:

InitListExpr 0xc5f0e80 '__WAIT_STATUS':'__WAIT_STATUS' field Field 0xc5e75f8 '__iptr' 'int *'
`-UnaryOperator 0xc5f0da8 'int *' prefix '&' cannot overflow
  `-MemberExpr 0xc5f0d70 'int' lvalue .exit_status 0xc5f0140
    `-DeclRefExpr 0xc5f0d48 'struct vsf_sysutil_wait_retval':'struct vsf_sysutil_wait_retval' lvalue Var 0xc5f03d0 'retval' 'struct vsf_sysutil_wait_retval':'struct vsf_sysutil_wait_retval'
john-h-kastner commented 4 years ago

I don't see a failure on this snippet.

Machiry commented 4 years ago

Are you using Mac? Can you try on pldev2?

Machiry commented 4 years ago

Can you try with this?

typedef union
  {
    union wait *__uptr;
    int *__iptr;
  } __WAIT_STATUS __attribute__ ((__transparent_union__));

  union wait
  {
    int w_status;
    struct
      {

 unsigned int __w_termsig:7;
 unsigned int __w_coredump:1;
 unsigned int __w_retcode:8;
 unsigned int:16;

      } __wait_terminated;
    struct
      {

 unsigned int __w_stopval:8;
 unsigned int __w_stopsig:8;
 unsigned int:16;

      } __wait_stopped;
  };

extern int wait (__WAIT_STATUS __stat_loc);

struct vsf_sysutil_wait_retval
{
  int syscall_retval;
  int exit_status;
};

struct vsf_sysutil_wait_retval vsf_sysutil_wait(void) {
    struct vsf_sysutil_wait_retval retval;
    int sys_ret = wait(&retval.exit_status);
    return retval;
}