Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

7.2alpha6 fails to compile with clang #14

Closed
apetresc opened this issue Feb 27, 2012 · 26 comments
Closed

7.2alpha6 fails to compile with clang #14

apetresc opened this issue Feb 27, 2012 · 26 comments

Comments

@apetresc
Copy link

Users of Homebrew have noticed the following problems when compiling with the default clang: 1 and 2.

The issue seems to be around the following macro:

libtool: compile:  /usr/bin/clang -DHAVE_CONFIG_H -I./include -I./include -I./libatomic_ops/src -I./libatomic_ops/src -fexceptions -Os -w -pipe -march=native -Qunused-arguments -c os_dep.c  -fno-common -DPIC -o .libs/os_dep.o
misc.c:943:7: error: array size is negative
      GC_STATIC_ASSERT((ptr_t)(word)(-1) > (ptr_t)0);
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/private/gc_priv.h:2143:51: note: expanded from macro 'GC_STATIC_ASSERT'
# define GC_STATIC_ASSERT(expr) (void)sizeof(char[(expr)? 1 : -1])
                                                  ^~~~~~~~~~~~~~
1 error generated.

Nobody is quite sure what that macro is intended to be doing (whether it is a bug in clang or a bug in the macro which clang exposes), but in either case it seems like something we should report upstream.

It compiles cleanly with LLVM.

@jacknagel
Copy link

Note that Apple clang 3.0 (211) from Xcode 4.2 compiles this, but the clang shipping with Xcode 4.3 does not.

@hboehm
Copy link
Collaborator

hboehm commented Feb 28, 2012

The code is checking that pointer comparisons behave like unsigned comparisons. It's purely a sanity check to preclude some subtle runtime bugs. The fact that it fails does not guarantee that the compiler is broken. In fact, in the version that I looked at, some platforms are exempted from this test. I don't remember doing that, which may mean that I forgot, or that someone else (Ivan Maidanski?) added the code.

I would guess that this is unintentional clang behavior. It's testing the behavior of nonportable code, so it may not really be a bug, but it seems weird. (If the compiler defines the GNUC macro, it arguably is a bug, since gcc doesn't behave this way.)

My guess is that it will cause the collector to break only if the OS allows memory mappings that cross the middle of the address space, i.e. the point at which pointer values "change sign", and only if runtime tests have the same issue. I would guess that 32-bit Linux allows this, so if the same clang front end is supposed to work there, it may be an issue.

My strategy would be:

  1. Check what the compiler thinks (char *)(size_t)(-1) > (char *)0 evaluates to. My guess is it evaluates to 0 (false). Which is weird.

  2. Ask the clang developers if they really meant to do this. If they say no, ask them to fix it.

  3. If they don't want to fix it, post a fix to gc@linux.hpl.hp.com that exempts clang from this sanity check, and see if someone can come with a reason not to apply it.

Hans

