[Bug libitm/63907] libitm/config/posix/rwlock.cc doesn't compile

2018-03-12 Thread dvitek at grammatech dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63907

--- Comment #13 from David Vitek  ---
Created attachment 43639
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43639=edit
hack for g++4.5.3 and old libc compatibility

This is a nasty hack and you should check that your system's definition of
PTHREAD_COND_INITIALIZER is all zeroes before using it.

[Bug libitm/63907] libitm/config/posix/rwlock.cc doesn't compile

2018-03-12 Thread dvitek at grammatech dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63907

--- Comment #12 from David Vitek  ---
Created attachment 43638
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43638=edit
patch for g++7.3 and old libc

This patch fixes the parse error with newer versions of g++

[Bug libitm/63907] libitm/config/posix/rwlock.cc doesn't compile

2018-03-12 Thread dvitek at grammatech dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63907

David Vitek  changed:

   What|Removed |Added

 CC||dvitek at grammatech dot com

--- Comment #11 from David Vitek  ---
I ran into this and figured out a solution.  There are actually two different
issues at play depending on which version of g++ is trying to build rwlock.cc.

g++ 7.3 can't deal with PTHREAD_COND_INITIALIZER being surrounded by parens in
the initializer list.  If we take away the parens, it parses great with g++
7.3.  I suspect this could be fixed in version control.  Specifically, the
string literal in the older definition of PTHREAD_COND_INITIALIZER does not
want to be converted to a character array.

g++ 4.5.3 refuses to parse any formulation I've been able to think of unless I
make the initializer list completely empty.  It just so happens that
PTHREAD_COND_INITIALIZER is a zero initializer with my libc, so the empty
initializer list is sufficient but abstraction-breaking.  You couldn't safely
commit this workaround to version control.

Details:
PTHREAD_COND_INITIALIZER expands to {{ 0, 0 }, 0, "", 0}

Here is the definition of pthread_cond_t:
struct _pthread_fastlock
{
  long int __status;
  int __spinlock;

};
typedef struct _pthread_descr_struct *_pthread_descr;
__extension__ typedef long long __pthread_cond_align_t;
typedef struct
{
  struct _pthread_fastlock __c_lock;
  _pthread_descr __c_waiting;
  char __padding[48 - sizeof (struct _pthread_fastlock)
   - sizeof (_pthread_descr) - sizeof (__pthread_cond_align_t)];
  __pthread_cond_align_t __align;
} pthread_cond_t;


struct S{
pthread_cond_t x;
/* g++ 7.3: error: no matching function for call to
'pthread_cond_t::pthread_cond_t()'
 * g++ 4.5.3: error: could not convert '{{0, 0}, 0, "", 0}' to
'pthread_cond_t'
 */
S() : x (PTHREAD_COND_INITIALIZER) {}
};


// Now without the parens:
struct S{
pthread_cond_t x;
/* g++ 7.3: Success!
 * g++ 4.5.3: error: could not convert '{{0, 0}, 0, "", 0}' to
'pthread_cond_t'
 */
S() : x PTHREAD_COND_INITIALIZER {}
};


Here are some stand-alone diagnostics that elucidate the root cause:

g++ 4.5.3 can't handle this code even with -std=gnu++0x.  I wasn't able to come
up with anything viable here besides {}.
struct S{
struct inner{
char A[1];
} x;
/* could not convert '{{0}}' to 'S::inner' */
S() : x {{0}} {};
};

g++ 7.3 doesn't like this:
struct R{
struct inner{
char __padding[1];
} x;
/* error: no matching function for call to 'R::inner::inner()' */
R() : x ({""}) {};
};

but it does like this:
struct R{
struct inner{
char __padding[1];
} x;
// OK
R() : x {""} {};
};

Two patches forthcoming...