Fossil SCM

Proposed workaround for long double compiler bug on OpenBSD/sparc64.

edward 2013-05-02 07:01 trunk
Commit c11d1444e660280c6fc4f0b4d1519b44219ed54f
+27 -1
--- auto.def
+++ auto.def
@@ -1,8 +1,8 @@
11
# System autoconfiguration. Try: ./configure --help
22
3
-use cc cc-lib
3
+use cc cc-lib cc-run
44
55
options {
66
with-openssl:path|auto|none
77
=> {Look for openssl in the given path, or auto or none}
88
with-zlib:path => {Look for zlib in the given path}
@@ -232,8 +232,34 @@
232232
if {![cc-check-functions getpassphrase]} {
233233
# Haiku needs this
234234
cc-check-function-in-lib getpass bsd
235235
}
236236
cc-check-function-in-lib dlopen dl
237
+
238
+# Check for long double bug
239
+# See test/long-double.test for more information.
240
+set code {
241
+ volatile long long n; volatile long double ld;
242
+ n = 2147483648L; ld = n;
243
+ if (ld < 0) return 1;
244
+}
245
+switch -glob -- [get-define host] {
246
+ sparc64-*-openbsd* {
247
+ msg-checking "Checking for long double bug..."
248
+ # If we're cross compiling we won't be able to run
249
+ # binaries at all, so first check and see if a trivial
250
+ # program runs okay.
251
+ if {[cc-run -code {return 0;}]} {
252
+ if {[cc-run -code $code]} {
253
+ msg-result "not found"
254
+ } else {
255
+ msg-result "found"
256
+ define-append EXTRA_CFLAGS -DLONGDOUBLE_TYPE=double
257
+ }
258
+ } else {
259
+ msg-result "Unable to test, assuming bug not present"
260
+ }
261
+ }
262
+}
237263
238264
make-template Makefile.in
239265
make-config-header autoconfig.h -auto {USE_* FOSSIL_*}
240266
241267
ADDED autosetup/cc-run.tcl
242268
ADDED test/long-double.test
--- auto.def
+++ auto.def
@@ -1,8 +1,8 @@
1 # System autoconfiguration. Try: ./configure --help
2
3 use cc cc-lib
4
5 options {
6 with-openssl:path|auto|none
7 => {Look for openssl in the given path, or auto or none}
8 with-zlib:path => {Look for zlib in the given path}
@@ -232,8 +232,34 @@
232 if {![cc-check-functions getpassphrase]} {
233 # Haiku needs this
234 cc-check-function-in-lib getpass bsd
235 }
236 cc-check-function-in-lib dlopen dl
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
238 make-template Makefile.in
239 make-config-header autoconfig.h -auto {USE_* FOSSIL_*}
240
241 DDED autosetup/cc-run.tcl
242 DDED test/long-double.test
--- auto.def
+++ auto.def
@@ -1,8 +1,8 @@
1 # System autoconfiguration. Try: ./configure --help
2
3 use cc cc-lib cc-run
4
5 options {
6 with-openssl:path|auto|none
7 => {Look for openssl in the given path, or auto or none}
8 with-zlib:path => {Look for zlib in the given path}
@@ -232,8 +232,34 @@
232 if {![cc-check-functions getpassphrase]} {
233 # Haiku needs this
234 cc-check-function-in-lib getpass bsd
235 }
236 cc-check-function-in-lib dlopen dl
237
238 # Check for long double bug
239 # See test/long-double.test for more information.
240 set code {
241 volatile long long n; volatile long double ld;
242 n = 2147483648L; ld = n;
243 if (ld < 0) return 1;
244 }
245 switch -glob -- [get-define host] {
246 sparc64-*-openbsd* {
247 msg-checking "Checking for long double bug..."
248 # If we're cross compiling we won't be able to run
249 # binaries at all, so first check and see if a trivial
250 # program runs okay.
251 if {[cc-run -code {return 0;}]} {
252 if {[cc-run -code $code]} {
253 msg-result "not found"
254 } else {
255 msg-result "found"
256 define-append EXTRA_CFLAGS -DLONGDOUBLE_TYPE=double
257 }
258 } else {
259 msg-result "Unable to test, assuming bug not present"
260 }
261 }
262 }
263
264 make-template Makefile.in
265 make-config-header autoconfig.h -auto {USE_* FOSSIL_*}
266
267 DDED autosetup/cc-run.tcl
268 DDED test/long-double.test
--- a/autosetup/cc-run.tcl
+++ b/autosetup/cc-run.tcl
@@ -0,0 +1,165 @@
1
+# @synopsis:
2
+#
3
+# The 'cc-run' module provides a way to compile and run a bit of
4
+# code. This is not cross compilation friendly and is therefore
5
+# against autosetup's general philosophy, but is sometimes the only
6
+# way to perform a test.
7
+#
8
+
9
+use cc
10
+
11
+module-options {}
12
+
13
+# cc-run is based on cctest in cc.tcl.
14
+
15
+# @cc-run ?settings?
16
+#
17
+# Low level C/C++ program checker. Compiles, links, and runs a small
18
+# C/C++ program according to the arguments and returns 1 if OK, or 0
19
+# if not.
20
+#
21
+# Supported settings are:
22
+#
23
+## -cflags cflags A list of flags to pass to the compiler
24
+## -includes list A list of includes, e.g. {stdlib.h stdio.h}
25
+## -declare code Code to declare before main()
26
+## -lang c|c++ Use the C (default) or C++ compiler
27
+## -libs liblist List of libraries to link, e.g. {-ldl -lm}
28
+## -code code Code to compile in the body of main()
29
+## -source code Compile a complete program. Ignore -includes, -declare and -code
30
+## -sourcefile file Shorthand for -source [readfile [get-define srcdir]/$file]
31
+#
32
+# Unless -source or -sourcefile is specified, the C program looks like:
33
+#
34
+## #include <firstinclude> /* same for remaining includes in the list */
35
+##
36
+## declare-code /* any code in -declare, verbatim */
37
+##
38
+## int main(void) {
39
+## code /* any code in -code, verbatim */
40
+## return 0;
41
+## }
42
+#
43
+# Any failures are recorded in 'config.log'
44
+#
45
+proc cc-run {args} {
46
+ set src conftest__.c
47
+ set tmp conftest__
48
+
49
+ # Easiest way to merge in the settings
50
+ cc-with $args {
51
+ array set opts [cc-get-settings]
52
+ }
53
+
54
+ if {[info exists opts(-sourcefile)]} {
55
+ set opts(-source) [readfile [get-define srcdir]/$opts(-sourcefile) "#error can't find $opts(-sourcefile)"]
56
+ }
57
+ if {[info exists opts(-source)]} {
58
+ set lines $opts(-source)
59
+ } else {
60
+ foreach i $opts(-includes) {
61
+ if {$opts(-code) ne "" && ![feature-checked $i]} {
62
+ # Compiling real code with an unchecked header file
63
+ # Quickly (and silently) check for it now
64
+
65
+ # Remove all -includes from settings before checking
66
+ set saveopts [cc-update-settings -includes {}]
67
+ msg-quiet cc-check-includes $i
68
+ cc-store-settings $saveopts
69
+ }
70
+ if {$opts(-code) eq "" || [have-feature $i]} {
71
+ lappend source "#include <$i>"
72
+ }
73
+ }
74
+ lappend source {*}$opts(-declare)
75
+ lappend source "int main(void) {"
76
+ lappend source $opts(-code)
77
+ lappend source "return 0;"
78
+ lappend source "}"
79
+
80
+ set lines [join $source \n]
81
+ }
82
+
83
+ # Build the command line
84
+ set cmdline {}
85
+ lappend cmdline {*}[get-define CCACHE]
86
+ switch -exact -- $opts(-lang) {
87
+ c++ {
88
+ lappend cmdline {*}[get-define CXX] {*}[get-define CXXFLAGS]
89
+ }
90
+ c {
91
+ lappend cmdline {*}[get-define CC] {*}[get-define CFLAGS]
92
+ }
93
+ default {
94
+ autosetup-error "cc-run called with unknown language: $opts(-lang)"
95
+ }
96
+ }
97
+
98
+ lappend cmdline {*}$opts(-cflags)
99
+
100
+ switch -glob -- [get-define host] {
101
+ *-*-darwin* {
102
+ # Don't generate .dSYM directories
103
+ lappend cmdline -gstabs
104
+ }
105
+ }
106
+ lappend cmdline $src -o $tmp {*}$opts(-libs)
107
+
108
+ # At this point we have the complete command line and the
109
+ # complete source to be compiled. Get the result from cache if
110
+ # we can
111
+ if {[info exists ::cc_cache($cmdline,$lines)]} {
112
+ msg-checking "(cached) "
113
+ set ok $::cc_cache($cmdline,$lines)
114
+ if {$::autosetup(debug)} {
115
+ configlog "From cache (ok=$ok): [join $cmdline]"
116
+ configlog "============"
117
+ configlog $lines
118
+ configlog "============"
119
+ }
120
+ return $ok
121
+ }
122
+
123
+ writefile $src $lines\n
124
+
125
+ set ok 1
126
+ if {[catch {exec-with-stderr {*}$cmdline} result errinfo]} {
127
+ configlog "Failed: [join $cmdline]"
128
+ configlog $result
129
+ configlog "============"
130
+ configlog "The failed code was:"
131
+ configlog $lines
132
+ configlog "============"
133
+ set ok 0
134
+ } else {
135
+ if {$::autosetup(debug)} {
136
+ configlog "Compiled OK: [join $cmdline]"
137
+ configlog "============"
138
+ configlog $lines
139
+ configlog "============"
140
+ }
141
+ if {[catch {exec-with-stderr ./$tmp} result errinfo]} {
142
+ configlog "Failed: $tmp"
143
+ configlog $result
144
+ configlog "============"
145
+ configlog "The failed code was:"
146
+ configlog $lines
147
+ configlog "============"
148
+ set ok 0
149
+ } else {
150
+ if {$::autosetup(debug)} {
151
+ configlog "Ran OK: $tmp"
152
+ configlog "============"
153
+ configlog $lines
154
+ configlog "============"
155
+ }
156
+ }
157
+ }
158
+ file delete $src
159
+ file delete $tmp
160
+
161
+ # cache it
162
+ set ::cc_cache($cmdline,$lines) $ok
163
+
164
+ return $ok
165
+}
--- a/autosetup/cc-run.tcl
+++ b/autosetup/cc-run.tcl
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/autosetup/cc-run.tcl
+++ b/autosetup/cc-run.tcl
@@ -0,0 +1,165 @@
1 # @synopsis:
2 #
3 # The 'cc-run' module provides a way to compile and run a bit of
4 # code. This is not cross compilation friendly and is therefore
5 # against autosetup's general philosophy, but is sometimes the only
6 # way to perform a test.
7 #
8
9 use cc
10
11 module-options {}
12
13 # cc-run is based on cctest in cc.tcl.
14
15 # @cc-run ?settings?
16 #
17 # Low level C/C++ program checker. Compiles, links, and runs a small
18 # C/C++ program according to the arguments and returns 1 if OK, or 0
19 # if not.
20 #
21 # Supported settings are:
22 #
23 ## -cflags cflags A list of flags to pass to the compiler
24 ## -includes list A list of includes, e.g. {stdlib.h stdio.h}
25 ## -declare code Code to declare before main()
26 ## -lang c|c++ Use the C (default) or C++ compiler
27 ## -libs liblist List of libraries to link, e.g. {-ldl -lm}
28 ## -code code Code to compile in the body of main()
29 ## -source code Compile a complete program. Ignore -includes, -declare and -code
30 ## -sourcefile file Shorthand for -source [readfile [get-define srcdir]/$file]
31 #
32 # Unless -source or -sourcefile is specified, the C program looks like:
33 #
34 ## #include <firstinclude> /* same for remaining includes in the list */
35 ##
36 ## declare-code /* any code in -declare, verbatim */
37 ##
38 ## int main(void) {
39 ## code /* any code in -code, verbatim */
40 ## return 0;
41 ## }
42 #
43 # Any failures are recorded in 'config.log'
44 #
45 proc cc-run {args} {
46 set src conftest__.c
47 set tmp conftest__
48
49 # Easiest way to merge in the settings
50 cc-with $args {
51 array set opts [cc-get-settings]
52 }
53
54 if {[info exists opts(-sourcefile)]} {
55 set opts(-source) [readfile [get-define srcdir]/$opts(-sourcefile) "#error can't find $opts(-sourcefile)"]
56 }
57 if {[info exists opts(-source)]} {
58 set lines $opts(-source)
59 } else {
60 foreach i $opts(-includes) {
61 if {$opts(-code) ne "" && ![feature-checked $i]} {
62 # Compiling real code with an unchecked header file
63 # Quickly (and silently) check for it now
64
65 # Remove all -includes from settings before checking
66 set saveopts [cc-update-settings -includes {}]
67 msg-quiet cc-check-includes $i
68 cc-store-settings $saveopts
69 }
70 if {$opts(-code) eq "" || [have-feature $i]} {
71 lappend source "#include <$i>"
72 }
73 }
74 lappend source {*}$opts(-declare)
75 lappend source "int main(void) {"
76 lappend source $opts(-code)
77 lappend source "return 0;"
78 lappend source "}"
79
80 set lines [join $source \n]
81 }
82
83 # Build the command line
84 set cmdline {}
85 lappend cmdline {*}[get-define CCACHE]
86 switch -exact -- $opts(-lang) {
87 c++ {
88 lappend cmdline {*}[get-define CXX] {*}[get-define CXXFLAGS]
89 }
90 c {
91 lappend cmdline {*}[get-define CC] {*}[get-define CFLAGS]
92 }
93 default {
94 autosetup-error "cc-run called with unknown language: $opts(-lang)"
95 }
96 }
97
98 lappend cmdline {*}$opts(-cflags)
99
100 switch -glob -- [get-define host] {
101 *-*-darwin* {
102 # Don't generate .dSYM directories
103 lappend cmdline -gstabs
104 }
105 }
106 lappend cmdline $src -o $tmp {*}$opts(-libs)
107
108 # At this point we have the complete command line and the
109 # complete source to be compiled. Get the result from cache if
110 # we can
111 if {[info exists ::cc_cache($cmdline,$lines)]} {
112 msg-checking "(cached) "
113 set ok $::cc_cache($cmdline,$lines)
114 if {$::autosetup(debug)} {
115 configlog "From cache (ok=$ok): [join $cmdline]"
116 configlog "============"
117 configlog $lines
118 configlog "============"
119 }
120 return $ok
121 }
122
123 writefile $src $lines\n
124
125 set ok 1
126 if {[catch {exec-with-stderr {*}$cmdline} result errinfo]} {
127 configlog "Failed: [join $cmdline]"
128 configlog $result
129 configlog "============"
130 configlog "The failed code was:"
131 configlog $lines
132 configlog "============"
133 set ok 0
134 } else {
135 if {$::autosetup(debug)} {
136 configlog "Compiled OK: [join $cmdline]"
137 configlog "============"
138 configlog $lines
139 configlog "============"
140 }
141 if {[catch {exec-with-stderr ./$tmp} result errinfo]} {
142 configlog "Failed: $tmp"
143 configlog $result
144 configlog "============"
145 configlog "The failed code was:"
146 configlog $lines
147 configlog "============"
148 set ok 0
149 } else {
150 if {$::autosetup(debug)} {
151 configlog "Ran OK: $tmp"
152 configlog "============"
153 configlog $lines
154 configlog "============"
155 }
156 }
157 }
158 file delete $src
159 file delete $tmp
160
161 # cache it
162 set ::cc_cache($cmdline,$lines) $ok
163
164 return $ok
165 }
--- a/test/long-double.test
+++ b/test/long-double.test
@@ -0,0 +1,71 @@
1
+#
2
+# OpenBSD on 64 bit SPARC has what appears to be a complier bug involving
3
+# the "long double" type. This has been observed on OpenBSD 5.1 and 5.2
4
+# using the bundled gcc compiler (gcc (GCC) 4.2.1 20070719).
5
+#
6
+# The following progam demonstrates the problem:
7
+#
8
+# #include <stdio.h>
9
+#
10
+# int
11
+# main (int argc, char *argv[])
12
+# {
13
+# volatile long long n;
14
+# volatile long double ld;
15
+#
16
+# n = 2147483648L;
17
+# ld = n;
18
+# printf (" n = %lld\n", n);
19
+# printf ("ld = %0.17Lg\n", ld);
20
+#
21
+# return 0;
22
+# }
23
+#
24
+# Example output, on an x86 system without the bug:
25
+# n = 2147483648
26
+# ld = 2147483648
27
+#
28
+# Example output, on an OpenBSD/sparc64 system with the bug:
29
+# n = 2147483648
30
+# ld = -2147483648
31
+#
32
+# The bug manifests itself in Fossil by way of a long double in
33
+# SQLite's internal sqlite3AtoF() function.
34
+#
35
+# An example demonstrating the bug using Fossil:
36
+#
37
+# $ ./fossil new x.fossil
38
+# $ ./fossil sqlite3 -R x.fossil
39
+# sqlite> select 2456247.35094206;
40
+# -2456247.35094206
41
+# sqlite> .quit
42
+#
43
+# See also:
44
+#
45
+# [fossil-users] System problem leads to Fossil problem on OpenBSD/sparc64
46
+# http://www.mail-archive.com/[email protected]/msg11144.html
47
+#
48
+
49
+# Fossil will write data on $HOME, running 'fossil new' here.
50
+# We need not to clutter the $HOME of the test caller.
51
+set env(HOME) [pwd]
52
+
53
+fossil new rep.fossil
54
+
55
+proc long-double {testname args} {
56
+ set i 1
57
+ foreach {sql result} $args {
58
+ set out [open test.sql w]
59
+ puts $out $sql
60
+ close $out
61
+ fossil sqlite3 -R rep.fossil < test.sql
62
+ test long-double-$testname.$i {$::RESULT eq $result}
63
+ incr i
64
+ }
65
+}
66
+
67
+# Returns "-2456247.35094206" on systems with the long double compiler bug.
68
+long-double 100 "select 2456247.35094206;" "2456247.35094206"
69
+
70
+file delete rep.fossil
71
+file delete test.sql
--- a/test/long-double.test
+++ b/test/long-double.test
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/test/long-double.test
+++ b/test/long-double.test
@@ -0,0 +1,71 @@
1 #
2 # OpenBSD on 64 bit SPARC has what appears to be a complier bug involving
3 # the "long double" type. This has been observed on OpenBSD 5.1 and 5.2
4 # using the bundled gcc compiler (gcc (GCC) 4.2.1 20070719).
5 #
6 # The following progam demonstrates the problem:
7 #
8 # #include <stdio.h>
9 #
10 # int
11 # main (int argc, char *argv[])
12 # {
13 # volatile long long n;
14 # volatile long double ld;
15 #
16 # n = 2147483648L;
17 # ld = n;
18 # printf (" n = %lld\n", n);
19 # printf ("ld = %0.17Lg\n", ld);
20 #
21 # return 0;
22 # }
23 #
24 # Example output, on an x86 system without the bug:
25 # n = 2147483648
26 # ld = 2147483648
27 #
28 # Example output, on an OpenBSD/sparc64 system with the bug:
29 # n = 2147483648
30 # ld = -2147483648
31 #
32 # The bug manifests itself in Fossil by way of a long double in
33 # SQLite's internal sqlite3AtoF() function.
34 #
35 # An example demonstrating the bug using Fossil:
36 #
37 # $ ./fossil new x.fossil
38 # $ ./fossil sqlite3 -R x.fossil
39 # sqlite> select 2456247.35094206;
40 # -2456247.35094206
41 # sqlite> .quit
42 #
43 # See also:
44 #
45 # [fossil-users] System problem leads to Fossil problem on OpenBSD/sparc64
46 # http://www.mail-archive.com/[email protected]/msg11144.html
47 #
48
49 # Fossil will write data on $HOME, running 'fossil new' here.
50 # We need not to clutter the $HOME of the test caller.
51 set env(HOME) [pwd]
52
53 fossil new rep.fossil
54
55 proc long-double {testname args} {
56 set i 1
57 foreach {sql result} $args {
58 set out [open test.sql w]
59 puts $out $sql
60 close $out
61 fossil sqlite3 -R rep.fossil < test.sql
62 test long-double-$testname.$i {$::RESULT eq $result}
63 incr i
64 }
65 }
66
67 # Returns "-2456247.35094206" on systems with the long double compiler bug.
68 long-double 100 "select 2456247.35094206;" "2456247.35094206"
69
70 file delete rep.fossil
71 file delete test.sql

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button