-----Original Message-----
From: Adrian Petrescu [mailto:reply+i-3407693-
23939a8efc49588c3792edc50b63c0f931b08474-1000362@reply.github.com]
Sent: Monday, February 27, 2012 12:30 PM
To: Boehm, Hans
Subject: [bdwgc] 7.2alpha6 fails to compile with clang (#14)

Users of Homebrew have noticed the following problems when compiling
with the default clang:
1
and 2.

The issue seems to be around the following macro:

libtool: compile:  /usr/bin/clang -DHAVE_CONFIG_H -I./include -
I./include -I./libatomic_ops/src -I./libatomic_ops/src -fexceptions -Os
-w -pipe -march=native -Qunused-arguments -c os_dep.c  -fno-common -
DPIC -o .libs/os_dep.o
misc.c:943:7: error: array size is negative
      GC_STATIC_ASSERT((ptr_t)(word)(-1) > (ptr_t)0);
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/private/gc_priv.h:2143:51: note: expanded from macro
'GC_STATIC_ASSERT'
# define GC_STATIC_ASSERT(expr) (void)sizeof(char[(expr)? 1 : -1])
                                                  ^~~~~~~~~~~~~~
1 error generated.

Nobody is quite sure what that macro is intended to be doing (whether
it is a bug in clang or a bug in the macro which clang exposes), but in
either case it seems like something we should report upstream.

It compiles cleanly with LLVM.


Reply to this email directly or view it on GitHub:
#14

@ivmai
Copy link
Owner

ivmai commented Feb 28, 2012

Hi Adrian,

28 02 2012, 00:30 Adrian Petrescu reply@reply.github.com:

Users of Homebrew have noticed the following problems when compiling with the default clang: 1 and 2.

The issue seems to be around the following macro:

libtool: compile:  /usr/bin/clang -DHAVE_CONFIG_H -I./include -I./include -I./libatomic_ops/src -I./libatomic_ops/src -fexceptions -Os -w -pipe -march=native -Qunused-arguments -c os_dep.c  -fno-common -DPIC -o .libs/os_dep.o
misc.c:943:7: error: array size is negative
      GC_STATIC_ASSERT((ptr_t)(word)(-1) > (ptr_t)0);
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/private/gc_priv.h:2143:51: note: expanded from macro 'GC_STATIC_ASSERT'
# define GC_STATIC_ASSERT(expr) (void)sizeof(char[(expr)? 1 : -1])
                                                  ^~~~~~~~~~~~~~
1 error generated.

This macro is intended to check whether compiler treats pointer comparison as unsigned integer comparison or not.
BDWGC requires pointers to be treated as unsigned integers in comparisons (this really matters if data address space occupies both halves of 4 GiB space).

It seems that used version of clang is broken regarding this issue (we can add a workaround (like we've done for ancient Borland compiler) in the hope that the produced executable won't be used in environments with both halves of 4 GiB space.

The alternative, better, solution is to cast pointers to word whenever compared (requires a lot of work).

BTW. What's the version of that 'default' clang?

I tried:
clang version 1.1 (branches/release_27)
Target: i386-pc-linux-gnu

It works ok except for test_stack - something wrong with the atomic intrinsics.

Regards.

Nobody is quite sure what that macro is intended to be doing (whether it is a bug in clang or a bug in the macro which clang exposes), but in either case it seems like something we should report upstream.

It compiles cleanly with LLVM.


Reply to this email directly or view it on GitHub:
#14

@pwagland
Copy link

Hi ivmai,

For me it also fails with clang:

$ clang --version
Apple clang version 3.1 (tags/Apple/clang-318.0.45) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin11.3.0
Thread model: posix

Cheers,
Paul

@hboehm
Copy link
Collaborator

hboehm commented Feb 29, 2012

On 29 Feb 2012, at 00:05, Boehm, Hans wrote:

We seem to be having several parallel conversations about this. Please keep further posts on the gc mailing list.

I think the crucial question is whether clang thinks

(char *)(size_t)(-1) > (char *)0

evaluates to 0 or 1, which should be a pretty simple test. That may depend on whether you're using a 32-bit or 64-bit compilation model and possibly on other compiler flags. We all think 1 is the right answer, though no standard requires that. (Except possibly clang claims to be gcc, and gcc says so?) Could someone for whom this is failing confirm that the answer is zero and post the compilation flags?

I get that error (see below) when compiling bdwg from repository with clang (see below) in 64-bit mode, but not in 32-bit mode. It compiles using llvm-gcc (see below) in 64-bitmode.

When running clang on this program:
int main() {
printf("%4d ", (char *)(size_t)(-1) > (char *)0);
return 0;
}
I get 1, both in 32- and 64-bit mode.

Hans

It is the clang one gets from latest Xvcode 4.3 developer package on OS X 10.7.3:
$ clang --version
Apple clang version 3.1 (tags/Apple/clang-318.0.45) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin11.3.0
Thread model: posix

LLVM-GCC:
/usr/bin/gcc -> llvm-gcc-4.2
$ /usr/bin/gcc --version
i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.9.00)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Makefile error:

libtool: compile: clang -DHAVE_CONFIG_H -I./include -I../bdwgc/include -I./libatomic_ops/src -I../bdwgc/libatomic_ops/src -fexceptions -Wall -Wextra -g -O2 -fno-strict-aliasing -MT misc.lo -MD -MP -MF .deps/misc.Tpo -c ../bdwgc/misc.c -fno-common -DPIC -o .libs/misc.o
../bdwgc/misc.c:953:7: error: array size is negative
GC_STATIC_ASSERT((ptr_t)(word)(-1) > (ptr_t)0);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../bdwgc/include/private/gc_priv.h:2182:51: note: expanded from macro 'GC_STATIC_ASSERT'

define GC_STATIC_ASSERT(expr) (void)sizeof(char[(expr)? 1 : -1])

                                              ^~~~~~~~~~~~~~

1 error generated.
make[1]: *** [misc.lo] Error 1
make: *** [all-recursive] Error 1

1 similar comment
@ivmai
Copy link
Owner

ivmai commented Feb 29, 2012

On 29 Feb 2012, at 00:05, Boehm, Hans wrote:

We seem to be having several parallel conversations about this. Please keep further posts on the gc mailing list.

I think the crucial question is whether clang thinks

(char *)(size_t)(-1) > (char *)0

evaluates to 0 or 1, which should be a pretty simple test. That may depend on whether you're using a 32-bit or 64-bit compilation model and possibly on other compiler flags. We all think 1 is the right answer, though no standard requires that. (Except possibly clang claims to be gcc, and gcc says so?) Could someone for whom this is failing confirm that the answer is zero and post the compilation flags?

I get that error (see below) when compiling bdwg from repository with clang (see below) in 64-bit mode, but not in 32-bit mode. It compiles using llvm-gcc (see below) in 64-bitmode.

When running clang on this program:
int main() {
printf("%4d ", (char *)(size_t)(-1) > (char *)0);
return 0;
}
I get 1, both in 32- and 64-bit mode.

Hans

It is the clang one gets from latest Xvcode 4.3 developer package on OS X 10.7.3:
$ clang --version
Apple clang version 3.1 (tags/Apple/clang-318.0.45) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin11.3.0
Thread model: posix

LLVM-GCC:
/usr/bin/gcc -> llvm-gcc-4.2
$ /usr/bin/gcc --version
i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.9.00)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Makefile error:

libtool: compile: clang -DHAVE_CONFIG_H -I./include -I../bdwgc/include -I./libatomic_ops/src -I../bdwgc/libatomic_ops/src -fexceptions -Wall -Wextra -g -O2 -fno-strict-aliasing -MT misc.lo -MD -MP -MF .deps/misc.Tpo -c ../bdwgc/misc.c -fno-common -DPIC -o .libs/misc.o
../bdwgc/misc.c:953:7: error: array size is negative
GC_STATIC_ASSERT((ptr_t)(word)(-1) > (ptr_t)0);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../bdwgc/include/private/gc_priv.h:2182:51: note: expanded from macro 'GC_STATIC_ASSERT'

define GC_STATIC_ASSERT(expr) (void)sizeof(char[(expr)? 1 : -1])

                                              ^~~~~~~~~~~~~~

1 error generated.
make[1]: *** [misc.lo] Error 1
make: *** [all-recursive] Error 1

@ivmai
Copy link
Owner

ivmai commented Feb 29, 2012

On 29 Feb 2012, at 00:05, Boehm, Hans wrote:

We seem to be having several parallel conversations about this. Please keep further posts on the gc mailing list.

I think the crucial question is whether clang thinks

(char *)(size_t)(-1) > (char *)0

evaluates to 0 or 1, which should be a pretty simple test.

It seems to be a bug in 64-bit clang. I have run the program below, made by replacing the compiling line of the file misc.c with preprocessing, on various compilers. All produce the output
1, 1
except clang in 64-bit mode, which produces
-1, 1
Strangely, the ?: operator causes clang to produce the result to be 0.

The compilers I tried were
clang -arch i386
clang
llvm-gcc-4.2
as in the post before, the compilers that on OS X 10.7.3 comes with Xcode 4.3.

(In this version of Xcode, /usr/bin/cc -> clang and /usr/bin/gcc -> llvm-gcc-4.2. Before that, also /usr/bin/cc pointed to llvm. So packages that call for cc, now will use clang instead of llvm-gcc.)

I also tried gcc-4.7 from the repository
$ gcc --version
gcc (GCC) 4.7.0 20120115 (experimental)

Hans

---- clang_test.c ----

#include <stdio.h>

typedef unsigned long word;
typedef char* ptr_t;

int main() {
#if 0
/* Line that produces error in clang 64-bit mode */
(void)sizeof(char[((ptr_t)(word)(-1) > (ptr_t)0)? 1 : -1]);
#endif

int k = ((ptr_t)(word)(-1) > (ptr_t)0)? 1 : -1;
int l = ((ptr_t)(word)(-1) > (ptr_t)0);

printf("%d, %d\n", k, l);
return 0;
}


1 similar comment
@hboehm
Copy link
Collaborator

hboehm commented Feb 29, 2012

On 29 Feb 2012, at 00:05, Boehm, Hans wrote:

We seem to be having several parallel conversations about this. Please keep further posts on the gc mailing list.

I think the crucial question is whether clang thinks

(char *)(size_t)(-1) > (char *)0

evaluates to 0 or 1, which should be a pretty simple test.

It seems to be a bug in 64-bit clang. I have run the program below, made by replacing the compiling line of the file misc.c with preprocessing, on various compilers. All produce the output
1, 1
except clang in 64-bit mode, which produces
-1, 1
Strangely, the ?: operator causes clang to produce the result to be 0.

The compilers I tried were
clang -arch i386
clang
llvm-gcc-4.2
as in the post before, the compilers that on OS X 10.7.3 comes with Xcode 4.3.

(In this version of Xcode, /usr/bin/cc -> clang and /usr/bin/gcc -> llvm-gcc-4.2. Before that, also /usr/bin/cc pointed to llvm. So packages that call for cc, now will use clang instead of llvm-gcc.)

I also tried gcc-4.7 from the repository
$ gcc --version
gcc (GCC) 4.7.0 20120115 (experimental)

Hans

---- clang_test.c ----

#include <stdio.h>

typedef unsigned long word;
typedef char* ptr_t;

int main() {
#if 0
/* Line that produces error in clang 64-bit mode */
(void)sizeof(char[((ptr_t)(word)(-1) > (ptr_t)0)? 1 : -1]);
#endif

int k = ((ptr_t)(word)(-1) > (ptr_t)0)? 1 : -1;
int l = ((ptr_t)(word)(-1) > (ptr_t)0);

printf("%d, %d\n", k, l);
return 0;
}


@hboehm
Copy link
Collaborator

hboehm commented Mar 1, 2012

That sounds like a good explanation.

You checked that word and ptr_t are defined correctly for the 64-bit setting?

Hans B.

-----Original Message-----
From: Hans Aberg [mailto:haberg-1@telia.com]
Sent: Wednesday, February 29, 2012 7:18 AM
To: Boehm, Hans
Cc: Ivan Maidanski; Adrian Petrescu; pwagland; gc@linux.hpl.hp.com
Subject: Re: [Gc] [bdwgc] 7.2alpha6 fails to compile with clang (#14)

On 29 Feb 2012, at 00:05, Boehm, Hans wrote:

We seem to be having several parallel conversations about this.
Please keep further posts on the gc mailing list.

I think the crucial question is whether clang thinks

(char *)(size_t)(-1) > (char *)0

evaluates to 0 or 1, which should be a pretty simple test.

It seems to be a bug in 64-bit clang. I have run the program below,
made by replacing the compiling line of the file misc.c with
preprocessing, on various compilers. All produce the output
1, 1
except clang in 64-bit mode, which produces
-1, 1
Strangely, the ?: operator causes clang to produce the result to be 0.

The compilers I tried were
clang -arch i386
clang
llvm-gcc-4.2
as in the post before, the compilers that on OS X 10.7.3 comes with
Xcode 4.3.

(In this version of Xcode, /usr/bin/cc -> clang and /usr/bin/gcc ->
llvm-gcc-4.2. Before that, also /usr/bin/cc pointed to llvm. So
packages that call for cc, now will use clang instead of llvm-gcc.)

I also tried gcc-4.7 from the repository
$ gcc --version
gcc (GCC) 4.7.0 20120115 (experimental)

Hans

---- clang_test.c ----

#include <stdio.h>

typedef unsigned long word;
typedef char* ptr_t;

int main() {
#if 0
/* Line that produces error in clang 64-bit mode */
(void)sizeof(char[((ptr_t)(word)(-1) > (ptr_t)0)? 1 : -1]);
#endif

int k = ((ptr_t)(word)(-1) > (ptr_t)0)? 1 : -1;
int l = ((ptr_t)(word)(-1) > (ptr_t)0);

printf("%d, %d\n", k, l);
return 0;
}


1 similar comment
@ivmai
Copy link
Owner

ivmai commented Mar 1, 2012

That sounds like a good explanation.

You checked that word and ptr_t are defined correctly for the 64-bit setting?

Hans B.

-----Original Message-----
From: Hans Aberg [mailto:haberg-1@telia.com]
Sent: Wednesday, February 29, 2012 7:18 AM
To: Boehm, Hans
Cc: Ivan Maidanski; Adrian Petrescu; pwagland; gc@linux.hpl.hp.com
Subject: Re: [Gc] [bdwgc] 7.2alpha6 fails to compile with clang (#14)

On 29 Feb 2012, at 00:05, Boehm, Hans wrote:

We seem to be having several parallel conversations about this.
Please keep further posts on the gc mailing list.

I think the crucial question is whether clang thinks

(char *)(size_t)(-1) > (char *)0

evaluates to 0 or 1, which should be a pretty simple test.

It seems to be a bug in 64-bit clang. I have run the program below,
made by replacing the compiling line of the file misc.c with
preprocessing, on various compilers. All produce the output
1, 1
except clang in 64-bit mode, which produces
-1, 1
Strangely, the ?: operator causes clang to produce the result to be 0.

The compilers I tried were
clang -arch i386
clang
llvm-gcc-4.2
as in the post before, the compilers that on OS X 10.7.3 comes with
Xcode 4.3.

(In this version of Xcode, /usr/bin/cc -> clang and /usr/bin/gcc ->
llvm-gcc-4.2. Before that, also /usr/bin/cc pointed to llvm. So
packages that call for cc, now will use clang instead of llvm-gcc.)

I also tried gcc-4.7 from the repository
$ gcc --version
gcc (GCC) 4.7.0 20120115 (experimental)

Hans

---- clang_test.c ----

#include <stdio.h>

typedef unsigned long word;
typedef char* ptr_t;

int main() {
#if 0
/* Line that produces error in clang 64-bit mode */
(void)sizeof(char[((ptr_t)(word)(-1) > (ptr_t)0)? 1 : -1]);
#endif

int k = ((ptr_t)(word)(-1) > (ptr_t)0)? 1 : -1;
int l = ((ptr_t)(word)(-1) > (ptr_t)0);

printf("%d, %d\n", k, l);
return 0;
}


@ivmai
Copy link
Owner

ivmai commented Mar 1, 2012

On 1 Mar 2012, at 01:43, Boehm, Hans wrote:

That sounds like a good explanation.

You checked that word and ptr_t are defined correctly for the 64-bit setting?

The values are those that I got from preprocessing with clang in 64-bit mode, the case that failed. When you say it, they could be defined differently in the other compiles that worked, for example in 32-but mode. But
typedef unsigned long word;
typedef char* ptr_t;
seems right for 64-bit mode.

Strictly speaking it is
typedef unsigned long GC_word;
typedef GC_word word;

Hans

1 similar comment
@hboehm
Copy link
Collaborator

hboehm commented Mar 1, 2012

On 1 Mar 2012, at 01:43, Boehm, Hans wrote:

That sounds like a good explanation.

You checked that word and ptr_t are defined correctly for the 64-bit setting?

The values are those that I got from preprocessing with clang in 64-bit mode, the case that failed. When you say it, they could be defined differently in the other compiles that worked, for example in 32-but mode. But
typedef unsigned long word;
typedef char* ptr_t;
seems right for 64-bit mode.

Strictly speaking it is
typedef unsigned long GC_word;
typedef GC_word word;

Hans

@ivmai
Copy link
Owner

ivmai commented Mar 1, 2012

On 1 Mar 2012, at 01:43, Boehm, Hans wrote:

You checked that word and ptr_t are defined correctly for the 64-bit setting?

They are all defined the same, also in the 32-bit compile 'clang -arch i386'.

Hans

1 similar comment
@hboehm
Copy link
Collaborator

hboehm commented Mar 1, 2012

On 1 Mar 2012, at 01:43, Boehm, Hans wrote:

You checked that word and ptr_t are defined correctly for the 64-bit setting?

They are all defined the same, also in the 32-bit compile 'clang -arch i386'.

Hans

@hboehm
Copy link
Collaborator

hboehm commented Mar 1, 2012

On 1 Mar 2012, at 10:45, Ivan Maidanski wrote:

I've changed all pointer relational comparisons (except for !=) to word ones (in "master" branch) and removed that check - I'll commit the patch next week.
For the "release" branch, I'll add a workaround to just skip that assertion for clang-x64.

I filed a bug-report to Apple.

Hans

1 similar comment
@ivmai
Copy link
Owner

ivmai commented Mar 1, 2012

On 1 Mar 2012, at 10:45, Ivan Maidanski wrote:

I've changed all pointer relational comparisons (except for !=) to word ones (in "master" branch) and removed that check - I'll commit the patch next week.
For the "release" branch, I'll add a workaround to just skip that assertion for clang-x64.

I filed a bug-report to Apple.

Hans

@ivmai
Copy link
Owner

ivmai commented Mar 4, 2012

Hi Hans A.,

I've added a workaround for the bug to "release" branch - please test it.
(I've post the alternate solution to "master" branch on Monday after testing.)

Regards.

01 03 2012, 21:43 Hans Aberg haberg-1@telia.com:

On 1 Mar 2012, at 10:45, Ivan Maidanski wrote:

I've changed all pointer relational comparisons (except for !=) to word ones (in "master" branch) and removed that check - I'll commit the patch next week.
For the "release" branch, I'll add a workaround to just skip that assertion for clang-x64.

I filed a bug-report to Apple.

Hans

1 similar comment
@hboehm
Copy link
Collaborator

hboehm commented Mar 4, 2012

Hi Hans A.,

I've added a workaround for the bug to "release" branch - please test it.
(I've post the alternate solution to "master" branch on Monday after testing.)

Regards.

01 03 2012, 21:43 Hans Aberg haberg-1@telia.com:

On 1 Mar 2012, at 10:45, Ivan Maidanski wrote:

I've changed all pointer relational comparisons (except for !=) to word ones (in "master" branch) and removed that check - I'll commit the patch next week.
For the "release" branch, I'll add a workaround to just skip that assertion for clang-x64.

I filed a bug-report to Apple.

Hans

@hboehm
Copy link
Collaborator

hboehm commented Mar 4, 2012

Hi Hans A.,

This is known (caused by using deprecated API) but could anybody propose a fix for it?

Regards.

04 03 2012, 15:55 Hans Aberg haberg-1@telia.com:

On 4 Mar 2012, at 11:50, Ivan Maidanski wrote:

I've added a workaround for the bug to "release" branch - please test it.
(I've post the alternate solution to "master" branch on Monday after testing.)

It compiled, from 'git clone --branch "release" ...', and all 10 'make check' tests passed, though I got 3 warnings (below), and linker comments (even further below).

Hans


libtool: compile: /usr/bin/clang -DHAVE_CONFIG_H -I./include -I../bdwgc/include -I./libatomic_ops/src -I../bdwgc/libatomic_ops/src -fexceptions -g -O2 -fno-strict-aliasing -MT dyn_load.lo -MD -MP -MF .deps/dyn_load.Tpo -c ../bdwgc/dyn_load.c -fno-common -DPIC -o .libs/dyn_load.o
../bdwgc/dyn_load.c:1379:37: warning: incompatible pointer types passing 'void (const struct mach_header_64 , intptr_t)' to parameter of type
'void (
)(const struct mach_header _, intptr_t)' [-Wincompatible-pointer-types]
_dyld_register_func_for_add_image(GC_dyld_image_add);
^~~~~~~~~~~~~~~~~
/usr/include/mach-o/dyld.h:61:54: note: passing argument to parameter 'func' here
extern void _dyld_register_func_for_add_image(void (_func)(const struct mach_header* mh, intptr_t vmaddr_slide)) ...
^
../bdwgc/dyn_load.c:1380:40: warning: incompatible pointer types passing 'void (const struct mach_header_64 , intptr_t)' to parameter of type
'void (
)(const struct mach_header _, intptr_t)' [-Wincompatible-pointer-types]
_dyld_register_func_for_remove_image(GC_dyld_image_remove);
^~~~~~~~~~~~~~~~~~~~
/usr/include/mach-o/dyld.h:62:57: note: passing argument to parameter 'func' here
extern void _dyld_register_func_for_remove_image(void (_func)(const struct mach_header* mh, intptr_t vmaddr_slide)) ...
^
../bdwgc/dyn_load.c:1403:12: warning: '_dyld_bind_fully_image_containing_address' is deprecated [-Wdeprecated-declarations]
if (!_dyld_bind_fully_image_containing_address(
^
3 warnings generated.


libtool: link: ar cru .libs/libgc.a allchblk.o alloc.o blacklst.o checksums.o dbg_mlc.o dyn_load.o finalize.o gc_dlopen.o gcj_mlc.o headers.o malloc.o mallocx.o mark.o mark_rts.o misc.o new_hblk.o obj_map.o os_dep.o pcr_interface.o ptr_chck.o real_malloc.o reclaim.o specific.o stubborn.o typd_mlc.o backgraph.o thread_local_alloc.o pthread_start.o pthread_support.o pthread_stop_world.o darwin_stop_world.o atomic_ops.o mach_dep.o
/usr/bin/ranlib: file: .libs/libgc.a(checksums.o) has no symbols
/usr/bin/ranlib: file: .libs/libgc.a(gc_dlopen.o) has no symbols
/usr/bin/ranlib: file: .libs/libgc.a(pcr_interface.o) has no symbols
/usr/bin/ranlib: file: .libs/libgc.a(real_malloc.o) has no symbols
/usr/bin/ranlib: file: .libs/libgc.a(specific.o) has no symbols
/usr/bin/ranlib: file: .libs/libgc.a(backgraph.o) has no symbols
/usr/bin/ranlib: file: .libs/libgc.a(pthread_stop_world.o) has no symbols
libtool: link: ranlib .libs/libgc.a
ranlib: file: .libs/libgc.a(checksums.o) has no symbols
ranlib: file: .libs/libgc.a(gc_dlopen.o) has no symbols
ranlib: file: .libs/libgc.a(pcr_interface.o) has no symbols
ranlib: file: .libs/libgc.a(real_malloc.o) has no symbols
ranlib: file: .libs/libgc.a(specific.o) has no symbols
ranlib: file: .libs/libgc.a(backgraph.o) has no symbols
ranlib: file: .libs/libgc.a(pthread_stop_world.o) has no symbols
libtool: link: ( cd ".libs" && rm -f "libgc.la" && ln -s "../libgc.la" "libgc.la" )

/bin/sh ./libtool --tag=CC --mode=compile /usr/bin/clang -DHAVE_CONFIG_H -I./include -I../bdwgc/include -I./libatomic_ops/src -I../bdwgc/libatomic_ops/src -fexceptions -g -O2 -fno-strict-aliasing -MT cordbscs.lo -MD -MP -MF .deps/cordbscs.Tpo -c -o cordbscs.lo test -f 'cord/cordbscs.c' || echo '../bdwgc/'cord/cordbscs.c

1 similar comment
@ivmai
Copy link
Owner

ivmai commented Mar 4, 2012

Hi Hans A.,

This is known (caused by using deprecated API) but could anybody propose a fix for it?

Regards.

04 03 2012, 15:55 Hans Aberg haberg-1@telia.com:

On 4 Mar 2012, at 11:50, Ivan Maidanski wrote:

I've added a workaround for the bug to "release" branch - please test it.
(I've post the alternate solution to "master" branch on Monday after testing.)

It compiled, from 'git clone --branch "release" ...', and all 10 'make check' tests passed, though I got 3 warnings (below), and linker comments (even further below).

Hans


libtool: compile: /usr/bin/clang -DHAVE_CONFIG_H -I./include -I../bdwgc/include -I./libatomic_ops/src -I../bdwgc/libatomic_ops/src -fexceptions -g -O2 -fno-strict-aliasing -MT dyn_load.lo -MD -MP -MF .deps/dyn_load.Tpo -c ../bdwgc/dyn_load.c -fno-common -DPIC -o .libs/dyn_load.o
../bdwgc/dyn_load.c:1379:37: warning: incompatible pointer types passing 'void (const struct mach_header_64 , intptr_t)' to parameter of type
'void (
)(const struct mach_header _, intptr_t)' [-Wincompatible-pointer-types]
_dyld_register_func_for_add_image(GC_dyld_image_add);
^~~~~~~~~~~~~~~~~
/usr/include/mach-o/dyld.h:61:54: note: passing argument to parameter 'func' here
extern void _dyld_register_func_for_add_image(void (_func)(const struct mach_header* mh, intptr_t vmaddr_slide)) ...
^
../bdwgc/dyn_load.c:1380:40: warning: incompatible pointer types passing 'void (const struct mach_header_64 , intptr_t)' to parameter of type
'void (
)(const struct mach_header _, intptr_t)' [-Wincompatible-pointer-types]
_dyld_register_func_for_remove_image(GC_dyld_image_remove);
^~~~~~~~~~~~~~~~~~~~
/usr/include/mach-o/dyld.h:62:57: note: passing argument to parameter 'func' here
extern void _dyld_register_func_for_remove_image(void (_func)(const struct mach_header* mh, intptr_t vmaddr_slide)) ...
^
../bdwgc/dyn_load.c:1403:12: warning: '_dyld_bind_fully_image_containing_address' is deprecated [-Wdeprecated-declarations]
if (!_dyld_bind_fully_image_containing_address(
^
3 warnings generated.


libtool: link: ar cru .libs/libgc.a allchblk.o alloc.o blacklst.o checksums.o dbg_mlc.o dyn_load.o finalize.o gc_dlopen.o gcj_mlc.o headers.o malloc.o mallocx.o mark.o mark_rts.o misc.o new_hblk.o obj_map.o os_dep.o pcr_interface.o ptr_chck.o real_malloc.o reclaim.o specific.o stubborn.o typd_mlc.o backgraph.o thread_local_alloc.o pthread_start.o pthread_support.o pthread_stop_world.o darwin_stop_world.o atomic_ops.o mach_dep.o
/usr/bin/ranlib: file: .libs/libgc.a(checksums.o) has no symbols
/usr/bin/ranlib: file: .libs/libgc.a(gc_dlopen.o) has no symbols
/usr/bin/ranlib: file: .libs/libgc.a(pcr_interface.o) has no symbols
/usr/bin/ranlib: file: .libs/libgc.a(real_malloc.o) has no symbols
/usr/bin/ranlib: file: .libs/libgc.a(specific.o) has no symbols
/usr/bin/ranlib: file: .libs/libgc.a(backgraph.o) has no symbols
/usr/bin/ranlib: file: .libs/libgc.a(pthread_stop_world.o) has no symbols
libtool: link: ranlib .libs/libgc.a
ranlib: file: .libs/libgc.a(checksums.o) has no symbols
ranlib: file: .libs/libgc.a(gc_dlopen.o) has no symbols
ranlib: file: .libs/libgc.a(pcr_interface.o) has no symbols
ranlib: file: .libs/libgc.a(real_malloc.o) has no symbols
ranlib: file: .libs/libgc.a(specific.o) has no symbols
ranlib: file: .libs/libgc.a(backgraph.o) has no symbols
ranlib: file: .libs/libgc.a(pthread_stop_world.o) has no symbols
libtool: link: ( cd ".libs" && rm -f "libgc.la" && ln -s "../libgc.la" "libgc.la" )

/bin/sh ./libtool --tag=CC --mode=compile /usr/bin/clang -DHAVE_CONFIG_H -I./include -I../bdwgc/include -I./libatomic_ops/src -I../bdwgc/libatomic_ops/src -fexceptions -g -O2 -fno-strict-aliasing -MT cordbscs.lo -MD -MP -MF .deps/cordbscs.Tpo -c -o cordbscs.lo test -f 'cord/cordbscs.c' || echo '../bdwgc/'cord/cordbscs.c

@hboehm
Copy link
Collaborator

hboehm commented Mar 4, 2012

On 4 Mar 2012, at 13:15, Ivan Maidanski wrote:

This is known (caused by using deprecated API) but could anybody propose a fix for it?

As you note, it seems deprecated. The only difference between the structs mach_header_64 and mach_header is that the former has an added field which seems to do nothing (see below). So it may have been added in order to pay attention that it should not be used.

The fix would be to not call _dyld_register_func_for_add_image() and _dyld_register_func_for_remove_image() in a 64-bit compile, since it will probably break.

Hans


/*

  • The 32-bit mach header appears at the very beginning of the object file for
  • 32-bit architectures.
    /
    struct mach_header {
    uint32_t magic; /
    mach magic number identifier /
    cpu_type_t cputype; /
    cpu specifier /
    cpu_subtype_t cpusubtype; /
    machine specifier /
    uint32_t filetype; /
    type of file /
    uint32_t ncmds; /
    number of load commands /
    uint32_t sizeofcmds; /
    the size of all the load commands /
    uint32_t flags; /
    flags */
    };

/* Constant for the magic field of the mach_header (32-bit architectures) /
#define MH_MAGIC 0xfeedface /
the mach magic number /
#define MH_CIGAM 0xcefaedfe /
NXSwapInt(MH_MAGIC) */

/*

  • The 64-bit mach header appears at the very beginning of object files for
  • 64-bit architectures.
    /
    struct mach_header_64 {
    uint32_t magic; /
    mach magic number identifier /
    cpu_type_t cputype; /
    cpu specifier /
    cpu_subtype_t cpusubtype; /
    machine specifier /
    uint32_t filetype; /
    type of file /
    uint32_t ncmds; /
    number of load commands /
    uint32_t sizeofcmds; /
    the size of all the load commands /
    uint32_t flags; /
    flags /
    uint32_t reserved; /
    reserved */
    };

/* Constant for the magic field of the mach_header_64 (64-bit architectures) /
#define MH_MAGIC_64 0xfeedfacf /
the 64-bit mach magic number */

#define MH_CIGAM_64 0xcffaedfe /* NXSwapInt(MH_MAGIC_64) */

1 similar comment
@ivmai
Copy link
Owner

ivmai commented Mar 4, 2012

On 4 Mar 2012, at 13:15, Ivan Maidanski wrote:

This is known (caused by using deprecated API) but could anybody propose a fix for it?

As you note, it seems deprecated. The only difference between the structs mach_header_64 and mach_header is that the former has an added field which seems to do nothing (see below). So it may have been added in order to pay attention that it should not be used.

The fix would be to not call _dyld_register_func_for_add_image() and _dyld_register_func_for_remove_image() in a 64-bit compile, since it will probably break.

Hans


/*

  • The 32-bit mach header appears at the very beginning of the object file for
  • 32-bit architectures.
    /
    struct mach_header {
    uint32_t magic; /
    mach magic number identifier /
    cpu_type_t cputype; /
    cpu specifier /
    cpu_subtype_t cpusubtype; /
    machine specifier /
    uint32_t filetype; /
    type of file /
    uint32_t ncmds; /
    number of load commands /
    uint32_t sizeofcmds; /
    the size of all the load commands /
    uint32_t flags; /
    flags */
    };

/* Constant for the magic field of the mach_header (32-bit architectures) /
#define MH_MAGIC 0xfeedface /
the mach magic number /
#define MH_CIGAM 0xcefaedfe /
NXSwapInt(MH_MAGIC) */

/*

  • The 64-bit mach header appears at the very beginning of object files for
  • 64-bit architectures.
    /
    struct mach_header_64 {
    uint32_t magic; /
    mach magic number identifier /
    cpu_type_t cputype; /
    cpu specifier /
    cpu_subtype_t cpusubtype; /
    machine specifier /
    uint32_t filetype; /
    type of file /
    uint32_t ncmds; /
    number of load commands /
    uint32_t sizeofcmds; /
    the size of all the load commands /
    uint32_t flags; /
    flags /
    uint32_t reserved; /
    reserved */
    };

/* Constant for the magic field of the mach_header_64 (64-bit architectures) /
#define MH_MAGIC_64 0xfeedfacf /
the 64-bit mach magic number */

#define MH_CIGAM_64 0xcffaedfe /* NXSwapInt(MH_MAGIC_64) */

@hboehm
Copy link
Collaborator

hboehm commented Mar 5, 2012

Hi the community,

04 03 2012, 16:51 Hans Aberg haberg-1@telia.com:

On 4 Mar 2012, at 13:15, Ivan Maidanski wrote:

This is known (caused by using deprecated API) but could anybody propose a fix for it?

As you note, it seems deprecated. The only difference between the structs mach_header_64 and mach_header is that the former has an added field which seems to do nothing (see below). So it may have been added in order to pay attention that it should not be used.

The fix would be to not call _dyld_register_func_for_add_image() and _dyld_register_func_for_remove_image() in a 64-bit compile, since it will probably break.

I'd like also to hear opinion about this from other Darwin experts.

Regards.

Hans


/*

  • The 32-bit mach header appears at the very beginning of the object file for
  • 32-bit architectures.
    /
    struct mach_header {
    uint32_t magic; /
    mach magic number identifier /
    cpu_type_t cputype; /
    cpu specifier /
    cpu_subtype_t cpusubtype; /
    machine specifier /
    uint32_t filetype; /
    type of file /
    uint32_t ncmds; /
    number of load commands /
    uint32_t sizeofcmds; /
    the size of all the load commands /
    uint32_t flags; /
    flags */
    };

/* Constant for the magic field of the mach_header (32-bit architectures) /
#define MH_MAGIC 0xfeedface /
the mach magic number /
#define MH_CIGAM 0xcefaedfe /
NXSwapInt(MH_MAGIC) */

/*

  • The 64-bit mach header appears at the very beginning of object files for
  • 64-bit architectures.
    /
    struct mach_header_64 {
    uint32_t magic; /
    mach magic number identifier /
    cpu_type_t cputype; /
    cpu specifier /
    cpu_subtype_t cpusubtype; /
    machine specifier /
    uint32_t filetype; /
    type of file /
    uint32_t ncmds; /
    number of load commands /
    uint32_t sizeofcmds; /
    the size of all the load commands /
    uint32_t flags; /
    flags /
    uint32_t reserved; /
    reserved */
    };

/* Constant for the magic field of the mach_header_64 (64-bit architectures) /
#define MH_MAGIC_64 0xfeedfacf /
the 64-bit mach magic number */

#define MH_CIGAM_64 0xcffaedfe /* NXSwapInt(MH_MAGIC_64) */

1 similar comment
@ivmai
Copy link
Owner

ivmai commented Mar 5, 2012

Hi the community,

04 03 2012, 16:51 Hans Aberg haberg-1@telia.com:

On 4 Mar 2012, at 13:15, Ivan Maidanski wrote:

This is known (caused by using deprecated API) but could anybody propose a fix for it?

As you note, it seems deprecated. The only difference between the structs mach_header_64 and mach_header is that the former has an added field which seems to do nothing (see below). So it may have been added in order to pay attention that it should not be used.

The fix would be to not call _dyld_register_func_for_add_image() and _dyld_register_func_for_remove_image() in a 64-bit compile, since it will probably break.

I'd like also to hear opinion about this from other Darwin experts.

Regards.

Hans


/*

  • The 32-bit mach header appears at the very beginning of the object file for
  • 32-bit architectures.
    /
    struct mach_header {
    uint32_t magic; /
    mach magic number identifier /
    cpu_type_t cputype; /
    cpu specifier /
    cpu_subtype_t cpusubtype; /
    machine specifier /
    uint32_t filetype; /
    type of file /
    uint32_t ncmds; /
    number of load commands /
    uint32_t sizeofcmds; /
    the size of all the load commands /
    uint32_t flags; /
    flags */
    };

/* Constant for the magic field of the mach_header (32-bit architectures) /
#define MH_MAGIC 0xfeedface /
the mach magic number /
#define MH_CIGAM 0xcefaedfe /
NXSwapInt(MH_MAGIC) */

/*

  • The 64-bit mach header appears at the very beginning of object files for
  • 64-bit architectures.
    /
    struct mach_header_64 {
    uint32_t magic; /
    mach magic number identifier /
    cpu_type_t cputype; /
    cpu specifier /
    cpu_subtype_t cpusubtype; /
    machine specifier /
    uint32_t filetype; /
    type of file /
    uint32_t ncmds; /
    number of load commands /
    uint32_t sizeofcmds; /
    the size of all the load commands /
    uint32_t flags; /
    flags /
    uint32_t reserved; /
    reserved */
    };

/* Constant for the magic field of the mach_header_64 (64-bit architectures) /
#define MH_MAGIC_64 0xfeedfacf /
the 64-bit mach magic number */

#define MH_CIGAM_64 0xcffaedfe /* NXSwapInt(MH_MAGIC_64) */

@ivmai ivmai closed this as completed Mar 7, 2012
@ivmai
Copy link
Owner

ivmai commented Sep 26, 2012

On 1 Mar 2012, at 18:41, Hans Aberg wrote:

On 1 Mar 2012, at 10:45, Ivan Maidanski wrote:

I've changed all pointer relational comparisons (except for !=) to word ones (in "master" branch) and removed that check - I'll commit the patch next week.
For the "release" branch, I'll add a workaround to just skip that assertion for clang-x64.

I filed a bug-report to Apple.

Apple has now fixed this problem for all 'clang' compilers that come with Xcode 4.5.

Specifically, the program below, both when using 'xcrun' (later compiler on Mac OS 10.7), and using 32- and 64-bit modes, now produces the output
1, 1
Before, in Xcode 4.3, /usr/bin/clang (i.e., 64-bit mode) produced the output
-1, 1

Hans


#include <stdio.h>

typedef unsigned long word;
typedef char* ptr_t;

int main() {
#if 1
/* Line that produces error in clang 64-bit mode. */
(void)sizeof(char[((ptr_t)(word)(-1) > (ptr_t)0)? 1 : -1]);
#endif

int k = ((ptr_t)(word)(-1) > (ptr_t)0)? 1 : -1;
int l = ((ptr_t)(word)(-1) > (ptr_t)0);

printf("%d, %d\n", k, l);
return 0;

}

1 similar comment
@hboehm
Copy link
Collaborator

hboehm commented Sep 26, 2012

On 1 Mar 2012, at 18:41, Hans Aberg wrote:

On 1 Mar 2012, at 10:45, Ivan Maidanski wrote:

I've changed all pointer relational comparisons (except for !=) to word ones (in "master" branch) and removed that check - I'll commit the patch next week.
For the "release" branch, I'll add a workaround to just skip that assertion for clang-x64.

I filed a bug-report to Apple.

Apple has now fixed this problem for all 'clang' compilers that come with Xcode 4.5.

Specifically, the program below, both when using 'xcrun' (later compiler on Mac OS 10.7), and using 32- and 64-bit modes, now produces the output
1, 1
Before, in Xcode 4.3, /usr/bin/clang (i.e., 64-bit mode) produced the output
-1, 1

Hans


#include <stdio.h>

typedef unsigned long word;
typedef char* ptr_t;

int main() {
#if 1
/* Line that produces error in clang 64-bit mode. */
(void)sizeof(char[((ptr_t)(word)(-1) > (ptr_t)0)? 1 : -1]);
#endif

int k = ((ptr_t)(word)(-1) > (ptr_t)0)? 1 : -1;
int l = ((ptr_t)(word)(-1) > (ptr_t)0);

printf("%d, %d\n", k, l);
return 0;

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants