summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2012-04-03 10:55:16 -0700
committerH.J. Lu <hjl.tools@gmail.com>2012-04-03 10:55:16 -0700
commit6a14926b44504e88488e3715b5b84928d454fb49 (patch)
tree9cf5f80773922c62ebd9ba07388a1f27354dc516
parentaabd700dee5d71eb0a8180fb3626a23da9a88fdd (diff)
parent749dea2a0549c126a0e992a6dd8e9b5eb28e1cee (diff)
downloadgcc-hjl/x32/java.tar.gz
Merge remote-tracking branch 'origin/master' into hjl/x32/javahjl/x32/java
-rw-r--r--config/ChangeLog9
-rw-r--r--config/math.m47
-rw-r--r--config/mmap.m46
-rw-r--r--gcc/ChangeLog276
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in3
-rw-r--r--gcc/acinclude.m493
-rw-r--r--gcc/aclocal.m41
-rw-r--r--gcc/ada/ChangeLog316
-rw-r--r--gcc/ada/Makefile.rtl1
-rw-r--r--gcc/ada/ali.adb10
-rw-r--r--gcc/ada/ali.ads5
-rw-r--r--gcc/ada/alloc.ads5
-rw-r--r--gcc/ada/bindgen.adb10
-rw-r--r--gcc/ada/csinfo.adb3
-rw-r--r--gcc/ada/debug.adb5
-rw-r--r--gcc/ada/einfo.adb4
-rw-r--r--gcc/ada/exp_attr.adb234
-rw-r--r--gcc/ada/exp_ch4.adb94
-rw-r--r--gcc/ada/exp_ch5.adb10
-rw-r--r--gcc/ada/exp_ch7.adb20
-rw-r--r--gcc/ada/exp_ch9.adb1221
-rw-r--r--gcc/ada/exp_pakd.adb12
-rw-r--r--gcc/ada/exp_util.adb244
-rw-r--r--gcc/ada/exp_util.ads39
-rw-r--r--gcc/ada/freeze.adb10
-rw-r--r--gcc/ada/g-expect.adb23
-rw-r--r--gcc/ada/g-sse.ads4
-rw-r--r--gcc/ada/gcc-interface/Makefile.in12
-rw-r--r--gcc/ada/gcc-interface/decl.c18
-rw-r--r--gcc/ada/gnat_ugn.texi27
-rw-r--r--gcc/ada/lib-writ.adb22
-rw-r--r--gcc/ada/lib-xref-alfa.adb1135
-rw-r--r--gcc/ada/lib-xref.adb157
-rw-r--r--gcc/ada/lib-xref.ads9
-rw-r--r--gcc/ada/opt.ads5
-rw-r--r--gcc/ada/osint.adb11
-rw-r--r--gcc/ada/osint.ads5
-rw-r--r--gcc/ada/prj-attr.adb3
-rw-r--r--gcc/ada/prj-nmsc.adb6
-rw-r--r--gcc/ada/prj.adb2
-rw-r--r--gcc/ada/prj.ads33
-rw-r--r--gcc/ada/rtsfind.ads27
-rw-r--r--gcc/ada/s-atopri.ads122
-rw-r--r--gcc/ada/sem.adb4
-rw-r--r--gcc/ada/sem_attr.adb11
-rw-r--r--gcc/ada/sem_attr.ads33
-rw-r--r--gcc/ada/sem_ch12.adb52
-rw-r--r--gcc/ada/sem_ch4.adb100
-rw-r--r--gcc/ada/sem_ch5.adb1209
-rw-r--r--gcc/ada/sem_ch5.ads29
-rw-r--r--gcc/ada/sem_ch6.adb59
-rw-r--r--gcc/ada/sem_res.adb106
-rw-r--r--gcc/ada/sem_util.adb75
-rw-r--r--gcc/ada/sem_util.ads5
-rw-r--r--gcc/ada/sinfo.adb16
-rw-r--r--gcc/ada/sinfo.ads13
-rw-r--r--gcc/ada/snames.ads-tmpl1
-rw-r--r--gcc/ada/style.adb10
-rw-r--r--gcc/ada/switch-c.adb18
-rw-r--r--gcc/basic-block.h3
-rw-r--r--gcc/bb-reorder.c2
-rw-r--r--gcc/cfghooks.c28
-rw-r--r--gcc/cgraph.h2
-rw-r--r--gcc/cgraphbuild.c14
-rw-r--r--gcc/cgraphunit.c347
-rw-r--r--gcc/combine-stack-adj.c135
-rw-r--r--gcc/combine.c4
-rw-r--r--gcc/config.gcc26
-rw-r--r--gcc/config/arm/arm.c28
-rw-r--r--gcc/config/arm/arm.h10
-rw-r--r--gcc/config/i386/biarchx32.h28
-rw-r--r--gcc/config/i386/i386.c120
-rw-r--r--gcc/config/i386/sse.md10
-rw-r--r--gcc/config/ia64/ia64.c80
-rw-r--r--gcc/config/ia64/vms.h3
-rw-r--r--gcc/config/sh/sh.c8
-rw-r--r--gcc/config/vms/make-crtlmap.awk12
-rw-r--r--gcc/config/vms/t-vms5
-rw-r--r--gcc/config/vms/vms-c.c7
-rw-r--r--gcc/config/vms/vms-crtlmap.map815
-rw-r--r--gcc/config/vms/vms-f.c31
-rw-r--r--gcc/config/vms/vms.c132
-rwxr-xr-xgcc/configure6
-rw-r--r--gcc/configure.ac2
-rw-r--r--gcc/cp/ChangeLog33
-rw-r--r--gcc/cp/call.c2
-rw-r--r--gcc/cp/class.c39
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/decl.c21
-rw-r--r--gcc/cp/method.c2
-rw-r--r--gcc/cp/pt.c40
-rw-r--r--gcc/cp/tree.c5
-rw-r--r--gcc/cprop.c2
-rw-r--r--gcc/cse.c4
-rw-r--r--gcc/double-int.c2
-rw-r--r--gcc/dse.c109
-rw-r--r--gcc/dse.h30
-rw-r--r--gcc/dwarf2out.c2
-rw-r--r--gcc/except.c16
-rw-r--r--gcc/ggc-page.c26
-rw-r--r--gcc/go/gofrontend/expressions.cc49
-rw-r--r--gcc/go/gofrontend/expressions.h5
-rw-r--r--gcc/ira-color.c3
-rw-r--r--gcc/java/ChangeLog13
-rw-r--r--gcc/java/class.c120
-rw-r--r--gcc/loop-init.c23
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/testsuite/ChangeLog84
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist-array3.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/noexcept01.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/noexcept17.C54
-rw-r--r--gcc/testsuite/g++.dg/eh/ctor1.C8
-rw-r--r--gcc/testsuite/g++.dg/eh/init-temp1.C8
-rw-r--r--gcc/testsuite/g++.dg/ext/weak4.C9
-rw-r--r--gcc/testsuite/g++.dg/opt/pr52727.C45
-rw-r--r--gcc/testsuite/g++.dg/template/inherit8.C13
-rw-r--r--gcc/testsuite/g++.dg/torture/pr52772.C85
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/ehcleanup-1.C9
-rw-r--r--gcc/testsuite/g++.dg/warn/Wzero-as-null-pointer-constant-5.C20
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/cleanup1.C8
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/spec40.C27
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr52760.c27
-rw-r--r--gcc/testsuite/gcc.dg/pr52803.c4
-rw-r--r--gcc/testsuite/gcc.dg/pr52808.c12
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr52756.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/pr52754.c33
-rw-r--r--gcc/testsuite/gfortran.dg/pr52835.f9016
-rw-r--r--gcc/testsuite/gnat.dg/controlled6.adb24
-rw-r--r--gcc/testsuite/gnat.dg/controlled6_pkg-iterators.adb21
-rw-r--r--gcc/testsuite/gnat.dg/controlled6_pkg-iterators.ads22
-rw-r--r--gcc/testsuite/gnat.dg/controlled6_pkg.ads15
-rw-r--r--gcc/testsuite/gnat.dg/specs/aggr5.ads19
-rw-r--r--gcc/tracer.c18
-rw-r--r--gcc/tree-affine.c2
-rw-r--r--gcc/tree-affine.h1
-rw-r--r--gcc/tree-cfg.c58
-rw-r--r--gcc/tree-data-ref.c156
-rw-r--r--gcc/tree-data-ref.h32
-rw-r--r--gcc/tree-ssa-ccp.c11
-rw-r--r--gcc/tree-ssa-forwprop.c12
-rw-r--r--gcc/tree-ssa-threadupdate.c52
-rw-r--r--gcc/tree-vect-slp.c15
-rw-r--r--gcc/varasm.c19
-rw-r--r--libffi/ChangeLog8
-rw-r--r--libffi/src/powerpc/ffi.c13
-rw-r--r--libgcc/ChangeLog10
-rw-r--r--libgcc/config/i386/linux-unwind.h2
-rw-r--r--libgcc/config/ia64/unwind-ia64.c12
-rw-r--r--libgfortran/ChangeLog12
-rw-r--r--libgfortran/config.h.in364
-rwxr-xr-xlibgfortran/configure732
-rw-r--r--libgfortran/configure.ac366
-rw-r--r--libgfortran/intrinsics/chmod.c1
-rw-r--r--libgo/MERGE2
-rw-r--r--libgo/Makefile.am8
-rw-r--r--libgo/Makefile.in8
-rw-r--r--libgo/go/archive/tar/reader.go2
-rw-r--r--libgo/go/archive/tar/writer.go17
-rw-r--r--libgo/go/archive/tar/writer_test.go9
-rw-r--r--libgo/go/archive/zip/reader.go65
-rw-r--r--libgo/go/archive/zip/reader_test.go252
-rw-r--r--libgo/go/archive/zip/struct.go9
-rw-r--r--libgo/go/archive/zip/testdata/crc32-not-streamed.zipbin0 -> 314 bytes
-rw-r--r--libgo/go/archive/zip/testdata/go-no-datadesc-sig.zipbin0 -> 330 bytes
-rw-r--r--libgo/go/archive/zip/testdata/go-with-datadesc-sig.zipbin0 -> 242 bytes
-rw-r--r--libgo/go/archive/zip/testdata/r.zipbin440 -> 0 bytes
-rw-r--r--libgo/go/archive/zip/writer.go1
-rw-r--r--libgo/go/archive/zip/writer_test.go2
-rw-r--r--libgo/go/crypto/tls/common.go30
-rw-r--r--libgo/go/crypto/tls/handshake_client.go14
-rw-r--r--libgo/go/crypto/tls/handshake_server.go10
-rw-r--r--libgo/go/crypto/tls/handshake_server_test.go2
-rw-r--r--libgo/go/crypto/tls/key_agreement.go4
-rw-r--r--libgo/go/crypto/tls/root_test.go37
-rw-r--r--libgo/go/crypto/tls/root_windows.go47
-rw-r--r--libgo/go/crypto/tls/tls.go7
-rw-r--r--libgo/go/crypto/x509/pkcs1.go2
-rw-r--r--libgo/go/crypto/x509/root.go17
-rw-r--r--libgo/go/crypto/x509/root_darwin.go (renamed from libgo/go/crypto/tls/root_darwin.go)17
-rw-r--r--libgo/go/crypto/x509/root_stub.go (renamed from libgo/go/crypto/tls/root_stub.go)9
-rw-r--r--libgo/go/crypto/x509/root_unix.go (renamed from libgo/go/crypto/tls/root_unix.go)18
-rw-r--r--libgo/go/crypto/x509/root_windows.go226
-rw-r--r--libgo/go/crypto/x509/verify.go36
-rw-r--r--libgo/go/crypto/x509/verify_test.go53
-rw-r--r--libgo/go/crypto/x509/x509.go2
-rw-r--r--libgo/go/database/sql/driver/driver.go11
-rw-r--r--libgo/go/database/sql/fakedb_test.go21
-rw-r--r--libgo/go/database/sql/sql.go145
-rw-r--r--libgo/go/database/sql/sql_test.go115
-rw-r--r--libgo/go/encoding/asn1/asn1.go10
-rw-r--r--libgo/go/encoding/asn1/asn1_test.go2
-rw-r--r--libgo/go/encoding/asn1/common.go3
-rw-r--r--libgo/go/encoding/asn1/marshal.go4
-rw-r--r--libgo/go/encoding/asn1/marshal_test.go6
-rw-r--r--libgo/go/encoding/binary/binary.go11
-rw-r--r--libgo/go/encoding/csv/reader.go3
-rw-r--r--libgo/go/encoding/gob/decode.go3
-rw-r--r--libgo/go/encoding/gob/doc.go2
-rw-r--r--libgo/go/encoding/gob/encoder_test.go4
-rw-r--r--libgo/go/encoding/gob/gobencdec_test.go19
-rw-r--r--libgo/go/encoding/json/encode.go5
-rw-r--r--libgo/go/exp/gotype/gotype.go2
-rw-r--r--libgo/go/exp/norm/maketables.go4
-rw-r--r--libgo/go/exp/norm/normalize.go2
-rw-r--r--libgo/go/exp/types/check_test.go2
-rw-r--r--libgo/go/exp/types/exportdata.go52
-rw-r--r--libgo/go/exp/types/gcimporter.go157
-rw-r--r--libgo/go/exp/types/gcimporter_test.go18
-rw-r--r--libgo/go/exp/types/universe.go5
-rw-r--r--libgo/go/exp/wingui/gui.go155
-rw-r--r--libgo/go/exp/wingui/winapi.go134
-rw-r--r--libgo/go/exp/wingui/zwinapi.go192
-rw-r--r--libgo/go/expvar/expvar.go41
-rw-r--r--libgo/go/flag/example_test.go83
-rw-r--r--libgo/go/fmt/doc.go6
-rw-r--r--libgo/go/fmt/export_test.go7
-rw-r--r--libgo/go/fmt/fmt_test.go11
-rw-r--r--libgo/go/fmt/format.go19
-rw-r--r--libgo/go/fmt/print.go58
-rw-r--r--libgo/go/fmt/scan.go113
-rw-r--r--libgo/go/fmt/scan_test.go4
-rw-r--r--libgo/go/go/build/build.go86
-rw-r--r--libgo/go/go/build/build_test.go1
-rw-r--r--libgo/go/go/build/deps_test.go424
-rw-r--r--libgo/go/go/parser/error_test.go166
-rw-r--r--libgo/go/go/parser/parser.go152
-rw-r--r--libgo/go/go/parser/parser_test.go83
-rw-r--r--libgo/go/go/parser/short_test.go75
-rw-r--r--libgo/go/go/parser/testdata/commas.src19
-rw-r--r--libgo/go/go/parser/testdata/issue3106.src46
-rw-r--r--libgo/go/go/printer/nodes.go58
-rw-r--r--libgo/go/go/printer/testdata/declarations.golden15
-rw-r--r--libgo/go/go/printer/testdata/declarations.input10
-rw-r--r--libgo/go/go/printer/testdata/statements.golden59
-rw-r--r--libgo/go/go/printer/testdata/statements.input43
-rw-r--r--libgo/go/go/scanner/scanner.go2
-rw-r--r--libgo/go/html/template/clone_test.go33
-rw-r--r--libgo/go/html/template/content.go4
-rw-r--r--libgo/go/html/template/doc.go2
-rw-r--r--libgo/go/html/template/escape.go42
-rw-r--r--libgo/go/html/template/escape_test.go9
-rw-r--r--libgo/go/html/template/template.go34
-rw-r--r--libgo/go/image/draw/draw.go2
-rw-r--r--libgo/go/image/image.go2
-rw-r--r--libgo/go/index/suffixarray/qsufsort.go4
-rw-r--r--libgo/go/io/io.go7
-rw-r--r--libgo/go/io/ioutil/ioutil.go9
-rw-r--r--libgo/go/log/log.go57
-rw-r--r--libgo/go/log/syslog/syslog_windows.go8
-rw-r--r--libgo/go/math/big/nat.go2
-rw-r--r--libgo/go/math/erf.go4
-rw-r--r--libgo/go/net/dial_test.go19
-rw-r--r--libgo/go/net/dnsclient.go20
-rw-r--r--libgo/go/net/dnsmsg.go350
-rw-r--r--libgo/go/net/dnsmsg_test.go13
-rw-r--r--libgo/go/net/fd.go4
-rw-r--r--libgo/go/net/fd_linux.go3
-rw-r--r--libgo/go/net/file_test.go112
-rw-r--r--libgo/go/net/http/client_test.go6
-rw-r--r--libgo/go/net/http/request.go6
-rw-r--r--libgo/go/net/http/request_test.go19
-rw-r--r--libgo/go/net/http/server.go2
-rw-r--r--libgo/go/net/http/transport.go2
-rw-r--r--libgo/go/net/http/transport_test.go26
-rw-r--r--libgo/go/net/http/triv.go53
-rw-r--r--libgo/go/net/interface.go2
-rw-r--r--libgo/go/net/interface_linux.go12
-rw-r--r--libgo/go/net/interface_stub.go2
-rw-r--r--libgo/go/net/interface_windows.go2
-rw-r--r--libgo/go/net/iprawsock_posix.go7
-rw-r--r--libgo/go/net/ipsock_posix.go82
-rw-r--r--libgo/go/net/mac.go20
-rw-r--r--libgo/go/net/mac_test.go16
-rw-r--r--libgo/go/net/mail/message.go3
-rw-r--r--libgo/go/net/multicast_test.go8
-rw-r--r--libgo/go/net/net.go17
-rw-r--r--libgo/go/net/net_test.go1
-rw-r--r--libgo/go/net/parse_test.go4
-rw-r--r--libgo/go/net/rpc/client.go3
-rw-r--r--libgo/go/net/server_test.go547
-rw-r--r--libgo/go/net/sock.go4
-rw-r--r--libgo/go/net/sockopt.go3
-rw-r--r--libgo/go/net/sockopt_bsd.go13
-rw-r--r--libgo/go/net/sockopt_linux.go13
-rw-r--r--libgo/go/net/sockopt_windows.go13
-rw-r--r--libgo/go/net/tcpsock_posix.go10
-rw-r--r--libgo/go/net/timeout_test.go51
-rw-r--r--libgo/go/net/udp_test.go4
-rw-r--r--libgo/go/net/udpsock_posix.go7
-rw-r--r--libgo/go/net/unicast_test.go523
-rw-r--r--libgo/go/net/unixsock_posix.go14
-rw-r--r--libgo/go/os/error.go18
-rw-r--r--libgo/go/os/error_plan9.go9
-rw-r--r--libgo/go/os/error_posix.go14
-rw-r--r--libgo/go/os/error_test.go81
-rw-r--r--libgo/go/os/error_windows.go30
-rw-r--r--libgo/go/os/exec/exec.go2
-rw-r--r--libgo/go/os/file_unix.go16
-rw-r--r--libgo/go/os/os_test.go19
-rw-r--r--libgo/go/os/types.go4
-rw-r--r--libgo/go/path/filepath/match.go24
-rw-r--r--libgo/go/path/filepath/match_test.go38
-rw-r--r--libgo/go/path/filepath/path.go61
-rw-r--r--libgo/go/path/filepath/path_test.go103
-rw-r--r--libgo/go/path/filepath/path_windows.go4
-rw-r--r--libgo/go/path/filepath/symlink.go67
-rw-r--r--libgo/go/path/filepath/symlink_windows.go63
-rw-r--r--libgo/go/reflect/type.go43
-rw-r--r--libgo/go/reflect/value.go13
-rw-r--r--libgo/go/runtime/compiler.go13
-rw-r--r--libgo/go/runtime/debug/stack_test.go21
-rw-r--r--libgo/go/runtime/pprof/pprof_test.go5
-rw-r--r--libgo/go/sort/sort.go8
-rw-r--r--libgo/go/strconv/isprint.go521
-rw-r--r--libgo/go/strconv/makeisprint.go162
-rw-r--r--libgo/go/strconv/quote.go181
-rw-r--r--libgo/go/strconv/quote_test.go15
-rw-r--r--libgo/go/strings/example_test.go2
-rw-r--r--libgo/go/sync/atomic/atomic_test.go16
-rw-r--r--libgo/go/syscall/mksyscall.awk13
-rw-r--r--libgo/go/testing/testing.go5
-rw-r--r--libgo/go/text/template/doc.go2
-rw-r--r--libgo/go/text/template/exec.go1
-rw-r--r--libgo/go/text/template/exec_test.go4
-rw-r--r--libgo/go/text/template/multi_test.go2
-rw-r--r--libgo/go/text/template/parse/lex.go25
-rw-r--r--libgo/go/text/template/parse/parse.go2
-rw-r--r--libgo/go/text/template/parse/parse_test.go15
-rw-r--r--libgo/go/time/tick_test.go2
-rw-r--r--libgo/go/time/time.go7
-rw-r--r--libgo/go/unicode/utf16/export_test.go11
-rw-r--r--libgo/go/unicode/utf16/utf16.go21
-rw-r--r--libgo/go/unicode/utf16/utf16_test.go10
-rw-r--r--libgo/go/unicode/utf8/utf8.go13
-rw-r--r--libgo/go/unicode/utf8/utf8_test.go21
-rwxr-xr-xlibgo/merge.sh2
-rw-r--r--libgo/runtime/malloc.goc20
-rw-r--r--libgo/runtime/proc.c30
-rw-r--r--libgo/runtime/runtime.c8
-rw-r--r--libgo/runtime/runtime.h2
-rw-r--r--libgomp/ChangeLog5
-rw-r--r--libgomp/configure.tgt2
-rw-r--r--libiberty/ChangeLog5
-rw-r--r--libiberty/stack-limit.c3
-rw-r--r--libitm/ChangeLog9
-rw-r--r--libitm/configure6
-rw-r--r--libitm/configure.tgt2
-rw-r--r--libstdc++-v3/ChangeLog37
-rwxr-xr-xlibstdc++-v3/configure5661
-rw-r--r--libstdc++-v3/crossconfig.m46
-rw-r--r--libstdc++-v3/include/bits/deque.tcc6
-rw-r--r--libstdc++-v3/include/bits/stl_vector.h65
-rw-r--r--libstdc++-v3/include/std/functional10
-rw-r--r--libstdc++-v3/testsuite/20_util/function/10.cc37
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/modifiers/emplace/52799.cc28
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/modifiers/emplace/52799.cc28
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/52591.cc38
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/modifiers/emplace/52799.cc28
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc2
363 files changed, 19079 insertions, 5375 deletions
diff --git a/config/ChangeLog b/config/ChangeLog
index f502696ac55..c1b15bea3f1 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,12 @@
+2012-04-03 Tristan Gingold <gingold@adacore.com>
+
+ * mmap.m4: Use *vms* instead of vms*.
+
+2012-04-02 Tristan Gingold <gingold@adacore.com>
+
+ * math.m4 (GCC_CHECK_MATH_FUNC): Remove if-present
+ argument. Define the variable.
+
2012-03-26 Tristan Gingold <gingold@adacore.com>
* math.m4: New file.
diff --git a/config/math.m4 b/config/math.m4
index 5527c25aec3..23835f230cb 100644
--- a/config/math.m4
+++ b/config/math.m4
@@ -14,10 +14,10 @@ dnl functions).
AC_DEFUN([GCC_CHECK_MATH_HEADERS],
[AC_CHECK_HEADERS_ONCE(math.h complex.h)])
-dnl GCC_CHECK_MATH_FUNC([name],[if-present])
+dnl GCC_CHECK_MATH_FUNC([name])
dnl
dnl Check whether math function NAME is available on the system (by compiling
-dnl and linking a C program) and run if-present on success.
+dnl and linking a C program) and run define HAVE_name on success.
dnl
dnl Note that OpenVMS system insists on including complex.h before math.h
AC_DEFUN([GCC_CHECK_MATH_FUNC],
@@ -44,6 +44,7 @@ main ()
[gcc_cv_math_func_$1=yes],
[gcc_cv_math_func_$1=no])])
if test $gcc_cv_math_func_$1 = yes; then
- $2
+ AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_$1),[1],
+ [Define to 1 if you have the `$1' function.])
fi
])
diff --git a/config/mmap.m4 b/config/mmap.m4
index 39d79afc749..fba0d9d3657 100644
--- a/config/mmap.m4
+++ b/config/mmap.m4
@@ -24,7 +24,7 @@ else
# read() to the same fd. The only system known to have a problem here
# is VMS, where text files have record structure.
case "$host_os" in
- vms* | ultrix*)
+ *vms* | ultrix*)
gcc_cv_func_mmap_file=no ;;
*)
gcc_cv_func_mmap_file=yes;;
@@ -42,7 +42,7 @@ else
# Systems known to be in this category are Windows (all variants),
# VMS, and Darwin.
case "$host_os" in
- vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00)
+ *vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00)
gcc_cv_func_mmap_dev_zero=no ;;
*)
gcc_cv_func_mmap_dev_zero=yes;;
@@ -74,7 +74,7 @@ else
# above for use of /dev/zero.
# Systems known to be in this category are Windows, VMS, and SCO Unix.
case "$host_os" in
- vms* | cygwin* | pe | mingw* | sco* | udk* )
+ *vms* | cygwin* | pe | mingw* | sco* | udk* )
gcc_cv_func_mmap_anon=no ;;
*)
gcc_cv_func_mmap_anon=yes;;
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9d3d5152d08..db516599680 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,279 @@
+2012-04-03 Tristan Gingold <gingold@adacore.com>
+
+ * configure.ac: Use GCC_AC_FUNC_MMAP_BLACKLIST instead
+ of gcc_AC_FUNC_MMAP_BLACKLIST.
+ * acinclude.m4 (gcc_AC_FUNC_MMAP_BLACKLIST): Remove.
+ * Makefile.in (aclocal_deps): Add mmap.m4.
+ * configure: Regenerate.
+ * aclocal.m4: Regenerate.
+
+2012-04-03 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/52808
+ * tracer.c (tail_duplicate): Return whether we have duplicated
+ any block.
+ (tracer): If we have duplicated any block, cleanup the CFG.
+ * cfghooks.c (duplicate_block): If we duplicated a loop
+ header but not its loop, destroy the loop because it now has
+ multiple entries.
+ * tree-ssa-threadupdate.c (thread_through_loop_header): Tell
+ the cfg manipulation routines we are not creating a multiple
+ entry loop.
+
+2012-04-03 Tristan Gingold <gingold@adacore.com>
+
+ * config/vms/vms-c.c (vms_pragma_nomember_alignment): Handle
+ 'byte' alignment.
+ (vms_c_common_override_options): Allow parameterless variadic
+ functions.
+
+2012-04-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/52835
+ * tree-data-ref.c (build_rdg): Return NULL if
+ compute_data_dependences_for_loop failed.
+
+2012-04-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ * varasm.c (initializer_constant_valid_for_bitfield_p): Return true
+ for REAL_CST as well.
+ (output_constructor): Use RECORD_OR_UNION_TYPE_P predicate.
+ In the bitfield case, if the value is a REAL_CST, convert it first to
+ an INTEGER_CST.
+
+2012-04-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config.gcc: Use i386/biarchx32.h instead of i386/biarch64.h
+ for --with-abi={x32|mx32} or --with-multilib-list=mx32.
+ (supported_defaults): Add abi for i[34567]86-*-* and x86_64-*-*.
+
+ * config/i386/biarchx32.h: New.
+
+2012-04-02 Anatoly Sokolov <aesok@post.ru>
+
+ * config/arm/arm.h (PREFERRED_RELOAD_CLASS): Remove.
+ * config/arm/arm.c (TARGET_PREFERRED_RELOAD_CLASS): Define.
+ (arm_preferred_reload_class): New function.
+
+2012-04-02 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/52756
+ * tree-ssa-threadupdate.c (def_split_header_continue_p): New function.
+ (thread_through_loop_header): After threading through the loop latch
+ remove the split part from the loop and clear further threading
+ opportunities that would create a multiple entry loop.
+
+2012-04-02 Richard Guenther <rguenther@suse.de>
+
+ PR rtl-optimization/52800
+ * cprop.c (execute_rtl_cprop): Call cleanup_cfg with
+ CLEANUP_CFG_CHANGED.
+
+2012-04-02 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/52803
+ * loop-init.c (gate_handle_loop2): Destroy loops here if
+ we don't enter RTL loop optimizers.
+
+2012-04-02 Uros Bizjak <ubizjak@gmail.com>
+
+ Partially revert:
+ 2012-03-29 Richard Guenther <rguenther@suse.de>
+
+ * rtl.h (extended_count): Remove.
+ * combine.c (extended_count): Remove.
+
+2012-04-02 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/40942
+ * pt.c (more_specialized_fn): Don't apply decay conversion to
+ types of function parameters.
+
+2012-04-02 Tristan Gingold <gingold@adacore.com>
+
+ * ggc-page.c (PAGE_L1_SIZE, PAGE_L2_SIZE, LOOKUP_L1, LOOKUP_L2)
+ (ggc_allocated_p, lookup_page_table_entry, set_page_table_entry)
+ (alloc_page, init_ggc, clear_marks, struct ggc_pch_data)
+ (ggc_pch_this_base): Use uintptr_t instead of size_t.
+
+2012-03-31 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR bootstrap/52784
+ * config/i386/i386.c (ix86_option_override_internal): Don't
+ check TARGET_64BIT if TARGET_64BIT_DEFAULT is false.
+
+2012-03-31 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree-cfg.c (call_can_make_abnormal_goto): New predicate.
+ (stmt_can_make_abnormal_goto): Use it.
+ (is_ctrl_altering_stmt): Likewise.
+
+2012-03-30 Naveen H.S <naveen.S@kpitcummins.com>
+ Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.c (push_regs): Skip banked registers when
+ resbank attribute is specified.
+ (sh_expand_epilogue): Likewise.
+
+2012-03-30 Richard Henderson <rth@redhat.com>
+
+ PR debug/52727
+ * combine-stack-adj.c (prev_active_insn_bb): New.
+ (next_active_insn_bb): New.
+ (force_move_args_size_note): New.
+ (combine_stack_adjustments_for_block): Use it.
+
+2012-03-30 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (struct expand_vec_perm_d): Add one_operand_p.
+ (ix86_expand_vector_init_duplicate): Initialize it.
+ (expand_vec_perm_palignr): Likewise.
+ (ix86_expand_vec_perm_const): Likewise.
+ (ix86_vectorize_vec_perm_const_ok): Likewise.
+ (expand_vec_perm_blend): Use it.
+ (expand_vec_perm_vpermil): Likewise.
+ (expand_vec_perm_pshufb): Likewise.
+ (expand_vec_perm_1): Likewise.
+ (expand_vec_perm_pshuflw_pshufhw): Likewise.
+ (expand_vec_perm_interleave2): Likewise.
+ (expand_vec_perm_vpermq_perm_1): Likewise.
+ (expand_vec_perm_vperm2f128): Likewise.
+ (expand_vec_perm_interleave3): Likewise.
+ (expand_vec_perm_vperm2f128_vblend): Likewise.
+ (expand_vec_perm_vpshufb2_vpermq): Likewise.
+ (expand_vec_perm_vpshufb2_vpermq_even_odd): Likewise,.
+ (expand_vec_perm_broadcast): Likewise.
+ (expand_vec_perm_vpshufb4_vpermq2): Likewise.
+
+2012-03-30 Richard Henderson <rth@redhat.com>
+
+ * dwarf2out.c (gen_variable_die): Initialize off.
+
+2012-03-30 Tristan Gingold <gingold@adacore.com>
+
+ * config/vms/vms-f.c: New file.
+ * config/vms/t-vms (vms-f.o): New rule.
+ * config.gcc (*-*-*vms*): Define fortran_target_objs.
+
+2012-03-30 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/52754
+ * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Only
+ propagate arbitrary addresses into really plain dereferences.
+
+2012-03-30 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/52772
+ * except.c (emit_to_new_bb_before): Move loop updating ...
+ (dw2_build_landing_pads): ... here. Use a proper block for
+ querying the loop father.
+
+2012-03-30 Tristan Gingold <gingold@adacore.com>
+
+ * config/ia64/ia64.c (ia64_section_type_flags): Remove
+ common_object attribute handling.
+ (SECTION_VMS_OVERLAY): Remove
+ (ia64_vms_common_object_attribute): Replace abort with an assert.
+ Do not set DECL_SECTION_NAME.
+ (ia64_vms_output_aligned_decl_common): Handle common_object
+ attribute.
+ (ia64_vms_elf_asm_named_section): Remove.
+ * config/ia64/vms.h (TARGET_ASM_NAMED_SECTION): Remove.
+
+2012-03-30 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/52786
+ * double-int.c (rshift_double): Remove not needed cast.
+
+2012-03-30 Richard Guenther <rguenther@suse.de>
+
+ * tree-affine.h (print_aff): Remove.
+ * tree-affine.c (print_aff): Make static.
+ * tree-data-ref.h (access_matrix_get_index_for_parameter): Remove.
+ (get_references_in_stmt): Likewise.
+ (print_direction_vector): Likewise.
+ (print_dir_vectors): Likewise.
+ (print_dist_vectors): Likewise.
+ (dump_subscript): Likewise.
+ (dump_ddrs): Likewise.
+ (dump_dist_dir_vectors): Likewise.
+ (dump_data_references): Likewise.
+ (dump_data_dependence_relation): Likewise.
+ (dump_data_dependence_direction): Likewise.
+ (dump_rdg_vertex): Likewise.
+ (dump_rdg_component): Likewise.
+ (debug_ddrs): Declare.
+ (struct data_ref_loc_d): Move ...
+ * tree-data-ref.c (struct data_ref_loc_d): ... here.
+ (get_references_in_stmt): Make static.
+ (dump_data_references): Likewise.
+ (dump_subscript): Likewise.
+ (print_direction_vector): Likewise.
+ (print_dir_vectors): Likewise.
+ (print_dist_vectors): Likewise.
+ (dump_data_dependence_relation): Likewise.
+ (dump_dist_dir_vectors): Likewise.
+ (dump_ddrs): Likewise.
+ (dump_rdg_vertex): Likewise.
+ (dump_rdg_component): Likewise.
+ (debug_ddrs): New function.
+ (access_matrix_get_index_for_parameter): Remove.
+
+2012-03-30 Tristan Gingold <gingold@adacore.com>
+
+ * config/vms/vms.c (VMS_CRTL_FLOAT32): Rename.
+ (VMS_CRTL_FLOAT64, VMS_CRTL_FLOAT64_VAXD): New.
+ (VMS_CRTL_FLOAT128, VMS_CRTL_DPML, VMS_CRTL_NODMPL)
+ (VMS_CRTL_32ONLY, VMS_CRTL_G_MASK, VMS_CRTL_G_NONE)
+ (VMS_CRTL_GA, VMS_CRTL_GL, VMS_CRTL_FLOATV2): New.
+ (vms_patch_builtins): Handle new flags
+ * config/vms/vms-crtlmap.map: Completed using nm on
+ c and math system libraries.
+ * config/vms/make-crtlmap.awk: Handle any number of flags.
+
+2012-03-30 Martin Jambor <mjambor@suse.cz>
+
+ * tree-ssa-ccp.c (insert_clobbers_for_var): Do not assert that there
+ is a builtin_stack_save in a dominating BB.
+
+2012-03-29 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/sse.md (avx_h<plusminus_insn>v4df3): Fix results
+ crossing 128bit lane boundary.
+
+2012-03-29 Vladimir Makarov <vmakarov@redhat.com>
+
+ * ira-color.c (setup_left_conflict_sizes_p): Process all
+ conflicting objects.
+
+2012-03-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/52760
+ * tree-vect-slp.c (vect_get_constant_vectors): Convert constant_p
+ shift count for {L,R}{SHIFT,ROTATE}_EXPR to TREE_TYPE (vector_type).
+
+2012-03-29 Richard Guenther <rguenther@suse.de>
+
+ * cgraph.h (cgraph_materialize_all_clones): Remove.
+ (reset_inline_failed): Likewise.
+ * cgraphunit.c (cgraph_materialize_all_clones): Make static.
+ * cgraphbuild.c (reset_inline_failed): Remove.
+ * rtl.h (cse_main): Remove.
+ (extended_count): Likewise.
+ * cse.c (dump_class): Mark as DEBUG_FUNCTION.
+ (cse_main): Make static.
+ * combine.c (extended_count): Remove.
+ (dump_combine_stats): Mark as DEBUG_FUNCTION.
+ * basic-block.h (reorder_basic_blocks): Remove.
+ * bb-reorder.c (reorder_basic_blocks): Make static.
+ * Makefile.in (dse.o): Remove dse.h dependency.
+ * dse.h: Remove.
+ * dse.c (gate_dse): Remove.
+ (clear_alias_mode_eq): Likewise.
+ (clear_alias_mode_hash): Likewise.
+ (dse_record_singleton_alias_set): Likewise.
+ (dse_invalidate_singleton_alias_set): Likewise.
+
2012-03-29 H.J. Lu <hongjiu.lu@intel.com>
* config/linux-android.h (ANDROID_STARTFILE_SPEC): Use
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 72fd57d8921..7fc43becf8f 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20120329
+20120403
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index d50faccca52..8fd82089563 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1650,6 +1650,7 @@ aclocal_deps = \
$(srcdir)/../config/unwind_ipinfo.m4 \
$(srcdir)/../config/warnings.m4 \
$(srcdir)/../config/dfp.m4 \
+ $(srcdir)/../config/mmap.m4 \
$(srcdir)/acinclude.m4
$(srcdir)/configure: @MAINT@ $(srcdir)/configure.ac $(srcdir)/aclocal.m4
@@ -3011,7 +3012,7 @@ dce.o : dce.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
dse.o : dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(TM_P_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
$(RECOG_H) $(EXPR_H) $(DF_H) cselib.h $(DBGCNT_H) $(TIMEVAR_H) \
- $(TREE_PASS_H) alloc-pool.h $(ALIAS_H) dse.h $(OPTABS_H) $(TARGET_H) \
+ $(TREE_PASS_H) alloc-pool.h $(ALIAS_H) $(OPTABS_H) $(TARGET_H) \
$(BITMAP_H) $(PARAMS_H)
fwprop.o : fwprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(DIAGNOSTIC_CORE_H) insn-config.h $(RECOG_H) $(FLAGS_H) $(OBSTACK_H) $(BASIC_BLOCK_H) \
diff --git a/gcc/acinclude.m4 b/gcc/acinclude.m4
index 84b828fe598..c24464b5977 100644
--- a/gcc/acinclude.m4
+++ b/gcc/acinclude.m4
@@ -221,99 +221,6 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
AC_SUBST(INSTALL_DATA)dnl
])
-# mmap(2) blacklisting. Some platforms provide the mmap library routine
-# but don't support all of the features we need from it.
-AC_DEFUN([gcc_AC_FUNC_MMAP_BLACKLIST],
-[
-AC_CHECK_HEADER([sys/mman.h],
- [gcc_header_sys_mman_h=yes], [gcc_header_sys_mman_h=no])
-AC_CHECK_FUNC([mmap], [gcc_func_mmap=yes], [gcc_func_mmap=no])
-if test "$gcc_header_sys_mman_h" != yes \
- || test "$gcc_func_mmap" != yes; then
- gcc_cv_func_mmap_file=no
- gcc_cv_func_mmap_dev_zero=no
- gcc_cv_func_mmap_anon=no
-else
- AC_CACHE_CHECK([whether read-only mmap of a plain file works],
- gcc_cv_func_mmap_file,
- [# Add a system to this blacklist if
- # mmap(0, stat_size, PROT_READ, MAP_PRIVATE, fd, 0) doesn't return a
- # memory area containing the same data that you'd get if you applied
- # read() to the same fd. The only system known to have a problem here
- # is VMS, where text files have record structure.
- case "$host_os" in
- vms* | ultrix*)
- gcc_cv_func_mmap_file=no ;;
- *)
- gcc_cv_func_mmap_file=yes;;
- esac])
- AC_CACHE_CHECK([whether mmap from /dev/zero works],
- gcc_cv_func_mmap_dev_zero,
- [# Add a system to this blacklist if it has mmap() but /dev/zero
- # does not exist, or if mmapping /dev/zero does not give anonymous
- # zeroed pages with both the following properties:
- # 1. If you map N consecutive pages in with one call, and then
- # unmap any subset of those pages, the pages that were not
- # explicitly unmapped remain accessible.
- # 2. If you map two adjacent blocks of memory and then unmap them
- # both at once, they must both go away.
- # Systems known to be in this category are Windows (all variants),
- # VMS, and Darwin.
- case "$host_os" in
- vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00)
- gcc_cv_func_mmap_dev_zero=no ;;
- *)
- gcc_cv_func_mmap_dev_zero=yes;;
- esac])
-
- # Unlike /dev/zero, the MAP_ANON(YMOUS) defines can be probed for.
- AC_CACHE_CHECK([for MAP_ANON(YMOUS)], gcc_cv_decl_map_anon,
- [AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-[#include <sys/types.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-#ifndef MAP_ANONYMOUS
-#define MAP_ANONYMOUS MAP_ANON
-#endif
-],
-[int n = MAP_ANONYMOUS;])],
- gcc_cv_decl_map_anon=yes,
- gcc_cv_decl_map_anon=no)])
-
- if test $gcc_cv_decl_map_anon = no; then
- gcc_cv_func_mmap_anon=no
- else
- AC_CACHE_CHECK([whether mmap with MAP_ANON(YMOUS) works],
- gcc_cv_func_mmap_anon,
- [# Add a system to this blacklist if it has mmap() and MAP_ANON or
- # MAP_ANONYMOUS, but using mmap(..., MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
- # doesn't give anonymous zeroed pages with the same properties listed
- # above for use of /dev/zero.
- # Systems known to be in this category are Windows, VMS, and SCO Unix.
- case "$host_os" in
- vms* | cygwin* | pe | mingw* | sco* | udk* )
- gcc_cv_func_mmap_anon=no ;;
- *)
- gcc_cv_func_mmap_anon=yes;;
- esac])
- fi
-fi
-
-if test $gcc_cv_func_mmap_file = yes; then
- AC_DEFINE(HAVE_MMAP_FILE, 1,
- [Define if read-only mmap of a plain file works.])
-fi
-if test $gcc_cv_func_mmap_dev_zero = yes; then
- AC_DEFINE(HAVE_MMAP_DEV_ZERO, 1,
- [Define if mmap of /dev/zero works.])
-fi
-if test $gcc_cv_func_mmap_anon = yes; then
- AC_DEFINE(HAVE_MMAP_ANON, 1,
- [Define if mmap with MAP_ANON(YMOUS) works.])
-fi
-])
-
dnl Determine if enumerated bitfields are unsigned. ISO C says they can
dnl be either signed or unsigned.
dnl
diff --git a/gcc/aclocal.m4 b/gcc/aclocal.m4
index 06028cc051f..a992c3a96ed 100644
--- a/gcc/aclocal.m4
+++ b/gcc/aclocal.m4
@@ -113,6 +113,7 @@ m4_include([../config/lcmessage.m4])
m4_include([../config/lib-ld.m4])
m4_include([../config/lib-link.m4])
m4_include([../config/lib-prefix.m4])
+m4_include([../config/mmap.m4])
m4_include([../config/override.m4])
m4_include([../config/picflag.m4])
m4_include([../config/progtest.m4])
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 7b8832d2992..69c2a847d78 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,319 @@
+2012-04-02 Robert Dewar <dewar@adacore.com>
+
+ * s-atopri.ads: Minor reformatting.
+
+2012-04-02 Thomas Quinot <quinot@adacore.com>
+
+ * sem_util.adb: Minor reformatting, minor code cleanup.
+
+2012-04-02 Ed Schonberg <schonberg@adacore.com>
+
+ * lib-xref.adb (Generate_Reference): For a reference to an
+ operator symbol, set the sloc to point to the first character
+ of the operator name, and not to the initial quaote.
+ (Output_References): Ditto for the definition of an operator
+ symbol.
+
+2012-04-02 Vincent Celier <celier@adacore.com>
+
+ * ali.adb (Scan_Ali): Recognize Z lines. Set
+ Implicit_With_From_Instantiation to True in the With_Record for
+ Z lines.
+ * ali.ads (With_Record): New Boolean component
+ Implicit_With_From_Instantiation, defaulted to False.
+ * csinfo.adb: Indicate that Implicit_With_From_Instantiation
+ is special
+ * lib-writ.adb (Write_ALI): New array Implicit_With.
+ (Collect_Withs): Set Implicit_With for the unit is it is not Yes.
+ (Write_With_Lines): Write a Z line instead of a W line if
+ Implicit_With is Yes for the unit.
+ * sem_ch12.adb (Inherit_Context): Only add a unit in the context
+ if it is not there yet.
+ * sinfo.ads: New flag Implicit_With_From_Instantiation (Flag12)
+ added.
+
+2012-04-02 Yannick Moy <moy@adacore.com>
+
+ * osint.adb, osint.ads (Add_Default_Search_Dirs): Add library
+ search dirs in file specified with option -gnateO.
+
+2012-04-02 Robert Dewar <dewar@adacore.com>
+
+ * sem_ch5.adb, exp_util.adb, sem_util.adb, exp_ch4.adb: Minor
+ reformatting.
+
+2012-04-02 Olivier Hainque <hainque@adacore.com>
+
+ * g-sse.ads: Add x86-solaris and x86_64-darwin to the set of
+ platforms where the use of this spec is supported. Add current
+ year to the copyright notice.
+ * gcc-interfaces/Makefile.in: Add g-sse.o and g-ssvety.o to
+ EXTRA_GNATRTL_NONTASKING_OBJS on x86 32/64 targets that support
+ it and where they were missing (x86-solaris, x86-freebsd,
+ x86_64-freebsd, and x86-darwin).
+
+2012-04-02 Gary Dismukes <dismukes@adacore.com>
+
+ * bindgen.adb (Gen_Ada_Init): When compiling for the AAMP small
+ library, where we no longer suppress the Standard_Library,
+ generate an empty body rather than the usual generation of
+ assignments to imported globals, since those aren't present in
+ the small library.
+
+2012-04-02 Ed Schonberg <schonberg@adacore.com>
+
+ * sinfo.ads: Minor documentation fix.
+
+2012-04-02 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * sem_res.adb (Resolve_Conditional_Expression): Add local variables
+ Else_Typ and Then_Typ. Add missing type conversions to the "then" and
+ "else" expressions when their respective types are scalar.
+
+2012-04-02 Vincent Pucci <pucci@adacore.com>
+
+ * exp_ch9.adb: Reordering of the local subprograms. New Table
+ for the lock free implementation that maps each protected
+ subprograms with the protected component it references.
+ (Allow_Lock_Free_Implementation): New routine. Check if
+ the protected body enables the lock free implementation.
+ (Build_Lock_Free_Protected_Subprogram_Body): New routine.
+ (Build_Lock_Free_Unprotected_Subprogram_Body): New routine.
+ (Comp_Of): New routine.
+ * Makefile.rtl: Add s-atopri.o
+ * debug.adb: New compiler debug flag -gnatd9 for lock free
+ implementation.
+ * rtsfind.ads: RE_Atomic_Compare_Exchange_8,
+ RE_Atomic_Compare_Exchange_16, RE_Atomic_Compare_Exchange_32,
+ RE_Atomic_Compare_Exchange_64, RE_Atomic_Load_8,
+ RE_Atomic_Load_16, RE_Atomic_Load_32, RE_Atomic_Load_64, RE_Uint8,
+ RE_Uint16, RE_Uint32, RE_Uint64 added.
+ * s-atropi.ads: New file. Defines atomic primitives used
+ by the lock free implementation.
+
+2012-04-02 Emmanuel Briot <briot@adacore.com>
+
+ * g-expect.adb (Expect_Internal): Fix leak of the input file descriptor.
+
+2012-04-02 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Quantified_Expression): Reimplemented.
+ The expansion no longer uses the copy of the original QE created
+ during analysis.
+ * sem.adb (Analyze): Add processing for loop parameter specifications.
+ * sem_ch4.adb (Analyze_Quantified_Expression): Reimplemented. The
+ routine no longer creates a copy of the original QE. All
+ constituents of a QE are now preanalyzed and resolved.
+ * sem_ch5.adb (Analyze_Iteration_Scheme): Remove the guard which
+ bypasses all processing when the iteration scheme is related to a
+ QE. Relovate the code which analyzes loop parameter specifications
+ to a separate routine. (Analyze_Iterator_Specification):
+ Preanalyze the iterator name. This action was originally
+ done in Analyze_Iteration_Scheme. Update the check which
+ detects an iterator specification in the context of a QE.
+ (Analyze_Loop_Parameter_Specification): New routine. This
+ procedure allows for a stand-alone analysis of a loop parameter
+ specification without the need of a parent iteration scheme. Add
+ code to update the type of the loop variable when the range
+ generates an itype and the context is a QE.
+ (Pre_Analyze_Range): Renamed to Preanalyze_Range. Update all references
+ to the routine.
+ * sem_ch5.ads: Code reformatting.
+ (Analyze_Loop_Parameter_Specification): New routine.
+ * sem_ch6.adb (Fully_Conformant_Expressions): Detect a case
+ when establishing conformance between two QEs utilizing different
+ specifications.
+ * sem_res.adb (Proper_Current_Scope): New routine.
+ (Resolve): Do not resolve a QE as there is nothing to be done now.
+ Ignore any loop scopes generated for QEs when detecting an expression
+ function as the scopes are cosmetic and do not appear in the tree.
+ (Resolve_Quantified_Expression): Removed. All resolution of
+ QE constituents is now performed during analysis. This ensures
+ that loop variables appearing in array aggregates are properly
+ resolved.
+
+2012-04-02 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_util.adb (Build_Default_Subtype): If the base type is
+ private and its full view is available, use the full view in
+ the subtype declaration.
+
+2012-04-02 Jose Ruiz <ruiz@adacore.com>
+
+ * gnat_ugn.texi: Add some minimal documentation about how to
+ use GNATtest for cross platforms.
+
+2012-04-02 Vincent Celier <celier@adacore.com>
+
+ * opt.ads (Object_Path_File_Name): New variable.
+ * prj-attr.adb: New Compiler attribute Object_Path_Switches.
+ * prj-nmsc.adb (Process_Compiler): Recognize new attribute
+ Object_Path_Switches.
+ * snames.ads-tmpl: New standard name Object_Path_Switches.
+ * switch-c.adb (Scan_Front_End_Switches): Recognize new switch
+ -gnateO= and put its value in Opt.Object_Path_File_Name.
+
+2012-04-02 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * exp_ch7.adb (Process_Declarations): Detect a case where
+ a source object was initialized by another source object,
+ but the expression was rewritten as a class-wide conversion
+ of Ada.Tags.Displace.
+ * exp_util.adb (Initialized_By_Ctrl_Function): Removed.
+ (Is_Controlled_Function_Call): New routine.
+ (Is_Displacement_Of_Ctrl_Function_Result): Removed.
+ (Is_Displacement_Of_Object_Or_Function_Result): New routine.
+ (Is_Source_Object): New routine.
+ (Requires_Cleanup_Actions): Detect a case where a source object was
+ initialized by another source object, but the expression was rewritten
+ as a class-wide conversion of Ada.Tags.Displace.
+ * exp_util.ads (Is_Displacement_Of_Ctrl_Function_Result): Removed.
+ (Is_Displacement_Of_Object_Or_Function_Result): New routine.
+
+2012-04-02 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_res.adb (Resolve_Call): A call to an expression function
+ does not freeze if it appears in a different scope from the
+ expression function itself. Such calls appear in the generated
+ bodies of other expression functions, or in pre/postconditions
+ of subsequent subprograms.
+
+2012-04-02 Yannick Moy <moy@adacore.com>
+
+ * lib-xref-alfa.adb: Code clean up.
+
+2012-04-02 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch12.adb (Analyze_Subprogram_Instantiation): Do not suppress
+ style checks, because the subprogram instance itself may contain
+ violations of syle rules.
+ * style.adb (Missing_Overriding): Check for missing overriding
+ indicator on a subprogram instance.
+
+2012-04-02 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * sem_ch6.adb (Last_Implicit_Declaration): New routine.
+ (Process_PPCs): Insert the body of _postconditions after the
+ last internally generated declaration. This ensures that actual
+ subtypes created for formal parameters are visible and properly
+ frozen as _postconditions may reference them.
+
+2012-04-02 Robert Dewar <dewar@adacore.com>
+
+ * einfo.adb (First_Component_Or_Discriminant) Now applies to
+ all types with discriminants, not just records.
+ * exp_attr.adb (Expand_N_Attribute): Add Scalar_Values handling
+ for arrays, scalars and non-variant records.
+ * sem_attr.adb (Analyze_Attribute): Handle Valid_Scalars
+ * sem_attr.ads (Valid_Scalars): Update description
+ * sem_util.ads, sem_util.adb (No_Scalar_Parts): New function.
+
+2012-03-31 Eric Botcazou <ebotcazou@adacore.com>
+
+ Revert
+ 2012-03-25 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (SS_MARK_NAME): New define.
+ (gnat_to_gnu_entity) <E_Function>: Prepend leaf attribute on entities
+ whose name is SS_MARK_NAME.
+
+2012-03-30 Robert Dewar <dewar@adacore.com>
+
+ * exp_ch5.adb, sem_util.adb, exp_ch4.adb: Minor comment updates.
+
+2012-03-30 Yannick Moy <moy@adacore.com>
+
+ * lib-xref-alfa.adb (Add_Alfa_File): Treat possibly 2 units at the same
+ time, putting all scopes in the same Alfa file.
+ (Add_Alfa_Xrefs): Correct errors in comparison function. Correct value
+ of Def component.
+ (Collect_Alfa): Possibly pass 2 units to Add_Alfa_File.
+
+2012-03-30 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * exp_util.adb (Is_Secondary_Stack_BIP_Func_Call): Handle a case where
+ a build-in-place call appears as Prefix'Reference'Reference.
+
+2012-03-30 Yannick Moy <moy@adacore.com>
+
+ * lib-xref-alfa.adb: Minor refactoring to remove internal package.
+
+2012-03-30 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * sem_ch5.adb (Analyze_Iteration_Scheme): Preanalyze the subtype
+ definition of a loop when the context is a quantified expression.
+
+2012-03-30 Vincent Celier <celier@adacore.com>
+
+ * prj.ads: Minor comment update.
+
+2012-03-30 Yannick Moy <moy@adacore.com>
+
+ * lib-xref-alfa.adb, alloc.ads, lib-xref.ads: Minor addition of
+ comments and refactoring.
+
+2012-03-30 Robert Dewar <dewar@adacore.com>
+
+ * lib-xref.adb, lib-xref-alfa.adb: Minor reformatting & code
+ reorganization.
+
+2012-03-30 Yannick Moy <moy@adacore.com>
+
+ * lib-xref-alfa.adb (Generate_Dereference): Use Get_Code_Unit
+ instead of Get_Source_Unit to get file for reference.
+ (Traverse_Compilation_Unit): Do not add scopes for generic units.
+ * lib-xref.adb (Generate_Reference): Use Get_Code_Unit instead
+ of Get_Source_Unit to get file for reference.
+ * sem_ch12.adb (Analyze_Package_Instantiation): Enable
+ instantiation in Alfa mode.
+
+2012-03-30 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * exp_ch7.adb (Process_Declarations): Replace
+ the call to Is_Null_Access_BIP_Func_Call with
+ Is_Secondary_Stack_BIP_Func_Call. Update the related comment.
+ * exp_util.adb (Is_Null_Access_BIP_Func_Call): Removed.
+ (Is_Secondary_Stack_BIP_Func_Call): New routine.
+ (Requires_Cleanup_Actions): Replace
+ the call to Is_Null_Access_BIP_Func_Call with
+ Is_Secondary_Stack_BIP_Func_Call. Update the related comment.
+ * exp_util.ads (Is_Null_Access_BIP_Func_Call): Removed.
+ (Is_Secondary_Stack_BIP_Func_Call): New routine.
+
+2012-03-30 Yannick Moy <moy@adacore.com>
+
+ * lib-xref-alfa.adb, lib-xref.adb: Code clean ups.
+
+2012-03-30 Gary Dismukes <dismukes@adacore.com>
+
+ * exp_ch5.adb (Expand_Iterator_Loop_Over_Array): For the case of a
+ loop entity which is rewritten as a renaming
+ of the indexed array, explicitly mark the entity as needing
+ debug info so that Materialize entity will be set later by
+ Debug_Renaming_Declaration when the renaming is expanded.
+
+2012-03-30 Robert Dewar <dewar@adacore.com>
+
+ * sem_attr.ads: Update comment.
+
+2012-03-30 Vincent Celier <celier@adacore.com>
+
+ * prj.ads: New Dependency_Kind: ALI_Closure.
+
+2012-03-30 Thomas Quinot <quinot@adacore.com>
+
+ * exp_pakd.adb: Minor reformatting.
+
+2012-03-30 Yannick Moy <moy@adacore.com>
+
+ * lib-xref-alfa.adb (Add_Alfa_File): Take into account possible absence
+ of compilation unit for unit in Sdep_Table.
+
+2012-03-30 Thomas Quinot <quinot@adacore.com>
+
+ * freeze.adb (Freeze_Record_Type): For a type with reversed bit
+ order and reversed storage order, disable front-end relayout.
+
2012-03-25 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Subtype>: Copy
diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl
index 71696585458..d3212b20559 100644
--- a/gcc/ada/Makefile.rtl
+++ b/gcc/ada/Makefile.rtl
@@ -479,6 +479,7 @@ GNATRTL_NONTASKING_OBJS= \
s-assert$(objext) \
s-atacco$(objext) \
s-atocou$(objext) \
+ s-atopri$(objext) \
s-auxdec$(objext) \
s-bitops$(objext) \
s-boarop$(objext) \
diff --git a/gcc/ada/ali.adb b/gcc/ada/ali.adb
index 93dd10956cc..28307ac72a4 100644
--- a/gcc/ada/ali.adb
+++ b/gcc/ada/ali.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -55,6 +55,7 @@ package body ALI is
'X' => True, -- xref
'S' => True, -- specific dispatching
'Y' => True, -- limited_with
+ 'Z' => True, -- implicit with from instantiation
'C' => True, -- SCO information
'F' => True, -- Alfa information
others => False);
@@ -782,7 +783,8 @@ package body ALI is
-- Acquire lines to be ignored
if Read_Xref then
- Ignore := ('U' | 'W' | 'Y' | 'D' | 'X' => False, others => True);
+ Ignore :=
+ ('U' | 'W' | 'Y' | 'Z' | 'D' | 'X' => False, others => True);
-- Read_Lines parameter given
@@ -1717,7 +1719,7 @@ package body ALI is
With_Loop : loop
Check_Unknown_Line;
- exit With_Loop when C /= 'W' and then C /= 'Y';
+ exit With_Loop when C /= 'W' and then C /= 'Y' and then C /= 'Z';
if Ignore ('W') then
Skip_Line;
@@ -1733,6 +1735,8 @@ package body ALI is
Withs.Table (Withs.Last).Elab_All_Desirable := False;
Withs.Table (Withs.Last).SAL_Interface := False;
Withs.Table (Withs.Last).Limited_With := (C = 'Y');
+ Withs.Table (Withs.Last).Implicit_With_From_Instantiation
+ := (C = 'Z');
-- Generic case with no object file available
diff --git a/gcc/ada/ali.ads b/gcc/ada/ali.ads
index b2b9b3d7ffc..39943c4fcc7 100644
--- a/gcc/ada/ali.ads
+++ b/gcc/ada/ali.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -558,6 +558,9 @@ package ALI is
Limited_With : Boolean := False;
-- True if unit is named in a limited_with_clause
+
+ Implicit_With_From_Instantiation : Boolean := False;
+ -- True if this is an implicit with from a generic instantiation
end record;
package Withs is new Table.Table (
diff --git a/gcc/ada/alloc.ads b/gcc/ada/alloc.ads
index c5cad729652..18a2be62157 100644
--- a/gcc/ada/alloc.ads
+++ b/gcc/ada/alloc.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2009, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -157,4 +157,7 @@ package Alloc is
Xrefs_Initial : constant := 5_000; -- Cross-refs
Xrefs_Increment : constant := 300;
+ Drefs_Initial : constant := 5; -- Dereferences
+ Drefs_Increment : constant := 1_000;
+
end Alloc;
diff --git a/gcc/ada/bindgen.adb b/gcc/ada/bindgen.adb
index a4b7d394deb..c44a648e210 100644
--- a/gcc/ada/bindgen.adb
+++ b/gcc/ada/bindgen.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -511,6 +511,14 @@ package body Bindgen is
if CodePeer_Mode then
WBI (" begin");
+ -- When compiling for the AAMP small library, where the standard library
+ -- is no longer suppressed, we still want to exclude the setting of the
+ -- various imported globals, which aren't present for that library.
+
+ elsif AAMP_On_Target and then Configurable_Run_Time_On_Target then
+ WBI (" begin");
+ WBI (" null;");
+
-- If the standard library is suppressed, then the only global variables
-- that might be needed (by the Ravenscar profile) are the priority and
-- the processor for the environment task.
diff --git a/gcc/ada/csinfo.adb b/gcc/ada/csinfo.adb
index ef319cff9e5..024af66479c 100644
--- a/gcc/ada/csinfo.adb
+++ b/gcc/ada/csinfo.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -218,6 +218,7 @@ begin
Set (Special, "Has_Dynamic_Range_Check", True);
Set (Special, "Has_Dynamic_Length_Check", True);
Set (Special, "Has_Private_View", True);
+ Set (Special, "Implicit_With_From_Instantiation", True);
Set (Special, "Is_Controlling_Actual", True);
Set (Special, "Is_Overloaded", True);
Set (Special, "Is_Static_Expression", True);
diff --git a/gcc/ada/debug.adb b/gcc/ada/debug.adb
index bb3e4857ad5..cbcdf0cbb51 100644
--- a/gcc/ada/debug.adb
+++ b/gcc/ada/debug.adb
@@ -153,7 +153,7 @@ package body Debug is
-- d6 Default access unconstrained to thin pointers
-- d7 Do not output version & file time stamp in -gnatv or -gnatl mode
-- d8 Force opposite endianness in packed stuff
- -- d9
+ -- d9 Allow lock free implementation
-- Debug flags for binder (GNATBIND)
@@ -710,6 +710,9 @@ package body Debug is
-- opposite endianness from the actual correct value. Useful in
-- testing out code generation from the packed routines.
+ -- d9 This allows lock free implementation for protected objects
+ -- (see Exp_Ch9).
+
------------------------------------------
-- Documentation for Binder Debug Flags --
------------------------------------------
diff --git a/gcc/ada/einfo.adb b/gcc/ada/einfo.adb
index 0fdc83c3086..0f597a1f941 100644
--- a/gcc/ada/einfo.adb
+++ b/gcc/ada/einfo.adb
@@ -5880,7 +5880,9 @@ package body Einfo is
begin
pragma Assert
- (Is_Record_Type (Id) or else Is_Incomplete_Or_Private_Type (Id));
+ (Is_Record_Type (Id)
+ or else Is_Incomplete_Or_Private_Type (Id)
+ or else Has_Discriminants (Id));
Comp_Id := First_Entity (Id);
while Present (Comp_Id) loop
diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index b8058ae2442..355770186db 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -76,6 +76,14 @@ package body Exp_Attr is
-- Local Subprograms --
-----------------------
+ function Build_Array_VS_Func
+ (A_Type : Entity_Id;
+ Nod : Node_Id) return Entity_Id;
+ -- Build function to test Valid_Scalars for array type A_Type. Nod is the
+ -- Valid_Scalars attribute node, used to insert the function body, and the
+ -- value returned is the entity of the constructed function body. We do not
+ -- bother to generate a separate spec for this subprogram.
+
procedure Compile_Stream_Body_In_Scope
(N : Node_Id;
Decl : Node_Id;
@@ -174,6 +182,149 @@ package body Exp_Attr is
-- expansion. Typically used for rounding and truncation attributes that
-- appear directly inside a conversion to integer.
+ -------------------------
+ -- Build_Array_VS_Func --
+ -------------------------
+
+ function Build_Array_VS_Func
+ (A_Type : Entity_Id;
+ Nod : Node_Id) return Entity_Id
+ is
+ Loc : constant Source_Ptr := Sloc (Nod);
+ Comp_Type : constant Entity_Id := Component_Type (A_Type);
+ Body_Stmts : List_Id;
+ Index_List : List_Id;
+ Func_Id : Entity_Id;
+ Formals : List_Id;
+
+ function Test_Component return List_Id;
+ -- Create one statement to test validity of one component designated by
+ -- a full set of indexes. Returns statement list containing test.
+
+ function Test_One_Dimension (N : Int) return List_Id;
+ -- Create loop to test one dimension of the array. The single statement
+ -- in the loop body tests the inner dimensions if any, or else the
+ -- single component. Note that this procedure is called recursively,
+ -- with N being the dimension to be initialized. A call with N greater
+ -- than the number of dimensions simply generates the component test,
+ -- terminating the recursion. Returns statement list containing tests.
+
+ --------------------
+ -- Test_Component --
+ --------------------
+
+ function Test_Component return List_Id is
+ Comp : Node_Id;
+ Anam : Name_Id;
+
+ begin
+ Comp :=
+ Make_Indexed_Component (Loc,
+ Prefix => Make_Identifier (Loc, Name_uA),
+ Expressions => Index_List);
+
+ if Is_Scalar_Type (Comp_Type) then
+ Anam := Name_Valid;
+ else
+ Anam := Name_Valid_Scalars;
+ end if;
+
+ return New_List (
+ Make_If_Statement (Loc,
+ Condition =>
+ Make_Op_Not (Loc,
+ Right_Opnd =>
+ Make_Attribute_Reference (Loc,
+ Attribute_Name => Anam,
+ Prefix => Comp)),
+ Then_Statements => New_List (
+ Make_Simple_Return_Statement (Loc,
+ Expression => New_Occurrence_Of (Standard_False, Loc)))));
+ end Test_Component;
+
+ ------------------------
+ -- Test_One_Dimension --
+ ------------------------
+
+ function Test_One_Dimension (N : Int) return List_Id is
+ Index : Entity_Id;
+
+ begin
+ -- If all dimensions dealt with, we simply test the component
+
+ if N > Number_Dimensions (A_Type) then
+ return Test_Component;
+
+ -- Here we generate the required loop
+
+ else
+ Index :=
+ Make_Defining_Identifier (Loc, New_External_Name ('J', N));
+
+ Append (New_Reference_To (Index, Loc), Index_List);
+
+ return New_List (
+ Make_Implicit_Loop_Statement (Nod,
+ Identifier => Empty,
+ Iteration_Scheme =>
+ Make_Iteration_Scheme (Loc,
+ Loop_Parameter_Specification =>
+ Make_Loop_Parameter_Specification (Loc,
+ Defining_Identifier => Index,
+ Discrete_Subtype_Definition =>
+ Make_Attribute_Reference (Loc,
+ Prefix => Make_Identifier (Loc, Name_uA),
+ Attribute_Name => Name_Range,
+ Expressions => New_List (
+ Make_Integer_Literal (Loc, N))))),
+ Statements => Test_One_Dimension (N + 1)),
+ Make_Simple_Return_Statement (Loc,
+ Expression => New_Occurrence_Of (Standard_True, Loc)));
+ end if;
+ end Test_One_Dimension;
+
+ -- Start of processing for Build_Array_VS_Func
+
+ begin
+ Index_List := New_List;
+ Func_Id := Make_Defining_Identifier (Loc, New_Internal_Name ('V'));
+
+ Body_Stmts := Test_One_Dimension (1);
+
+ -- Parameter is always (A : A_Typ)
+
+ Formals := New_List (
+ Make_Parameter_Specification (Loc,
+ Defining_Identifier => Make_Defining_Identifier (Loc, Name_uA),
+ In_Present => True,
+ Out_Present => False,
+ Parameter_Type => New_Reference_To (A_Type, Loc)));
+
+ -- Build body
+
+ Set_Ekind (Func_Id, E_Function);
+ Set_Is_Internal (Func_Id);
+
+ Insert_Action (Nod,
+ Make_Subprogram_Body (Loc,
+ Specification =>
+ Make_Function_Specification (Loc,
+ Defining_Unit_Name => Func_Id,
+ Parameter_Specifications => Formals,
+ Result_Definition =>
+ New_Occurrence_Of (Standard_Boolean, Loc)),
+ Declarations => New_List,
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => Body_Stmts)));
+
+ if not Debug_Generated_Code then
+ Set_Debug_Info_Off (Func_Id);
+ end if;
+
+ return Func_Id;
+ end Build_Array_VS_Func;
+
----------------------------------
-- Compile_Stream_Body_In_Scope --
----------------------------------
@@ -5373,8 +5524,89 @@ package body Exp_Attr is
-------------------
when Attribute_Valid_Scalars => Valid_Scalars : declare
+ Ftyp : Entity_Id;
+
begin
- raise Program_Error;
+ if Present (Underlying_Type (Ptyp)) then
+ Ftyp := Underlying_Type (Ptyp);
+ else
+ Ftyp := Ptyp;
+ end if;
+
+ -- For scalar types, Valid_Scalars is the same as Valid
+
+ if Is_Scalar_Type (Ftyp) then
+ Rewrite (N,
+ Make_Attribute_Reference (Loc,
+ Attribute_Name => Name_Valid,
+ Prefix => Pref));
+ Analyze_And_Resolve (N, Standard_Boolean);
+
+ -- For array types, we construct a function that determines if there
+ -- are any non-valid scalar subcomponents, and call the function.
+ -- We only do this for arrays whose component type needs checking
+
+ elsif Is_Array_Type (Ftyp)
+ and then not No_Scalar_Parts (Component_Type (Ftyp))
+ then
+ Rewrite (N,
+ Make_Function_Call (Loc,
+ Name =>
+ New_Occurrence_Of (Build_Array_VS_Func (Ftyp, N), Loc),
+ Parameter_Associations => New_List (Pref)));
+
+ Analyze_And_Resolve (N, Standard_Boolean);
+
+ -- For record types, we build a big conditional expression, applying
+ -- Valid or Valid_Scalars as appropriate to all relevant components.
+
+ elsif (Is_Record_Type (Ptyp) or else Has_Discriminants (Ptyp))
+ and then not No_Scalar_Parts (Ptyp)
+ then
+ declare
+ C : Entity_Id;
+ X : Node_Id;
+ A : Name_Id;
+
+ begin
+ X := New_Occurrence_Of (Standard_True, Loc);
+ C := First_Component_Or_Discriminant (Ptyp);
+ while Present (C) loop
+ if No_Scalar_Parts (Etype (C)) then
+ goto Continue;
+ elsif Is_Scalar_Type (Etype (C)) then
+ A := Name_Valid;
+ else
+ A := Name_Valid_Scalars;
+ end if;
+
+ X :=
+ Make_And_Then (Loc,
+ Left_Opnd => X,
+ Right_Opnd =>
+ Make_Attribute_Reference (Loc,
+ Attribute_Name => A,
+ Prefix =>
+ Make_Selected_Component (Loc,
+ Prefix =>
+ Duplicate_Subexpr (Pref, Name_Req => True),
+ Selector_Name =>
+ New_Occurrence_Of (C, Loc))));
+ <<Continue>>
+ Next_Component_Or_Discriminant (C);
+ end loop;
+
+ Rewrite (N, X);
+ Analyze_And_Resolve (N, Standard_Boolean);
+ end;
+
+ -- For all other types, result is True (but not static)
+
+ else
+ Rewrite (N, New_Occurrence_Of (Standard_Boolean, Loc));
+ Analyze_And_Resolve (N, Standard_Boolean);
+ Set_Is_Static_Expression (N, False);
+ end if;
end Valid_Scalars;
-----------
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index d04512ad5e1..02a733cee88 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -3072,7 +3072,7 @@ package body Exp_Ch4 is
Low_Bound := Opnd_Low_Bound (1);
-- OK, we don't know the lower bound, we have to build a horrible
- -- expression actions node of the form
+ -- conditional expression node of the form
-- if Cond1'Length /= 0 then
-- Opnd1 low bound
@@ -3998,9 +3998,9 @@ package body Exp_Ch4 is
end if;
end;
- -- We set the allocator as analyzed so that when we analyze the
- -- expression actions node, we do not get an unwanted recursive
- -- expansion of the allocator expression.
+ -- We set the allocator as analyzed so that when we analyze
+ -- the conditional expression node, we do not get an unwanted
+ -- recursive expansion of the allocator expression.
Set_Analyzed (N, True);
Nod := Relocate_Node (N);
@@ -4279,7 +4279,7 @@ package body Exp_Ch4 is
-- Expand_N_Conditional_Expression --
-------------------------------------
- -- Deal with limited types and expression actions
+ -- Deal with limited types and condition actions
procedure Expand_N_Conditional_Expression (N : Node_Id) is
Loc : constant Source_Ptr := Sloc (N);
@@ -7832,9 +7832,7 @@ package body Exp_Ch4 is
begin
-- Do validity check if validity checking operands
- if Validity_Checks_On
- and then Validity_Check_Operands
- then
+ if Validity_Checks_On and then Validity_Check_Operands then
Ensure_Valid (Operand);
end if;
@@ -7866,7 +7864,7 @@ package body Exp_Ch4 is
-- end if;
-- end loop;
- -- Conversely, an existentially quantified expression:
+ -- Similarly, an existentially quantified expression:
-- for some X in range => Cond
@@ -7884,75 +7882,79 @@ package body Exp_Ch4 is
-- given by an iterator specification, not a loop parameter specification.
procedure Expand_N_Quantified_Expression (N : Node_Id) is
- Loc : constant Source_Ptr := Sloc (N);
- Is_Universal : constant Boolean := All_Present (N);
- Actions : constant List_Id := New_List;
- Tnn : constant Entity_Id := Make_Temporary (Loc, 'T', N);
- Cond : Node_Id;
- Decl : Node_Id;
- I_Scheme : Node_Id;
- Original_N : Node_Id;
- Test : Node_Id;
+ Actions : constant List_Id := New_List;
+ For_All : constant Boolean := All_Present (N);
+ Iter_Spec : constant Node_Id := Iterator_Specification (N);
+ Loc : constant Source_Ptr := Sloc (N);
+ Loop_Spec : constant Node_Id := Loop_Parameter_Specification (N);
+ Cond : Node_Id;
+ Flag : Entity_Id;
+ Scheme : Node_Id;
+ Stmts : List_Id;
begin
- -- Retrieve the original quantified expression (non analyzed)
+ -- Create the declaration of the flag which tracks the status of the
+ -- quantified expression. Generate:
- if Present (Loop_Parameter_Specification (N)) then
- Original_N := Parent (Parent (Loop_Parameter_Specification (N)));
- else
- Original_N := Parent (Parent (Iterator_Specification (N)));
- end if;
+ -- Flag : Boolean := (True | False);
- -- Rewrite N with the original quantified expression
+ Flag := Make_Temporary (Loc, 'T', N);
- Rewrite (N, Original_N);
-
- Decl :=
+ Append_To (Actions,
Make_Object_Declaration (Loc,
- Defining_Identifier => Tnn,
+ Defining_Identifier => Flag,
Object_Definition => New_Occurrence_Of (Standard_Boolean, Loc),
Expression =>
- New_Occurrence_Of (Boolean_Literals (Is_Universal), Loc));
- Append_To (Actions, Decl);
+ New_Occurrence_Of (Boolean_Literals (For_All), Loc)));
+
+ -- Construct the circuitry which tracks the status of the quantified
+ -- expression. Generate:
+
+ -- if [not] Cond then
+ -- Flag := (False | True);
+ -- exit;
+ -- end if;
Cond := Relocate_Node (Condition (N));
- if Is_Universal then
+ if For_All then
Cond := Make_Op_Not (Loc, Cond);
end if;
- Test :=
+ Stmts := New_List (
Make_Implicit_If_Statement (N,
Condition => Cond,
Then_Statements => New_List (
Make_Assignment_Statement (Loc,
- Name => New_Occurrence_Of (Tnn, Loc),
+ Name => New_Occurrence_Of (Flag, Loc),
Expression =>
- New_Occurrence_Of (Boolean_Literals (not Is_Universal), Loc)),
- Make_Exit_Statement (Loc)));
+ New_Occurrence_Of (Boolean_Literals (not For_All), Loc)),
+ Make_Exit_Statement (Loc))));
- if Present (Loop_Parameter_Specification (N)) then
- I_Scheme :=
+ -- Build the loop equivalent of the quantified expression
+
+ if Present (Iter_Spec) then
+ Scheme :=
Make_Iteration_Scheme (Loc,
- Loop_Parameter_Specification =>
- Loop_Parameter_Specification (N));
+ Iterator_Specification => Iter_Spec);
else
- I_Scheme :=
+ Scheme :=
Make_Iteration_Scheme (Loc,
- Iterator_Specification => Iterator_Specification (N));
+ Loop_Parameter_Specification => Loop_Spec);
end if;
Append_To (Actions,
Make_Loop_Statement (Loc,
- Iteration_Scheme => I_Scheme,
- Statements => New_List (Test),
+ Iteration_Scheme => Scheme,
+ Statements => Stmts,
End_Label => Empty));
+ -- Transform the quantified expression
+
Rewrite (N,
Make_Expression_With_Actions (Loc,
- Expression => New_Occurrence_Of (Tnn, Loc),
+ Expression => New_Occurrence_Of (Flag, Loc),
Actions => Actions));
-
Analyze_And_Resolve (N, Standard_Boolean);
end Expand_N_Quantified_Expression;
diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb
index 6d00dc806ae..82fc705ecff 100644
--- a/gcc/ada/exp_ch5.adb
+++ b/gcc/ada/exp_ch5.adb
@@ -2777,7 +2777,7 @@ package body Exp_Ch5 is
end loop;
-- Loop through elsif parts, dealing with constant conditions and
- -- possible expression actions that are present.
+ -- possible condition actions that are present.
if Present (Elsif_Parts (N)) then
E := First (Elsif_Parts (N));
@@ -3303,6 +3303,14 @@ package body Exp_Ch5 is
New_Reference_To (Component_Type (Array_Typ), Loc),
Name => Ind_Comp));
+ -- Mark the loop variable as needing debug info, so that expansion
+ -- of the renaming will result in Materialize_Entity getting set via
+ -- Debug_Renaming_Declaration. (This setting is needed here because
+ -- the setting in Freeze_Entity comes after the expansion, which is
+ -- too late. ???)
+
+ Set_Debug_Info_Needed (Id);
+
-- for Index in Array loop
-- This case utilizes the already given iterator name
diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index 0347dcc5bd7..f8730f3d9ab 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -1824,15 +1824,14 @@ package body Exp_Ch7 is
-- Obj : Access_Typ := Non_BIP_Function_Call'reference;
-- Obj : Access_Typ :=
- -- BIP_Function_Call
- -- (..., BIPaccess => null, ...)'reference;
+ -- BIP_Function_Call (BIPalloc => 2, ...)'reference;
elsif Is_Access_Type (Obj_Typ)
and then Needs_Finalization
(Available_View (Designated_Type (Obj_Typ)))
and then Present (Expr)
and then
- (Is_Null_Access_BIP_Func_Call (Expr)
+ (Is_Secondary_Stack_BIP_Func_Call (Expr)
or else
(Is_Non_BIP_Func_Call (Expr)
and then not Is_Related_To_Func_Return (Obj_Id)))
@@ -1918,16 +1917,17 @@ package body Exp_Ch7 is
Processing_Actions (Has_No_Init => True);
-- Detect a case where a source object has been initialized by
- -- a controlled function call which was later rewritten as a
- -- class-wide conversion of Ada.Tags.Displace.
+ -- a controlled function call or another object which was later
+ -- rewritten as a class-wide conversion of Ada.Tags.Displace.
- -- Obj : Class_Wide_Type := Function_Call (...);
+ -- Obj1 : CW_Type := Src_Obj;
+ -- Obj2 : CW_Type := Function_Call (...);
- -- Temp : ... := Function_Call (...)'reference;
- -- Obj : Class_Wide_Type renames
- -- (... Ada.Tags.Displace (Temp));
+ -- Obj1 : CW_Type renames (... Ada.Tags.Displace (Src_Obj));
+ -- Tmp : ... := Function_Call (...)'reference;
+ -- Obj2 : CW_Type renames (... Ada.Tags.Displace (Tmp));
- elsif Is_Displacement_Of_Ctrl_Function_Result (Obj_Id) then
+ elsif Is_Displacement_Of_Object_Or_Function_Result (Obj_Id) then
Processing_Actions (Has_No_Init => True);
end if;
diff --git a/gcc/ada/exp_ch9.adb b/gcc/ada/exp_ch9.adb
index a827284ff63..212ed30cebd 100644
--- a/gcc/ada/exp_ch9.adb
+++ b/gcc/ada/exp_ch9.adb
@@ -25,6 +25,7 @@
with Atree; use Atree;
with Checks; use Checks;
+with Debug; use Debug;
with Einfo; use Einfo;
with Elists; use Elists;
with Errout; use Errout;
@@ -60,6 +61,7 @@ with Sinfo; use Sinfo;
with Snames; use Snames;
with Stand; use Stand;
with Stringt; use Stringt;
+with Table;
with Targparm; use Targparm;
with Tbuild; use Tbuild;
with Uintp; use Uintp;
@@ -75,6 +77,34 @@ package body Exp_Ch9 is
Entry_Family_Bound : constant Int := 2**16;
+ ------------------------------
+ -- Lock Free Data Structure --
+ ------------------------------
+
+ -- A data structure used for the Lock Free (LF) implementation of protected
+ -- objects. Since a protected subprogram can only access a single protected
+ -- component in the LF implementation, this structure stores each protected
+ -- subprogram and its accessed protected component when the protected
+ -- object allows the LF implementation.
+
+ type Lock_Free_Sub_Type is record
+ Sub_Body : Node_Id;
+ Comp_Id : Entity_Id;
+ end record;
+
+ subtype Subprogram_Id is Nat;
+
+ -- The following table used for the Lock Free implementation of protected
+ -- objects maps Lock_Free_Sub_Type to Subprogram_Id.
+
+ package LF_Sub_Table is new Table.Table (
+ Table_Component_Type => Lock_Free_Sub_Type,
+ Table_Index_Type => Subprogram_Id,
+ Table_Low_Bound => 1,
+ Table_Initial => 5,
+ Table_Increment => 5,
+ Table_Name => "LF_Sub_Table");
+
-----------------------
-- Local Subprograms --
-----------------------
@@ -109,6 +139,10 @@ package body Exp_Ch9 is
-- Decls is the list of declarations to be enhanced.
-- Ent is the entity for the original entry body.
+ function Allow_Lock_Free_Implementation (N : Node_Id) return Boolean;
+ -- Given a protected body N, return True if N permits a lock free
+ -- implementation.
+
function Build_Accept_Body (Astat : Node_Id) return Node_Id;
-- Transform accept statement into a block with added exception handler.
-- Used both for simple accept statements and for accept alternatives in
@@ -144,6 +178,32 @@ package body Exp_Ch9 is
-- of the range of each entry family. A single array with that size is
-- allocated for each concurrent object of the type.
+ function Build_Find_Body_Index (Typ : Entity_Id) return Node_Id;
+ -- Build the function that translates the entry index in the call
+ -- (which depends on the size of entry families) into an index into the
+ -- Entry_Bodies_Array, to determine the body and barrier function used
+ -- in a protected entry call. A pointer to this function appears in every
+ -- protected object.
+
+ function Build_Find_Body_Index_Spec (Typ : Entity_Id) return Node_Id;
+ -- Build subprogram declaration for previous one
+
+ function Build_Lock_Free_Protected_Subprogram_Body
+ (N : Node_Id;
+ Pid : Node_Id;
+ N_Op_Spec : Node_Id) return Node_Id;
+ -- This function is used to construct the lock free version of a protected
+ -- subprogram when the protected type denoted by Pid allows the lock free
+ -- implementation. It only contains a call to the unprotected version of
+ -- the subprogram body.
+
+ function Build_Lock_Free_Unprotected_Subprogram_Body
+ (N : Node_Id;
+ Pid : Node_Id) return Node_Id;
+ -- This function is used to construct the lock free version of an
+ -- unprotected subprogram when the protected type denoted by Pid allows the
+ -- lock free implementation.
+
function Build_Parameter_Block
(Loc : Source_Ptr;
Actuals : List_Id;
@@ -169,49 +229,6 @@ package body Exp_Ch9 is
-- and Decl is the enclosing synchronized type declaration at whose
-- freeze point the generated body is analyzed.
- function Build_Renamed_Formal_Declaration
- (New_F : Entity_Id;
- Formal : Entity_Id;
- Comp : Entity_Id;
- Renamed_Formal : Node_Id) return Node_Id;
- -- Create a renaming declaration for a formal, within a protected entry
- -- body or an accept body. The renamed object is a component of the
- -- parameter block that is a parameter in the entry call.
-
- -- In Ada 2012, if the formal is an incomplete tagged type, the renaming
- -- does not dereference the corresponding component to prevent an illegal
- -- use of the incomplete type (AI05-0151).
-
- procedure Build_Wrapper_Bodies
- (Loc : Source_Ptr;
- Typ : Entity_Id;
- N : Node_Id);
- -- Ada 2005 (AI-345): Typ is either a concurrent type or the corresponding
- -- record of a concurrent type. N is the insertion node where all bodies
- -- will be placed. This routine builds the bodies of the subprograms which
- -- serve as an indirection mechanism to overriding primitives of concurrent
- -- types, entries and protected procedures. Any new body is analyzed.
-
- procedure Build_Wrapper_Specs
- (Loc : Source_Ptr;
- Typ : Entity_Id;
- N : in out Node_Id);
- -- Ada 2005 (AI-345): Typ is either a concurrent type or the corresponding
- -- record of a concurrent type. N is the insertion node where all specs
- -- will be placed. This routine builds the specs of the subprograms which
- -- serve as an indirection mechanism to overriding primitives of concurrent
- -- types, entries and protected procedures. Any new spec is analyzed.
-
- function Build_Find_Body_Index (Typ : Entity_Id) return Node_Id;
- -- Build the function that translates the entry index in the call
- -- (which depends on the size of entry families) into an index into the
- -- Entry_Bodies_Array, to determine the body and barrier function used
- -- in a protected entry call. A pointer to this function appears in every
- -- protected object.
-
- function Build_Find_Body_Index_Spec (Typ : Entity_Id) return Node_Id;
- -- Build subprogram declaration for previous one
-
function Build_Protected_Entry
(N : Node_Id;
Ent : Entity_Id;
@@ -252,6 +269,19 @@ package body Exp_Ch9 is
-- a cleanup handler that unlocks the object in all cases.
-- (see Exp_Ch7.Expand_Cleanup_Actions).
+ function Build_Renamed_Formal_Declaration
+ (New_F : Entity_Id;
+ Formal : Entity_Id;
+ Comp : Entity_Id;
+ Renamed_Formal : Node_Id) return Node_Id;
+ -- Create a renaming declaration for a formal, within a protected entry
+ -- body or an accept body. The renamed object is a component of the
+ -- parameter block that is a parameter in the entry call.
+ --
+ -- In Ada 2012, if the formal is an incomplete tagged type, the renaming
+ -- does not dereference the corresponding component to prevent an illegal
+ -- use of the incomplete type (AI05-0151).
+
function Build_Selected_Name
(Prefix : Entity_Id;
Selector : Entity_Id;
@@ -291,6 +321,26 @@ package body Exp_Ch9 is
-- subprogram that is called from all protected operations on the same
-- object, including the protected version of the same subprogram.
+ procedure Build_Wrapper_Bodies
+ (Loc : Source_Ptr;
+ Typ : Entity_Id;
+ N : Node_Id);
+ -- Ada 2005 (AI-345): Typ is either a concurrent type or the corresponding
+ -- record of a concurrent type. N is the insertion node where all bodies
+ -- will be placed. This routine builds the bodies of the subprograms which
+ -- serve as an indirection mechanism to overriding primitives of concurrent
+ -- types, entries and protected procedures. Any new body is analyzed.
+
+ procedure Build_Wrapper_Specs
+ (Loc : Source_Ptr;
+ Typ : Entity_Id;
+ N : in out Node_Id);
+ -- Ada 2005 (AI-345): Typ is either a concurrent type or the corresponding
+ -- record of a concurrent type. N is the insertion node where all specs
+ -- will be placed. This routine builds the specs of the subprograms which
+ -- serve as an indirection mechanism to overriding primitives of concurrent
+ -- types, entries and protected procedures. Any new spec is analyzed.
+
procedure Collect_Entry_Families
(Loc : Source_Ptr;
Cdecls : List_Id;
@@ -299,6 +349,10 @@ package body Exp_Ch9 is
-- For each entry family in a concurrent type, create an anonymous array
-- type of the right size, and add a component to the corresponding_record.
+ function Comp_Of (Sub_Body : Node_Id) return Entity_Id;
+ -- For the lock free implementation, return the protected component entity
+ -- referenced in Sub_Body using LF_Sub_Table.
+
function Concurrent_Object
(Spec_Id : Entity_Id;
Conc_Typ : Entity_Id) return Entity_Id;
@@ -322,6 +376,26 @@ package body Exp_Ch9 is
-- step of the expansion must to be done after private data has been moved
-- to its final resting scope to ensure proper visibility of debug objects.
+ procedure Extract_Dispatching_Call
+ (N : Node_Id;
+ Call_Ent : out Entity_Id;
+ Object : out Entity_Id;
+ Actuals : out List_Id;
+ Formals : out List_Id);
+ -- Given a dispatching call, extract the entity of the name of the call,
+ -- its actual dispatching object, its actual parameters and the formal
+ -- parameters of the overridden interface-level version. If the type of
+ -- the dispatching object is an access type then an explicit dereference
+ -- is returned in Object.
+
+ procedure Extract_Entry
+ (N : Node_Id;
+ Concval : out Node_Id;
+ Ename : out Node_Id;
+ Index : out Node_Id);
+ -- Given an entry call, returns the associated concurrent object,
+ -- the entry name, and the entry family index.
+
function Family_Offset
(Loc : Source_Ptr;
Hi : Node_Id;
@@ -358,26 +432,6 @@ package body Exp_Ch9 is
-- the scope of Context_Id and Context_Decls is the declarative list of
-- Context.
- procedure Extract_Dispatching_Call
- (N : Node_Id;
- Call_Ent : out Entity_Id;
- Object : out Entity_Id;
- Actuals : out List_Id;
- Formals : out List_Id);
- -- Given a dispatching call, extract the entity of the name of the call,
- -- its actual dispatching object, its actual parameters and the formal
- -- parameters of the overridden interface-level version. If the type of
- -- the dispatching object is an access type then an explicit dereference
- -- is returned in Object.
-
- procedure Extract_Entry
- (N : Node_Id;
- Concval : out Node_Id;
- Ename : out Node_Id;
- Index : out Node_Id);
- -- Given an entry call, returns the associated concurrent object,
- -- the entry name, and the entry family index.
-
function Find_Task_Or_Protected_Pragma
(T : Node_Id;
P : Name_Id) return Node_Id;
@@ -393,6 +447,9 @@ package body Exp_Ch9 is
-- Task_Body_Procedure of Spec_Id. The returned entity denotes formal
-- parameter _E.
+ function Is_Exception_Safe (Subprogram : Node_Id) return Boolean;
+ -- Tell whether a given subprogram cannot raise an exception
+
function Is_Potentially_Large_Family
(Base_Index : Entity_Id;
Conctyp : Entity_Id;
@@ -762,6 +819,263 @@ package body Exp_Ch9 is
Prepend_To (Decls, Decl);
end Add_Object_Pointer;
+ ------------------------------------
+ -- Allow_Lock_Free_Implementation --
+ ------------------------------------
+
+ -- Here are the restrictions for the Lock Free implementation
+
+ -- Implementation Restrictions on protected declaration
+
+ -- There must be only protected scalar components (at least one)
+
+ -- Component types must support an atomic compare_exchange primitive
+ -- (size equals to 1, 2, 4 or 8 bytes).
+
+ -- No entries
+
+ -- Implementation Restrictions on protected operations
+
+ -- Cannot refer to non-constant outside of the scope of the protected
+ -- operation.
+
+ -- Can only access a single protected component: all protected
+ -- component names appearing in a scope (including nested scopes)
+ -- must statically denote the same protected component.
+
+ -- Fundamental Restrictions on protected operations
+
+ -- No loop and procedure call statements
+
+ -- Any function call and attribute reference must be static
+
+ function Allow_Lock_Free_Implementation (N : Node_Id) return Boolean is
+ Decls : constant List_Id := Declarations (N);
+ Spec : constant Entity_Id := Corresponding_Spec (N);
+ Pro_Def : constant Node_Id := Protected_Definition (Parent (Spec));
+ Pri_Decls : constant List_Id := Private_Declarations (Pro_Def);
+ Vis_Decls : constant List_Id := Visible_Declarations (Pro_Def);
+
+ Comp_Id : Entity_Id;
+ Comp_Size : Int;
+ Comp_Type : Entity_Id;
+ No_Component : Boolean := True;
+ N_Decl : Node_Id;
+
+ function Permit_Lock_Free (Sub_Body : Node_Id) return Boolean;
+ -- Return True if the protected subprogram body Sub_Body doesn't
+ -- prevent the lock free code expansion, i.e. Sub_Body meets all the
+ -- restrictions listed below that allow the lock free implementation.
+ --
+ -- Can only access a single protected component
+ --
+ -- No loop and procedure call statements
+
+ -- Any function call and attribute reference must be static
+
+ -- Cannot refer to non-constant outside of the scope of the protected
+ -- subprogram.
+
+ ----------------------
+ -- Permit_Lock_Free --
+ ----------------------
+
+ function Permit_Lock_Free (Sub_Body : Node_Id) return Boolean is
+ Sub_Id : constant Entity_Id := Corresponding_Spec (Sub_Body);
+ Comp_Id : Entity_Id := Empty;
+ LF_Sub : Lock_Free_Sub_Type;
+
+ function Check_Node (N : Node_Id) return Traverse_Result;
+ -- Check the node N meet the lock free restrictions
+
+ function Check_All_Nodes is new Traverse_Func (Check_Node);
+
+ ----------------
+ -- Check_Node --
+ ----------------
+
+ function Check_Node (N : Node_Id) return Traverse_Result is
+ Comp_Decl : Node_Id;
+ Id : Entity_Id;
+
+ begin
+ case Nkind (N) is
+
+ -- Function call or attribute reference case
+
+ when N_Function_Call | N_Attribute_Reference =>
+
+ -- Any function call and attribute reference must be static
+
+ if not Is_Static_Expression (N) then
+ return Abandon;
+ end if;
+
+ -- Loop and procedure call statement case
+
+ when N_Procedure_Call_Statement | N_Loop_Statement =>
+ -- No loop and procedure call statements
+ return Abandon;
+
+ -- Identifier case
+
+ when N_Identifier =>
+ if Present (Entity (N)) then
+ Id := Entity (N);
+
+ -- Cannot refer to non-constant entities outside of the
+ -- scope of the protected subprogram.
+
+ if Ekind (Id) in Assignable_Kind
+ and then Sloc (Scope (Id)) > No_Location
+ and then not Scope_Within_Or_Same (Scope (Id), Sub_Id)
+ and then not Scope_Within_Or_Same (Scope (Id),
+ Protected_Body_Subprogram (Sub_Id))
+ then
+ return Abandon;
+ end if;
+
+ -- Can only access a single protected component
+
+ if Ekind_In (Id, E_Constant, E_Variable)
+ and then Present (Prival_Link (Id))
+ then
+ Comp_Decl := Parent (Prival_Link (Id));
+
+ if Nkind (Comp_Decl) = N_Component_Declaration
+ and then Is_List_Member (Comp_Decl)
+ and then List_Containing (Comp_Decl) = Pri_Decls
+ then
+ -- Check if another protected component has already
+ -- been accessed by the subprogram body.
+
+ if Present (Comp_Id)
+ and then Comp_Id /= Prival_Link (Id)
+ then
+ return Abandon;
+
+ elsif not Present (Comp_Id) then
+ Comp_Id := Prival_Link (Id);
+ end if;
+ end if;
+ end if;
+ end if;
+
+ -- Ok for all other nodes
+
+ when others => return OK;
+ end case;
+
+ return OK;
+ end Check_Node;
+
+ -- Start of processing for Permit_Lock_Free
+
+ begin
+ if Check_All_Nodes (Sub_Body) = OK then
+
+ -- Fill LF_Sub with Sub_Body and its corresponding protected
+ -- component entity and then store LF_Sub in the lock free
+ -- subprogram table LF_Sub_Table.
+
+ LF_Sub.Sub_Body := Sub_Body;
+ LF_Sub.Comp_Id := Comp_Id;
+ LF_Sub_Table.Append (LF_Sub);
+ return True;
+
+ else
+ return False;
+ end if;
+ end Permit_Lock_Free;
+
+ -- Start of processing for Allow_Lock_Free_Implementation
+
+ begin
+ -- Debug switch -gnatd9 enables Lock Free implementation
+
+ if not Debug_Flag_9 then
+ return False;
+ end if;
+
+ -- Look for any entries declared in the visible part of the protected
+ -- declaration.
+
+ N_Decl := First (Vis_Decls);
+ while Present (N_Decl) loop
+ if Nkind (N_Decl) = N_Entry_Declaration then
+ return False;
+ end if;
+
+ N_Decl := Next (N_Decl);
+ end loop;
+
+ -- Look for any entry, plus look for any scalar component declared in
+ -- the private part of the protected declaration.
+
+ N_Decl := First (Pri_Decls);
+ while Present (N_Decl) loop
+
+ -- Check at least one scalar component is declared
+
+ if Nkind (N_Decl) = N_Component_Declaration then
+ if No_Component then
+ No_Component := False;
+ end if;
+
+ Comp_Id := Defining_Identifier (N_Decl);
+ Comp_Type := Etype (Comp_Id);
+
+ -- Verify the component is a scalar
+
+ if not Is_Scalar_Type (Comp_Type) then
+ return False;
+ end if;
+
+ Comp_Size := UI_To_Int (Esize (Base_Type (Comp_Type)));
+
+ -- Check the size of the component is 8, 16, 32 or 64 bits
+
+ case Comp_Size is
+ when 8 | 16 | 32 | 64 =>
+ null;
+ when others =>
+ return False;
+ end case;
+
+ -- Check there is no entry declared in the private part.
+
+ else
+ if Nkind (N_Decl) = N_Entry_Declaration then
+ return False;
+ end if;
+ end if;
+
+ N_Decl := Next (N_Decl);
+ end loop;
+
+ -- One scalar component must be present
+
+ if No_Component then
+ return False;
+ end if;
+
+ -- Ensure all protected subprograms meet the restrictions that allow the
+ -- lock free implementation.
+
+ N_Decl := First (Decls);
+ while Present (N_Decl) loop
+ if Nkind (N_Decl) = N_Subprogram_Body
+ and then not Permit_Lock_Free (N_Decl)
+ then
+ return False;
+ end if;
+
+ Next (N_Decl);
+ end loop;
+
+ return True;
+ end Allow_Lock_Free_Implementation;
+
-----------------------
-- Build_Accept_Body --
-----------------------
@@ -2720,18 +3034,16 @@ package body Exp_Ch9 is
if No (If_St) then
If_St :=
Make_Implicit_If_Statement (Typ,
- Condition => Cond,
+ Condition => Cond,
Then_Statements => Stats,
- Elsif_Parts => New_List);
-
+ Elsif_Parts => New_List);
Ret := If_St;
else
- Append (
+ Append_To (Elsif_Parts (If_St),
Make_Elsif_Part (Loc,
Condition => Cond,
- Then_Statements => Stats),
- Elsif_Parts (If_St));
+ Then_Statements => Stats));
end if;
end Add_If_Clause;
@@ -2788,7 +3100,7 @@ package body Exp_Ch9 is
else
-- Suppose entries e1, e2, ... have size l1, l2, ... we generate
-- the following:
- --
+
-- if E <= l1 then return 1;
-- elsif E <= l1 + l2 then return 2;
-- ...
@@ -2834,8 +3146,8 @@ package body Exp_Ch9 is
return
Make_Subprogram_Body (Loc,
- Specification => Spec,
- Declarations => Decls,
+ Specification => Spec,
+ Declarations => Decls,
Handled_Statement_Sequence =>
Make_Handled_Sequence_Of_Statements (Loc,
Statements => New_List (Ret)));
@@ -2856,21 +3168,543 @@ package body Exp_Ch9 is
begin
return
Make_Function_Specification (Loc,
- Defining_Unit_Name => Id,
+ Defining_Unit_Name => Id,
Parameter_Specifications => New_List (
Make_Parameter_Specification (Loc,
Defining_Identifier => Parm1,
- Parameter_Type =>
+ Parameter_Type =>
New_Reference_To (RTE (RE_Address), Loc)),
Make_Parameter_Specification (Loc,
Defining_Identifier => Parm2,
- Parameter_Type =>
+ Parameter_Type =>
New_Reference_To (RTE (RE_Protected_Entry_Index), Loc))),
- Result_Definition => New_Occurrence_Of (
+
+ Result_Definition => New_Occurrence_Of (
RTE (RE_Protected_Entry_Index), Loc));
end Build_Find_Body_Index_Spec;
+ -----------------------------------------------
+ -- Build_Lock_Free_Protected_Subprogram_Body --
+ -----------------------------------------------
+
+ function Build_Lock_Free_Protected_Subprogram_Body
+ (N : Node_Id;
+ Pid : Node_Id;
+ N_Op_Spec : Node_Id) return Node_Id
+ is
+ Loc : constant Source_Ptr := Sloc (N);
+ Op_Spec : Node_Id;
+ P_Op_Spec : Node_Id;
+ Uactuals : List_Id;
+ Pformal : Node_Id;
+ Unprot_Call : Node_Id;
+ R : Node_Id;
+ Return_Stmt : Node_Id := Empty; -- init to avoid gcc 3 warning
+ Exc_Safe : Boolean;
+
+ begin
+ Op_Spec := Specification (N);
+ Exc_Safe := Is_Exception_Safe (N);
+
+ P_Op_Spec :=
+ Build_Protected_Sub_Specification (N, Pid, Protected_Mode);
+
+ -- Build a list of the formal parameters of the protected version of
+ -- the subprogram to use as the actual parameters of the unprotected
+ -- version.
+
+ Uactuals := New_List;
+ Pformal := First (Parameter_Specifications (P_Op_Spec));
+ while Present (Pformal) loop
+ Append_To (Uactuals,
+ Make_Identifier (Loc, Chars (Defining_Identifier (Pformal))));
+ Next (Pformal);
+ end loop;
+
+ -- Make a call to the unprotected version of the subprogram built above
+ -- for use by the protected version built below.
+
+ if Nkind (Op_Spec) = N_Function_Specification then
+ if Exc_Safe then
+ R := Make_Temporary (Loc, 'R');
+ Unprot_Call :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => R,
+ Constant_Present => True,
+ Object_Definition => New_Copy (Result_Definition (N_Op_Spec)),
+ Expression =>
+ Make_Function_Call (Loc,
+ Name => Make_Identifier (Loc,
+ Chars => Chars (Defining_Unit_Name (N_Op_Spec))),
+ Parameter_Associations => Uactuals));
+
+ Return_Stmt :=
+ Make_Simple_Return_Statement (Loc,
+ Expression => New_Reference_To (R, Loc));
+
+ else
+ Unprot_Call := Make_Simple_Return_Statement (Loc,
+ Expression => Make_Function_Call (Loc,
+ Name =>
+ Make_Identifier (Loc,
+ Chars => Chars (Defining_Unit_Name (N_Op_Spec))),
+ Parameter_Associations => Uactuals));
+ end if;
+
+ else
+ Unprot_Call :=
+ Make_Procedure_Call_Statement (Loc,
+ Name =>
+ Make_Identifier (Loc, Chars (Defining_Unit_Name (N_Op_Spec))),
+ Parameter_Associations => Uactuals);
+ end if;
+
+ if Nkind (Op_Spec) = N_Function_Specification
+ and then Exc_Safe
+ then
+ Unprot_Call :=
+ Make_Block_Statement (Loc,
+ Declarations => New_List (Unprot_Call),
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => New_List (Return_Stmt)));
+ end if;
+
+ return
+ Make_Subprogram_Body (Loc,
+ Declarations => Empty_List,
+ Specification => P_Op_Spec,
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => New_List (Unprot_Call)));
+ end Build_Lock_Free_Protected_Subprogram_Body;
+
+ -------------------------------------------------
+ -- Build_Lock_Free_Unprotected_Subprogram_Body --
+ -------------------------------------------------
+
+ function Build_Lock_Free_Unprotected_Subprogram_Body
+ (N : Node_Id;
+ Pid : Node_Id) return Node_Id
+ is
+ Decls : constant List_Id := Declarations (N);
+ Is_Procedure : constant Boolean :=
+ Ekind (Corresponding_Spec (N)) = E_Procedure;
+ Loc : constant Source_Ptr := Sloc (N);
+
+ function Ren_Comp_Id (Decls : List_Id) return Entity_Id;
+ -- Given the list of delaration Decls, return the renamed entity
+ -- of the protected component accessed by the subprogram body.
+
+ -----------------
+ -- Ren_Comp_Id --
+ -----------------
+
+ function Ren_Comp_Id (Decls : List_Id) return Entity_Id is
+ N_Decl : Node_Id;
+ Pri_Link : Node_Id;
+
+ begin
+ N_Decl := First (Decls);
+ while Present (N_Decl) loop
+
+ -- Look for a renaming declaration
+
+ if Nkind (N_Decl) = N_Object_Renaming_Declaration then
+ Pri_Link := Prival_Link (Defining_Identifier (N_Decl));
+
+ -- Compare the renamed entity and the accessed component entity
+ -- in the LF_Sub_Table.
+
+ if Present (Pri_Link) and then Pri_Link = Comp_Of (N) then
+ return Defining_Identifier (N_Decl);
+ end if;
+ end if;
+
+ Next (N_Decl);
+ end loop;
+
+ return Empty;
+ end Ren_Comp_Id;
+
+ Obj_Id : constant Entity_Id := Ren_Comp_Id (Decls);
+ At_Comp_Id : Entity_Id;
+ At_Load_Id : Entity_Id;
+ Copy_Id : Entity_Id;
+ Exit_Stmt : Node_Id;
+ Label : Node_Id := Empty;
+ Label_Id : Entity_Id;
+ New_Body : Node_Id;
+ New_Decls : List_Id;
+ New_Stmts : List_Id;
+ Obj_Typ : Entity_Id;
+ Old_Id : Entity_Id;
+ Typ_Size : Int;
+ Unsigned_Id : Entity_Id;
+
+ function Make_If (Stmt : Node_Id) return Node_Id;
+ -- Given the statement Stmt, return an if statement with Stmt at the end
+ -- of the list of statements.
+
+ procedure Process_Stmts (Stmts : List_Id);
+ -- Wrap each return and raise statements in Stmts into an if statement
+ -- generated by Make_If. Replace all references to the protected object
+ -- Obj by a reference to its copy Obj_Copy.
+
+ -------------
+ -- Make_If --
+ -------------
+
+ function Make_If (Stmt : Node_Id) return Node_Id is
+ begin
+ -- Generate (for Typ_Size = 32):
+
+ -- if System.Atomic_Primitives.Atomic_Compare_Exchange_32
+ -- (Obj'Address,
+ -- Interfaces.Unsigned_32! (Obj_Old),
+ -- Interfaces.Unsigned_32! (Obj_Copy));
+ -- then
+ -- < Stmt >
+ -- else
+ -- goto L0;
+ -- end if;
+
+ -- Check whether a label has already been created
+
+ if not Present (Label) then
+
+ -- Create a label which will point just after the last
+ -- statement of the loop statement generated in step 3.
+
+ -- Generate:
+
+ -- L0 : Label;
+
+ Label_Id :=
+ Make_Identifier (Loc, New_External_Name ('L', 0));
+
+ Set_Entity (Label_Id,
+ Make_Defining_Identifier (Loc, Chars (Label_Id)));
+ Label := Make_Label (Loc, Label_Id);
+
+ Append_To (Decls,
+ Make_Implicit_Label_Declaration (Loc,
+ Defining_Identifier => Entity (Label_Id),
+ Label_Construct => Label));
+ end if;
+
+ return
+ Make_If_Statement (Loc,
+ Condition =>
+ Make_Function_Call (Loc,
+ Name => New_Reference_To (At_Comp_Id, Loc),
+ Parameter_Associations => New_List (
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Reference_To (Obj_Id, Loc),
+ Attribute_Name => Name_Address),
+ Unchecked_Convert_To (Unsigned_Id,
+ New_Reference_To (Old_Id, Loc)),
+ Unchecked_Convert_To (Unsigned_Id,
+ New_Reference_To (Copy_Id, Loc)))),
+
+ Then_Statements => New_List (
+ Relocate_Node (Stmt)),
+
+ Else_Statements => New_List (
+ Make_Goto_Statement (Loc,
+ Name => New_Reference_To (Entity (Label_Id), Loc))));
+ end Make_If;
+
+ -------------------
+ -- Process_Stmts --
+ -------------------
+
+ procedure Process_Stmts (Stmts : List_Id) is
+ Stmt : Node_Id;
+
+ function Check_Node (N : Node_Id) return Traverse_Result;
+ -- Recognize a return and raise statement and wrap it into an if
+ -- statement. Replace all references to the protected object by
+ -- a reference to its copy. Reset all Analyzed flags in order to
+ -- reanalyze statments inside the new unprotected subprogram body.
+
+ procedure Process_Nodes is
+ new Traverse_Proc (Check_Node);
+
+ ----------------
+ -- Check_Node --
+ ----------------
+
+ function Check_Node (N : Node_Id) return Traverse_Result is
+ begin
+ -- In case of a procedure, wrap each return and raise statements
+ -- inside an if statement created by Make_If.
+
+ if Is_Procedure
+ and then Nkind_In (N, N_Simple_Return_Statement,
+ N_Extended_Return_Statement,
+ N_Raise_Statement)
+ and then
+ (Nkind (N) /= N_Simple_Return_Statement
+ or else N /= Last (Stmts))
+ then
+ Rewrite (N, Make_If (N));
+ return Skip;
+
+ -- Replace all references to the protected object by a reference
+ -- to the new copy.
+
+ elsif Nkind (N) = N_Identifier
+ and then Present (Entity (N))
+ and then Entity (N) = Obj_Id
+ then
+ Rewrite (N, Make_Identifier (Loc, Chars (Copy_Id)));
+ return Skip;
+ end if;
+
+ -- We mark the node as unanalyzed in order to reanalyze it inside
+ -- the unprotected subprogram body.
+
+ Set_Analyzed (N, False);
+
+ return OK;
+ end Check_Node;
+
+ -- Start of processing for Process_Stmts
+
+ begin
+ -- Process_Nodes for each statement in Stmts
+
+ Stmt := First (Stmts);
+ while Present (Stmt) loop
+ Process_Nodes (Stmt);
+ Next (Stmt);
+ end loop;
+ end Process_Stmts;
+
+ -- Start of processing for Build_Lock_Free_Unprotected_Subprogram_Body
+
+ begin
+ New_Stmts := New_Copy_List (Statements (Handled_Statement_Sequence (N)));
+
+ -- Do the transformation only if the subprogram accesses a protected
+ -- component.
+
+ if not Present (Obj_Id) then
+ goto Continue;
+ end if;
+
+ Copy_Id :=
+ Make_Defining_Identifier (Loc,
+ Chars => New_External_Name (Chars (Obj_Id), Suffix => "_copy"));
+
+ Obj_Typ := Etype (Obj_Id);
+ Typ_Size := UI_To_Int (Esize (Base_Type (Obj_Typ)));
+
+ Process_Stmts (New_Stmts);
+
+ -- Procedure case
+
+ if Is_Procedure then
+ case Typ_Size is
+ when 8 =>
+ At_Comp_Id := RTE (RE_Atomic_Compare_Exchange_8);
+ At_Load_Id := RTE (RE_Atomic_Load_8);
+ Unsigned_Id := RTE (RE_Uint8);
+
+ when 16 =>
+ At_Comp_Id := RTE (RE_Atomic_Compare_Exchange_16);
+ At_Load_Id := RTE (RE_Atomic_Load_16);
+ Unsigned_Id := RTE (RE_Uint16);
+
+ when 32 =>
+ At_Comp_Id := RTE (RE_Atomic_Compare_Exchange_32);
+ At_Load_Id := RTE (RE_Atomic_Load_32);
+ Unsigned_Id := RTE (RE_Uint32);
+
+ when 64 =>
+ At_Comp_Id := RTE (RE_Atomic_Compare_Exchange_64);
+ At_Load_Id := RTE (RE_Atomic_Load_64);
+ Unsigned_Id := RTE (RE_Uint64);
+ when others => null;
+ end case;
+
+ -- Generate (e.g. for Typ_Size = 32):
+
+ -- begin
+ -- loop
+ -- declare
+ -- Obj_Old : constant Obj_Typ :=
+ -- Obj_Typ!
+ -- (System.Atomic_Primitives.Atomic_Load_32
+ -- (Obj'Address));
+ -- Obj_Copy : Obj_Typ := Obj_Old;
+ -- begin
+ -- < New_Stmts >
+ -- exit when
+ -- System.Atomic_Primitives.Atomic_Compare_Exchange_32
+ -- (Obj'Address,
+ -- Interfaces.Unsigned_32! (Obj_Old),
+ -- Interfaces.Unsigned_32! (Obj_Copy));
+ -- end;
+ -- end loop;
+ -- end;
+
+ -- Step 1: Define a copy and save the old value of the protected
+ -- object. The copy replaces all the references to the object present
+ -- in the body of the procedure.
+
+ -- Generate:
+
+ -- Obj_Old : constant Obj_Typ :=
+ -- Obj_Typ!
+ -- (System.Atomic_Primitives.Atomic_Load_32
+ -- (Obj'Address));
+ -- Obj_Copy : Obj_Typ := Obj_Old;
+
+ Old_Id := Make_Defining_Identifier (Loc,
+ New_External_Name (Chars (Obj_Id), Suffix => "_old"));
+
+ New_Decls := New_List (
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Old_Id,
+ Constant_Present => True,
+ Object_Definition => New_Reference_To (Obj_Typ, Loc),
+ Expression => Unchecked_Convert_To (Obj_Typ,
+ Make_Function_Call (Loc,
+ Name => New_Reference_To (At_Load_Id, Loc),
+ Parameter_Associations => New_List (
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Reference_To (Obj_Id, Loc),
+ Attribute_Name => Name_Address))))),
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Copy_Id,
+ Object_Definition => New_Reference_To (Obj_Typ, Loc),
+ Expression => New_Reference_To (Old_Id, Loc)));
+
+ -- Step 2: Create an exit statement of the loop statement generated
+ -- in step 3.
+
+ -- Generate (for Typ_Size = 32):
+
+ -- exit when System.Atomic_Primitives.Atomic_Compare_Exchange_32
+ -- (Obj'Address,
+ -- Interfaces.Unsigned_32! (Obj_Old),
+ -- Interfaces.Unsigned_32! (Obj_Copy));
+
+ Exit_Stmt :=
+ Make_Exit_Statement (Loc,
+ Condition =>
+ Make_Function_Call (Loc,
+ Name => New_Reference_To (At_Comp_Id, Loc),
+ Parameter_Associations => New_List (
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Reference_To (Obj_Id, Loc),
+ Attribute_Name => Name_Address),
+ Unchecked_Convert_To (Unsigned_Id,
+ New_Reference_To (Old_Id, Loc)),
+ Unchecked_Convert_To (Unsigned_Id,
+ New_Reference_To (Copy_Id, Loc)))));
+
+ -- Check the last statement is a return statement
+
+ if Nkind (Last (New_Stmts)) = N_Simple_Return_Statement then
+ Rewrite (Last (New_Stmts), Exit_Stmt);
+ else
+ Append_To (New_Stmts, Exit_Stmt);
+ end if;
+
+ -- Step 3: Create the loop statement which encloses a block
+ -- declaration that contains all the statements of the original
+ -- procedure body.
+
+ -- Generate:
+
+ -- loop
+ -- declare
+ -- < New_Decls >
+ -- begin
+ -- < New_Stmts >
+ -- end;
+ -- end loop;
+
+ New_Stmts := New_List (
+ Make_Loop_Statement (Loc,
+ Statements => New_List (
+ Make_Block_Statement (Loc,
+ Declarations => New_Decls,
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => New_Stmts))),
+ End_Label => Empty));
+
+ -- Append the label to the statements of the loop when needed
+
+ if Present (Label) then
+ Append_To (Statements (First (New_Stmts)), Label);
+ end if;
+
+ -- Function case
+
+ else
+ case Typ_Size is
+ when 8 =>
+ At_Load_Id := RTE (RE_Atomic_Load_8);
+ when 16 =>
+ At_Load_Id := RTE (RE_Atomic_Load_16);
+ when 32 =>
+ At_Load_Id := RTE (RE_Atomic_Load_32);
+ when 64 =>
+ At_Load_Id := RTE (RE_Atomic_Load_64);
+ when others => null;
+ end case;
+
+ -- Define a copy of the protected object which replaces all the
+ -- references to the object present in the body of the function.
+
+ -- Generate:
+
+ -- Obj_Copy : constant Obj_Typ :=
+ -- Obj_Typ!
+ -- (System.Atomic_Primitives.Atomic_Load_32
+ -- (Obj'Address));
+
+ Append_To (Decls,
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Copy_Id,
+ Constant_Present => True,
+ Object_Definition => New_Reference_To (Obj_Typ, Loc),
+ Expression => Unchecked_Convert_To (Obj_Typ,
+ Make_Function_Call (Loc,
+ Name => New_Reference_To (At_Load_Id, Loc),
+ Parameter_Associations => New_List (
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Reference_To (Obj_Id, Loc),
+ Attribute_Name => Name_Address))))));
+ end if;
+
+ << Continue >>
+
+ -- Add renamings for the Protection object, discriminals, privals and
+ -- the entry index constant for use by debugger.
+
+ Debug_Private_Data_Declarations (Decls);
+
+ -- Make an unprotected version of the subprogram for use within the same
+ -- object, with new name and extra parameter representing the object.
+
+ New_Body :=
+ Make_Subprogram_Body (Loc,
+ Specification =>
+ Build_Protected_Sub_Specification (N, Pid, Unprotected_Mode),
+ Declarations => Decls,
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => New_Stmts));
+ return New_Body;
+ end Build_Lock_Free_Unprotected_Subprogram_Body;
+
-------------------------
-- Build_Master_Entity --
-------------------------
@@ -3442,102 +4276,6 @@ package body Exp_Ch9 is
Exc_Safe : Boolean;
Lock_Kind : RE_Id;
- function Is_Exception_Safe (Subprogram : Node_Id) return Boolean;
- -- Tell whether a given subprogram cannot raise an exception
-
- -----------------------
- -- Is_Exception_Safe --
- -----------------------
-
- function Is_Exception_Safe (Subprogram : Node_Id) return Boolean is
-
- function Has_Side_Effect (N : Node_Id) return Boolean;
- -- Return True whenever encountering a subprogram call or raise
- -- statement of any kind in the sequence of statements
-
- ---------------------
- -- Has_Side_Effect --
- ---------------------
-
- -- What is this doing buried two levels down in exp_ch9. It seems
- -- like a generally useful function, and indeed there may be code
- -- duplication going on here ???
-
- function Has_Side_Effect (N : Node_Id) return Boolean is
- Stmt : Node_Id;
- Expr : Node_Id;
-
- function Is_Call_Or_Raise (N : Node_Id) return Boolean;
- -- Indicate whether N is a subprogram call or a raise statement
-
- ----------------------
- -- Is_Call_Or_Raise --
- ----------------------
-
- function Is_Call_Or_Raise (N : Node_Id) return Boolean is
- begin
- return Nkind_In (N, N_Procedure_Call_Statement,
- N_Function_Call,
- N_Raise_Statement,
- N_Raise_Constraint_Error,
- N_Raise_Program_Error,
- N_Raise_Storage_Error);
- end Is_Call_Or_Raise;
-
- -- Start of processing for Has_Side_Effect
-
- begin
- Stmt := N;
- while Present (Stmt) loop
- if Is_Call_Or_Raise (Stmt) then
- return True;
- end if;
-
- -- An object declaration can also contain a function call
- -- or a raise statement
-
- if Nkind (Stmt) = N_Object_Declaration then
- Expr := Expression (Stmt);
-
- if Present (Expr) and then Is_Call_Or_Raise (Expr) then
- return True;
- end if;
- end if;
-
- Next (Stmt);
- end loop;
-
- return False;
- end Has_Side_Effect;
-
- -- Start of processing for Is_Exception_Safe
-
- begin
- -- If the checks handled by the back end are not disabled, we cannot
- -- ensure that no exception will be raised.
-
- if not Access_Checks_Suppressed (Empty)
- or else not Discriminant_Checks_Suppressed (Empty)
- or else not Range_Checks_Suppressed (Empty)
- or else not Index_Checks_Suppressed (Empty)
- or else Opt.Stack_Checking_Enabled
- then
- return False;
- end if;
-
- if Has_Side_Effect (First (Declarations (Subprogram)))
- or else
- Has_Side_Effect (
- First (Statements (Handled_Statement_Sequence (Subprogram))))
- then
- return False;
- else
- return True;
- end if;
- end Is_Exception_Safe;
-
- -- Start of processing for Build_Protected_Subprogram_Body
-
begin
Op_Spec := Specification (N);
Exc_Safe := Is_Exception_Safe (N);
@@ -4698,6 +5436,21 @@ package body Exp_Ch9 is
end loop;
end Collect_Entry_Families;
+ -------------
+ -- Comp_Of --
+ -------------
+
+ function Comp_Of (Sub_Body : Node_Id) return Entity_Id is
+ begin
+ for Sub_Id in 1 .. LF_Sub_Table.Last loop
+ if Sub_Body = LF_Sub_Table.Table (Sub_Id).Sub_Body then
+ return LF_Sub_Table.Table (Sub_Id).Comp_Id;
+ end if;
+ end loop;
+
+ return Empty;
+ end Comp_Of;
+
-----------------------
-- Concurrent_Object --
-----------------------
@@ -7715,6 +8468,9 @@ package body Exp_Ch9 is
Loc : constant Source_Ptr := Sloc (N);
Pid : constant Entity_Id := Corresponding_Spec (N);
+ Lock_Free_On : constant Boolean := Allow_Lock_Free_Implementation (N);
+ -- This flag indicates whether the lock free implementation is active
+
Current_Node : Node_Id;
Disp_Op_Body : Node_Id;
New_Op_Body : Node_Id;
@@ -7843,8 +8599,14 @@ package body Exp_Ch9 is
if not Is_Eliminated (Defining_Entity (Op_Body))
and then not Is_Eliminated (Corresponding_Spec (Op_Body))
then
- New_Op_Body :=
- Build_Unprotected_Subprogram_Body (Op_Body, Pid);
+ if Lock_Free_On then
+ New_Op_Body :=
+ Build_Lock_Free_Unprotected_Subprogram_Body
+ (Op_Body, Pid);
+ else
+ New_Op_Body :=
+ Build_Unprotected_Subprogram_Body (Op_Body, Pid);
+ end if;
Insert_After (Current_Node, New_Op_Body);
Current_Node := New_Op_Body;
@@ -7854,6 +8616,7 @@ package body Exp_Ch9 is
-- appear that this is needed only if this is a visible
-- operation of the type, or if it is an interrupt handler,
-- and this was the strategy used previously in GNAT.
+
-- However, the operation may be exported through a 'Access
-- to an external caller. This is the common idiom in code
-- that uses the Ada 2005 Timing_Events package. As a result
@@ -7863,9 +8626,15 @@ package body Exp_Ch9 is
-- declaration in the protected body itself.
if Present (Corresponding_Spec (Op_Body)) then
- New_Op_Body :=
- Build_Protected_Subprogram_Body (
- Op_Body, Pid, Specification (New_Op_Body));
+ if Lock_Free_On then
+ New_Op_Body :=
+ Build_Lock_Free_Protected_Subprogram_Body
+ (Op_Body, Pid, Specification (New_Op_Body));
+ else
+ New_Op_Body :=
+ Build_Protected_Subprogram_Body
+ (Op_Body, Pid, Specification (New_Op_Body));
+ end if;
Insert_After (Current_Node, New_Op_Body);
Analyze (New_Op_Body);
@@ -12688,6 +13457,97 @@ package body Exp_Ch9 is
end if;
end Install_Private_Data_Declarations;
+ -----------------------
+ -- Is_Exception_Safe --
+ -----------------------
+
+ function Is_Exception_Safe (Subprogram : Node_Id) return Boolean is
+
+ function Has_Side_Effect (N : Node_Id) return Boolean;
+ -- Return True whenever encountering a subprogram call or raise
+ -- statement of any kind in the sequence of statements
+
+ ---------------------
+ -- Has_Side_Effect --
+ ---------------------
+
+ -- What is this doing buried two levels down in exp_ch9. It seems like a
+ -- generally useful function, and indeed there may be code duplication
+ -- going on here ???
+
+ function Has_Side_Effect (N : Node_Id) return Boolean is
+ Stmt : Node_Id;
+ Expr : Node_Id;
+
+ function Is_Call_Or_Raise (N : Node_Id) return Boolean;
+ -- Indicate whether N is a subprogram call or a raise statement
+
+ ----------------------
+ -- Is_Call_Or_Raise --
+ ----------------------
+
+ function Is_Call_Or_Raise (N : Node_Id) return Boolean is
+ begin
+ return Nkind_In (N, N_Procedure_Call_Statement,
+ N_Function_Call,
+ N_Raise_Statement,
+ N_Raise_Constraint_Error,
+ N_Raise_Program_Error,
+ N_Raise_Storage_Error);
+ end Is_Call_Or_Raise;
+
+ -- Start of processing for Has_Side_Effect
+
+ begin
+ Stmt := N;
+ while Present (Stmt) loop
+ if Is_Call_Or_Raise (Stmt) then
+ return True;
+ end if;
+
+ -- An object declaration can also contain a function call or a
+ -- raise statement.
+
+ if Nkind (Stmt) = N_Object_Declaration then
+ Expr := Expression (Stmt);
+
+ if Present (Expr) and then Is_Call_Or_Raise (Expr) then
+ return True;
+ end if;
+ end if;
+
+ Next (Stmt);
+ end loop;
+
+ return False;
+ end Has_Side_Effect;
+
+ -- Start of processing for Is_Exception_Safe
+
+ begin
+ -- If the checks handled by the back end are not disabled, we cannot
+ -- ensure that no exception will be raised.
+
+ if not Access_Checks_Suppressed (Empty)
+ or else not Discriminant_Checks_Suppressed (Empty)
+ or else not Range_Checks_Suppressed (Empty)
+ or else not Index_Checks_Suppressed (Empty)
+ or else Opt.Stack_Checking_Enabled
+ then
+ return False;
+ end if;
+
+ if Has_Side_Effect (First (Declarations (Subprogram)))
+ or else
+ Has_Side_Effect
+ (First (Statements (Handled_Statement_Sequence (Subprogram))))
+ then
+ return False;
+ else
+ return True;
+ end if;
+ end Is_Exception_Safe;
+
---------------------------------
-- Is_Potentially_Large_Family --
---------------------------------
@@ -12702,11 +13562,12 @@ package body Exp_Ch9 is
return Scope (Base_Index) = Standard_Standard
and then Base_Index = Base_Type (Standard_Integer)
and then Has_Discriminants (Conctyp)
- and then Present
- (Discriminant_Default_Value (First_Discriminant (Conctyp)))
+ and then
+ Present (Discriminant_Default_Value (First_Discriminant (Conctyp)))
and then
(Denotes_Discriminant (Lo, True)
- or else Denotes_Discriminant (Hi, True));
+ or else
+ Denotes_Discriminant (Hi, True));
end Is_Potentially_Large_Family;
-------------------------------------
diff --git a/gcc/ada/exp_pakd.adb b/gcc/ada/exp_pakd.adb
index 8a95ec5c876..756a3d19be3 100644
--- a/gcc/ada/exp_pakd.adb
+++ b/gcc/ada/exp_pakd.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -509,7 +509,7 @@ package body Exp_Pakd is
Shift : out Node_Id);
-- This procedure performs common processing on the N_Indexed_Component
-- parameter given as N, whose prefix is a reference to a packed array.
- -- This is used for the get and set when the component size is 1,2,4
+ -- This is used for the get and set when the component size is 1, 2, 4,
-- or for other component sizes when the packed array type is a modular
-- type (i.e. the cases that are handled with inline code).
--
@@ -1472,10 +1472,10 @@ package body Exp_Pakd is
end if;
end if;
- -- Now create copies removing side effects. Note that in some
- -- complex cases, this may cause the fact that we have already
- -- set a packed array type on Obj to get lost. So we save the
- -- type of Obj, and make sure it is reset properly.
+ -- Now create copies removing side effects. Note that in some complex
+ -- cases, this may cause the fact that we have already set a packed
+ -- array type on Obj to get lost. So we save the type of Obj, and
+ -- make sure it is reset properly.
declare
T : constant Entity_Id := Etype (Obj);
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index ae7f2b95467..ae5470f659c 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -3940,27 +3940,29 @@ package body Exp_Util is
return True;
end Is_All_Null_Statements;
- ---------------------------------------------
- -- Is_Displacement_Of_Ctrl_Function_Result --
- ---------------------------------------------
+ --------------------------------------------------
+ -- Is_Displacement_Of_Object_Or_Function_Result --
+ --------------------------------------------------
- function Is_Displacement_Of_Ctrl_Function_Result
+ function Is_Displacement_Of_Object_Or_Function_Result
(Obj_Id : Entity_Id) return Boolean
is
- function Initialized_By_Ctrl_Function (N : Node_Id) return Boolean;
- -- Determine whether object declaration N is initialized by a controlled
- -- function call.
+ function Is_Controlled_Function_Call (N : Node_Id) return Boolean;
+ -- Determine if particular node denotes a controlled function call
function Is_Displace_Call (N : Node_Id) return Boolean;
-- Determine whether a particular node is a call to Ada.Tags.Displace.
-- The call might be nested within other actions such as conversions.
- ----------------------------------
- -- Initialized_By_Ctrl_Function --
- ----------------------------------
+ function Is_Source_Object (N : Node_Id) return Boolean;
+ -- Determine whether a particular node denotes a source object
+
+ ---------------------------------
+ -- Is_Controlled_Function_Call --
+ ---------------------------------
- function Initialized_By_Ctrl_Function (N : Node_Id) return Boolean is
- Expr : Node_Id := Original_Node (Expression (N));
+ function Is_Controlled_Function_Call (N : Node_Id) return Boolean is
+ Expr : Node_Id := Original_Node (N);
begin
if Nkind (Expr) = N_Function_Call then
@@ -3977,7 +3979,7 @@ package body Exp_Util is
Nkind_In (Expr, N_Expanded_Name, N_Identifier)
and then Ekind (Entity (Expr)) = E_Function
and then Needs_Finalization (Etype (Entity (Expr)));
- end Initialized_By_Ctrl_Function;
+ end Is_Controlled_Function_Call;
----------------------
-- Is_Displace_Call --
@@ -4004,39 +4006,66 @@ package body Exp_Util is
end loop;
return
- Nkind (Call) = N_Function_Call
+ Present (Call)
+ and then Nkind (Call) = N_Function_Call
and then Is_RTE (Entity (Name (Call)), RE_Displace);
end Is_Displace_Call;
+ ----------------------
+ -- Is_Source_Object --
+ ----------------------
+
+ function Is_Source_Object (N : Node_Id) return Boolean is
+ begin
+ return
+ Present (N)
+ and then Nkind (N) in N_Has_Entity
+ and then Is_Object (Entity (N))
+ and then Comes_From_Source (N);
+ end Is_Source_Object;
+
-- Local variables
Decl : constant Node_Id := Parent (Obj_Id);
Obj_Typ : constant Entity_Id := Base_Type (Etype (Obj_Id));
Orig_Decl : constant Node_Id := Original_Node (Decl);
- -- Start of processing for Is_Displacement_Of_Ctrl_Function_Result
+ -- Start of processing for Is_Displacement_Of_Object_Or_Function_Result
begin
- -- Detect the following case:
+ -- Case 1:
+
+ -- Obj : CW_Type := Function_Call (...);
+
+ -- rewritten into:
+
+ -- Tmp : ... := Function_Call (...)'reference;
+ -- Obj : CW_Type renames (... Ada.Tags.Displace (Tmp));
+
+ -- where the return type of the function and the class-wide type require
+ -- dispatch table pointer displacement.
+
+ -- Case 2:
- -- Obj : Class_Wide_Type := Function_Call (...);
+ -- Obj : CW_Type := Src_Obj;
- -- which is rewritten into:
+ -- rewritten into:
- -- Temp : ... := Function_Call (...)'reference;
- -- Obj : Class_Wide_Type renames (... Ada.Tags.Displace (Temp));
+ -- Obj : CW_Type renames (... Ada.Tags.Displace (Src_Obj));
- -- when the return type of the function and the class-wide type require
+ -- where the type of the source object and the class-wide type require
-- dispatch table pointer displacement.
return
Nkind (Decl) = N_Object_Renaming_Declaration
and then Nkind (Orig_Decl) = N_Object_Declaration
and then Comes_From_Source (Orig_Decl)
- and then Initialized_By_Ctrl_Function (Orig_Decl)
and then Is_Class_Wide_Type (Obj_Typ)
- and then Is_Displace_Call (Renamed_Object (Obj_Id));
- end Is_Displacement_Of_Ctrl_Function_Result;
+ and then Is_Displace_Call (Renamed_Object (Obj_Id))
+ and then
+ (Is_Controlled_Function_Call (Expression (Orig_Decl))
+ or else Is_Source_Object (Expression (Orig_Decl)));
+ end Is_Displacement_Of_Object_Or_Function_Result;
------------------------------
-- Is_Finalizable_Transient --
@@ -4475,74 +4504,6 @@ package body Exp_Util is
and then Is_Library_Level_Entity (Typ);
end Is_Library_Level_Tagged_Type;
- ----------------------------------
- -- Is_Null_Access_BIP_Func_Call --
- ----------------------------------
-
- function Is_Null_Access_BIP_Func_Call (Expr : Node_Id) return Boolean is
- Call : Node_Id := Expr;
-
- begin
- -- Build-in-place calls usually appear in 'reference format
-
- if Nkind (Call) = N_Reference then
- Call := Prefix (Call);
- end if;
-
- if Nkind_In (Call, N_Qualified_Expression,
- N_Unchecked_Type_Conversion)
- then
- Call := Expression (Call);
- end if;
-
- if Is_Build_In_Place_Function_Call (Call) then
- declare
- Access_Nam : Name_Id := No_Name;
- Actual : Node_Id;
- Param : Node_Id;
- Formal : Node_Id;
-
- begin
- -- Examine all parameter associations of the function call
-
- Param := First (Parameter_Associations (Call));
- while Present (Param) loop
- if Nkind (Param) = N_Parameter_Association
- and then Nkind (Selector_Name (Param)) = N_Identifier
- then
- Formal := Selector_Name (Param);
- Actual := Explicit_Actual_Parameter (Param);
-
- -- Construct the name of formal BIPaccess. It is much easier
- -- to extract the name of the function using an arbitrary
- -- formal's scope rather than the Name field of Call.
-
- if Access_Nam = No_Name
- and then Present (Entity (Formal))
- then
- Access_Nam :=
- New_External_Name
- (Chars (Scope (Entity (Formal))),
- BIP_Formal_Suffix (BIP_Object_Access));
- end if;
-
- -- A match for BIPaccess => null has been found
-
- if Chars (Formal) = Access_Nam
- and then Nkind (Actual) = N_Null
- then
- return True;
- end if;
- end if;
-
- Next (Param);
- end loop;
- end;
- end if;
-
- return False;
- end Is_Null_Access_BIP_Func_Call;
-
--------------------------
-- Is_Non_BIP_Func_Call --
--------------------------
@@ -4949,6 +4910,77 @@ package body Exp_Util is
end if;
end Is_Renamed_Object;
+ --------------------------------------
+ -- Is_Secondary_Stack_BIP_Func_Call --
+ --------------------------------------
+
+ function Is_Secondary_Stack_BIP_Func_Call (Expr : Node_Id) return Boolean is
+ Call : Node_Id := Expr;
+
+ begin
+ -- Build-in-place calls usually appear in 'reference format. Note that
+ -- the accessibility check machinery may add an extra 'reference due to
+ -- side effect removal.
+
+ while Nkind (Call) = N_Reference loop
+ Call := Prefix (Call);
+ end loop;
+
+ if Nkind_In (Call, N_Qualified_Expression,
+ N_Unchecked_Type_Conversion)
+ then
+ Call := Expression (Call);
+ end if;
+
+ if Is_Build_In_Place_Function_Call (Call) then
+ declare
+ Access_Nam : Name_Id := No_Name;
+ Actual : Node_Id;
+ Param : Node_Id;
+ Formal : Node_Id;
+
+ begin
+ -- Examine all parameter associations of the function call
+
+ Param := First (Parameter_Associations (Call));
+ while Present (Param) loop
+ if Nkind (Param) = N_Parameter_Association
+ and then Nkind (Selector_Name (Param)) = N_Identifier
+ then
+ Formal := Selector_Name (Param);
+ Actual := Explicit_Actual_Parameter (Param);
+
+ -- Construct the name of formal BIPalloc. It is much easier
+ -- to extract the name of the function using an arbitrary
+ -- formal's scope rather than the Name field of Call.
+
+ if Access_Nam = No_Name
+ and then Present (Entity (Formal))
+ then
+ Access_Nam :=
+ New_External_Name
+ (Chars (Scope (Entity (Formal))),
+ BIP_Formal_Suffix (BIP_Alloc_Form));
+ end if;
+
+ -- A match for BIPalloc => 2 has been found
+
+ if Chars (Formal) = Access_Nam
+ and then Nkind (Actual) = N_Integer_Literal
+ and then Intval (Actual) = Uint_2
+ then
+ return True;
+ end if;
+ end if;
+
+ Next (Param);
+ end loop;
+ end;
+ end if;
+
+ return False;
+ end Is_Secondary_Stack_BIP_Func_Call;
+
-------------------------------------
-- Is_Tag_To_Class_Wide_Conversion --
-------------------------------------
@@ -7123,18 +7155,17 @@ package body Exp_Util is
-- Obj : Access_Typ := Non_BIP_Function_Call'reference;
--
-- Obj : Access_Typ :=
- -- BIP_Function_Call
- -- (..., BIPaccess => null, ...)'reference;
+ -- BIP_Function_Call (BIPalloc => 2, ...)'reference;
elsif Is_Access_Type (Obj_Typ)
and then Needs_Finalization
(Available_View (Designated_Type (Obj_Typ)))
and then Present (Expr)
and then
- (Is_Null_Access_BIP_Func_Call (Expr)
- or else
- (Is_Non_BIP_Func_Call (Expr)
- and then not Is_Related_To_Func_Return (Obj_Id)))
+ (Is_Secondary_Stack_BIP_Func_Call (Expr)
+ or else
+ (Is_Non_BIP_Func_Call (Expr)
+ and then not Is_Related_To_Func_Return (Obj_Id)))
then
return True;
@@ -7187,17 +7218,18 @@ package body Exp_Util is
then
return True;
- -- Detect a case where a source object has been initialized by a
- -- controlled function call which was later rewritten as a class-
- -- wide conversion of Ada.Tags.Displace.
+ -- Detect a case where a source object has been initialized by
+ -- a controlled function call or another object which was later
+ -- rewritten as a class-wide conversion of Ada.Tags.Displace.
- -- Obj : Class_Wide_Type := Function_Call (...);
+ -- Obj1 : CW_Type := Src_Obj;
+ -- Obj2 : CW_Type := Function_Call (...);
- -- Temp : ... := Function_Call (...)'reference;
- -- Obj : Class_Wide_Type renames
- -- (... Ada.Tags.Displace (Temp));
+ -- Obj1 : CW_Type renames (... Ada.Tags.Displace (Src_Obj));
+ -- Tmp : ... := Function_Call (...)'reference;
+ -- Obj2 : CW_Type renames (... Ada.Tags.Displace (Tmp));
- elsif Is_Displacement_Of_Ctrl_Function_Result (Obj_Id) then
+ elsif Is_Displacement_Of_Object_Or_Function_Result (Obj_Id) then
return True;
end if;
diff --git a/gcc/ada/exp_util.ads b/gcc/ada/exp_util.ads
index 97e9b5c9a56..9f3ae2a2554 100644
--- a/gcc/ada/exp_util.ads
+++ b/gcc/ada/exp_util.ads
@@ -521,11 +521,12 @@ package Exp_Util is
-- False otherwise. True for an empty list. It is an error to call this
-- routine with No_List as the argument.
- function Is_Displacement_Of_Ctrl_Function_Result
+ function Is_Displacement_Of_Object_Or_Function_Result
(Obj_Id : Entity_Id) return Boolean;
- -- Determine whether Obj_Id is a source object that has been initialized by
- -- a controlled function call later rewritten as a class-wide conversion of
- -- Ada.Tags.Displace.
+ -- Determine whether Obj_Id is a source entity that has been initialized by
+ -- either a controlled function call or the assignment of another source
+ -- object. In both cases the initialization expression is rewritten as a
+ -- class-wide conversion of Ada.Tags.Displace.
function Is_Finalizable_Transient
(Decl : Node_Id;
@@ -548,13 +549,20 @@ package Exp_Util is
-- Return True if Typ is a library level tagged type. Currently we use
-- this information to build statically allocated dispatch tables.
- function Is_Null_Access_BIP_Func_Call (Expr : Node_Id) return Boolean;
- -- Determine whether node Expr denotes a build-in-place function call with
- -- a value of "null" for extra formal BIPaccess.
-
function Is_Non_BIP_Func_Call (Expr : Node_Id) return Boolean;
-- Determine whether node Expr denotes a non build-in-place function call
+ function Is_Possibly_Unaligned_Object (N : Node_Id) return Boolean;
+ -- Node N is an object reference. This function returns True if it is
+ -- possible that the object may not be aligned according to the normal
+ -- default alignment requirement for its type (e.g. if it appears in a
+ -- packed record, or as part of a component that has a component clause.)
+
+ function Is_Possibly_Unaligned_Slice (N : Node_Id) return Boolean;
+ -- Determine whether the node P is a slice of an array where the slice
+ -- result may cause alignment problems because it has an alignment that
+ -- is not compatible with the type. Return True if so.
+
function Is_Ref_To_Bit_Packed_Array (N : Node_Id) return Boolean;
-- Determine whether the node P is a reference to a bit packed array, i.e.
-- whether the designated object is a component of a bit packed array, or a
@@ -571,17 +579,6 @@ package Exp_Util is
-- Determine whether object Id is related to an expanded return statement.
-- The case concerned is "return Id.all;".
- function Is_Possibly_Unaligned_Slice (N : Node_Id) return Boolean;
- -- Determine whether the node P is a slice of an array where the slice
- -- result may cause alignment problems because it has an alignment that
- -- is not compatible with the type. Return True if so.
-
- function Is_Possibly_Unaligned_Object (N : Node_Id) return Boolean;
- -- Node N is an object reference. This function returns True if it is
- -- possible that the object may not be aligned according to the normal
- -- default alignment requirement for its type (e.g. if it appears in a
- -- packed record, or as part of a component that has a component clause.)
-
function Is_Renamed_Object (N : Node_Id) return Boolean;
-- Returns True if the node N is a renamed object. An expression is
-- considered to be a renamed object if either it is the Name of an object
@@ -593,6 +590,10 @@ package Exp_Util is
-- We consider that a (1 .. 2) is a renamed object since it is the prefix
-- of the name in the renaming declaration.
+ function Is_Secondary_Stack_BIP_Func_Call (Expr : Node_Id) return Boolean;
+ -- Determine whether Expr denotes a build-in-place function which returns
+ -- its result on the secondary stack.
+
function Is_Tag_To_Class_Wide_Conversion
(Obj_Id : Entity_Id) return Boolean;
-- Determine whether object Obj_Id is the result of a tag-to-class-wide
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index fc7600070f7..3eae40e036b 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -2161,8 +2161,16 @@ package body Freeze is
-- Here is where we do the processing for reversed bit order
- else
+ elsif not Reverse_Storage_Order (Rec) then
Adjust_Record_For_Reverse_Bit_Order (Rec);
+
+ -- Case where we have both a reverse Bit_Order and a corresponding
+ -- Scalar_Storage_Order: leave record untouched, the back-end
+ -- will take care of required layout conversions.
+
+ else
+ null;
+
end if;
end if;
diff --git a/gcc/ada/g-expect.adb b/gcc/ada/g-expect.adb
index c6e18efa5b7..94f69642af4 100644
--- a/gcc/ada/g-expect.adb
+++ b/gcc/ada/g-expect.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2000-2011, AdaCore --
+-- Copyright (C) 2000-2012, AdaCore --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -33,7 +33,7 @@ with System; use System;
with System.OS_Constants; use System.OS_Constants;
with Ada.Calendar; use Ada.Calendar;
-with GNAT.IO;
+with GNAT.IO; use GNAT.IO;
with GNAT.OS_Lib; use GNAT.OS_Lib;
with GNAT.Regpat; use GNAT.Regpat;
@@ -678,6 +678,7 @@ package body GNAT.Expect is
-- ??? Note that ddd tries again up to three times
-- in that case. See LiterateA.C:174
+ Close (Descriptors (D).Input_Fd);
Descriptors (D).Input_Fd := Invalid_FD;
Result := Expect_Process_Died;
return;
@@ -893,7 +894,8 @@ package body GNAT.Expect is
begin
Non_Blocking_Spawn
- (Process, Command, Arguments, Err_To_Out => Err_To_Out);
+ (Process, Command, Arguments, Err_To_Out => Err_To_Out,
+ Buffer_Size => 0);
if Input'Length > 0 then
Send (Process, Input);
@@ -1055,17 +1057,18 @@ package body GNAT.Expect is
Command_With_Path : String_Access;
begin
- -- Create the rest of the pipes
-
- Set_Up_Communications
- (Descriptor, Err_To_Out, Pipe1'Access, Pipe2'Access, Pipe3'Access);
-
Command_With_Path := Locate_Exec_On_Path (Command);
if Command_With_Path = null then
raise Invalid_Process;
end if;
+ -- Create the rest of the pipes once we know we will be able to
+ -- execute the process.
+
+ Set_Up_Communications
+ (Descriptor, Err_To_Out, Pipe1'Access, Pipe2'Access, Pipe3'Access);
+
-- Fork a new process
Descriptor.Pid := Fork;
@@ -1365,6 +1368,8 @@ package body GNAT.Expect is
end if;
if Create_Pipe (Pipe2) /= 0 then
+ Close (Pipe1.Input);
+ Close (Pipe1.Output);
return;
end if;
@@ -1389,7 +1394,7 @@ package body GNAT.Expect is
-- Create a separate pipe for standard error
if Create_Pipe (Pipe3) /= 0 then
- return;
+ Pipe3.all := Pipe2.all;
end if;
end if;
diff --git a/gcc/ada/g-sse.ads b/gcc/ada/g-sse.ads
index 706516b9830..60d3577ad41 100644
--- a/gcc/ada/g-sse.ads
+++ b/gcc/ada/g-sse.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2009, Free Software Foundation, Inc. --
+-- Copyright (C) 2009-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -40,6 +40,8 @@
-- GNU/Linux x86 and x86_64
-- Windows XP/Vista x86 and x86_64
+-- Solaris x86
+-- Darwin x86_64
-- This unit exposes vector _component_ types together with general comments
-- on the binding contents.
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index 9991405e3cc..5c4acda5388 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -1083,6 +1083,8 @@ ifeq ($(strip $(filter-out %86 %x86_64 solaris2%,$(arch) $(osys))),)
TOOLS_TARGET_PAIRS=mlib-tgt-specific.adb<mlib-tgt-specific-solaris.adb
+ EXTRA_GNATRTL_NONTASKING_OBJS=g-sse.o g-ssvety.o
+
EH_MECHANISM=-gcc
THREADSLIB = -lposix4 -lthread
MISCLIB = -lposix4 -lnsl -lsocket
@@ -1175,6 +1177,8 @@ ifeq ($(strip $(filter-out %86 kfreebsd%,$(arch) $(osys))),)
mlib-tgt-specific.adb<mlib-tgt-specific-linux.adb \
indepsw.adb<indepsw-gnu.adb
+ EXTRA_GNATRTL_NONTASKING_OBJS=g-sse.o g-ssvety.o
+
EH_MECHANISM=-gcc
THREADSLIB = -lpthread
GNATLIB_SHARED = gnatlib-shared-dual
@@ -1231,6 +1235,8 @@ ifeq ($(strip $(filter-out %86 freebsd%,$(arch) $(osys))),)
mlib-tgt-specific.adb<mlib-tgt-specific-linux.adb
GNATLIB_SHARED = gnatlib-shared-dual
+ EXTRA_GNATRTL_NONTASKING_OBJS=g-sse.o g-ssvety.o
+
EH_MECHANISM=-gcc
THREADSLIB= -lpthread
GMEM_LIB = gmemlib
@@ -1259,6 +1265,8 @@ ifeq ($(strip $(filter-out %86_64 freebsd%,$(arch) $(osys))),)
mlib-tgt-specific.adb<mlib-tgt-specific-linux.adb
GNATLIB_SHARED = gnatlib-shared-dual
+ EXTRA_GNATRTL_NONTASKING_OBJS=g-sse.o g-ssvety.o
+
EH_MECHANISM=-gcc
THREADSLIB= -lpthread
GMEM_LIB = gmemlib
@@ -2160,6 +2168,8 @@ ifeq ($(strip $(filter-out darwin%,$(osys))),)
$(X86_TARGET_PAIRS) \
system.ads<system-darwin-x86.ads
endif
+
+ EXTRA_GNATRTL_NONTASKING_OBJS=g-sse.o g-ssvety.o
endif
ifeq ($(strip $(filter-out %x86_64,$(arch))),)
@@ -2178,6 +2188,8 @@ ifeq ($(strip $(filter-out darwin%,$(osys))),)
$(X86_64_TARGET_PAIRS) \
system.ads<system-darwin-x86_64.ads
endif
+
+ EXTRA_GNATRTL_NONTASKING_OBJS=g-sse.o g-ssvety.o
endif
ifeq ($(strip $(filter-out powerpc%,$(arch))),)
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index b925f422a21..dac9942237f 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -81,9 +81,6 @@
#define FOREIGN_FORCE_REALIGN_STACK 0
#endif
-/* The (internal) name of the System.Secondary_Stack.SS_Mark function. */
-#define SS_MARK_NAME "system__secondary_stack__ss_mark"
-
struct incomplete
{
struct incomplete *next;
@@ -4409,21 +4406,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
get_identifier ("force_align_arg_pointer"), NULL_TREE,
gnat_entity);
- /* ??? Declare System.Secondary_Stack.SS_Mark as leaf, in order to
- avoid creating abnormal edges in SJLJ mode, which can break the
- dominance relationship if there is a dynamic stack allocation.
- We cannot do this in System.Secondary_Stack directly since it's
- a compiler unit and this would introduce bootstrap path issues. */
- if (IDENTIFIER_LENGTH (gnu_entity_name) == strlen (SS_MARK_NAME)
- && IDENTIFIER_POINTER (gnu_entity_name)[0] == SS_MARK_NAME[0]
- && IDENTIFIER_POINTER (gnu_entity_name)[1] == SS_MARK_NAME[1]
- && IDENTIFIER_POINTER (gnu_entity_name)[2] == SS_MARK_NAME[2]
- && gnu_entity_name == get_identifier (SS_MARK_NAME))
- prepend_one_attribute_to
- (&attr_list, ATTR_MACHINE_ATTRIBUTE,
- get_identifier ("leaf"), NULL_TREE,
- gnat_entity);
-
/* The lists have been built in reverse. */
gnu_param_list = nreverse (gnu_param_list);
if (has_stub)
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index 5c313ac76f0..e8e4d6e978c 100644
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -94,10 +94,12 @@ Texts. A copy of the license is included in the section entitled
@ifset unw
@set PLATFORM
+@set TITLESUFFIX
@end ifset
@ifset vms
@set PLATFORM OpenVMS
+@set TITLESUFFIX for OpenVMS
@end ifset
@c @ovar(ARG)
@@ -115,7 +117,7 @@ Texts. A copy of the license is included in the section entitled
@c of the @ovar macro have been expanded inline.
-@settitle @value{EDITION} User's Guide @value{PLATFORM}
+@settitle @value{EDITION} User's Guide @value{TITLESUFFIX}
@dircategory GNU Ada tools
@direntry
* @value{EDITION} User's Guide: (gnat_ugn). @value{PLATFORM}
@@ -484,6 +486,7 @@ Creating Unit Tests Using gnattest
* Tagged Types Substitutability Testing::
* Testing with Contracts::
* Additional Tests::
+* Support for other platforms/run-times::
* Current Limitations::
Other Utility Programs
@@ -3077,7 +3080,7 @@ $ gnatlink ada_unit file1.o file2.o --LINK=./my_script
Where CC is the name of the non-GNU C++ compiler.
If the @code{zero cost} exception mechanism is used, and the platform
-supports automatic registration of exception tables (e.g.@: Solaris or IRIX),
+supports automatic registration of exception tables (e.g.@: Solaris),
paths to more objects are required:
@smallexample
@@ -17988,6 +17991,7 @@ default location.
* Tagged Types Substitutability Testing::
* Testing with Contracts::
* Additional Tests::
+* Support for other platforms/run-times::
* Current Limitations::
@end menu
@@ -18474,6 +18478,25 @@ gnatmake -Pmixing/test_driver.gpr
mixing/test_runner
@end smallexample
+@node Support for other platforms/run-times
+@section Support for other platforms/run-times
+
+@noindent
+@command{gnattest} can be used to generate the test harness for platforms
+and run-time libraries others than the default native target with the
+default full run-time. For example, when using a limited run-time library
+such as Zero FootPrint (ZFP), a simplified harness is generated.
+
+Two variables are used to tell the underlying AUnit framework how to generate
+the test harness: @code{PLATFORM}, which identifies the target, and
+@code{RUNTIME}, used to determine the run-time library for which the harness
+is generated. For example, the following options are used to generate the
+AUnit test harness for a PowerPC ELF target using the ZFP run-time library:
+
+@smallexample
+gnattest -Psimple.gpr -XPLATFORM=powerpc-elf -XRUNTIME=zfp
+@end smallexample
+
@node Current Limitations
@section Current Limitations
diff --git a/gcc/ada/lib-writ.adb b/gcc/ada/lib-writ.adb
index 2d67ea03ccd..e25355bfc30 100644
--- a/gcc/ada/lib-writ.adb
+++ b/gcc/ada/lib-writ.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -196,6 +196,10 @@ package body Lib.Writ is
Elab_All_Des_Flags : array (Units.First .. Last_Unit) of Boolean;
-- Array of flags to show which units have Elaborate_All_Desirable set
+ type Yes_No is (Unknown, Yes, No);
+
+ Implicit_With : array (Units.First .. Last_Unit) of Yes_No;
+
Sdep_Table : Unit_Ref_Table (1 .. Pos (Last_Unit - Units.First + 2));
-- Sorted table of source dependencies. One extra entry in case we
-- have to add a dummy entry for System.
@@ -276,6 +280,15 @@ package body Lib.Writ is
else
Set_From_With_Type (Cunit_Entity (Unum));
end if;
+
+ if Implicit_With (Unum) /= Yes then
+ if Implicit_With_From_Instantiation (Item) then
+ Implicit_With (Unum) := Yes;
+
+ else
+ Implicit_With (Unum) := No;
+ end if;
+ end if;
end if;
Next (Item);
@@ -552,6 +565,7 @@ package body Lib.Writ is
Elab_All_Flags (J) := False;
Elab_Des_Flags (J) := False;
Elab_All_Des_Flags (J) := False;
+ Implicit_With (J) := Unknown;
end loop;
Collect_Withs (Unode);
@@ -770,10 +784,14 @@ package body Lib.Writ is
Uname := Units.Table (Unum).Unit_Name;
Fname := Units.Table (Unum).Unit_File_Name;
- if Ekind (Cunit_Entity (Unum)) = E_Package
+ if Implicit_With (Unum) = Yes then
+ Write_Info_Initiate ('Z');
+
+ elsif Ekind (Cunit_Entity (Unum)) = E_Package
and then From_With_Type (Cunit_Entity (Unum))
then
Write_Info_Initiate ('Y');
+
else
Write_Info_Initiate ('W');
end if;
diff --git a/gcc/ada/lib-xref-alfa.adb b/gcc/ada/lib-xref-alfa.adb
index 4961fedc8c1..c9ab1e03b10 100644
--- a/gcc/ada/lib-xref-alfa.adb
+++ b/gcc/ada/lib-xref-alfa.adb
@@ -40,102 +40,19 @@ package body Alfa is
-- Table of Alfa_Entities, True for each entity kind used in Alfa
Alfa_Entities : constant array (Entity_Kind) of Boolean :=
- (E_Void => False,
- E_Variable => True,
- E_Component => False,
- E_Constant => True,
- E_Discriminant => False,
-
- E_Loop_Parameter => True,
- E_In_Parameter => True,
- E_Out_Parameter => True,
- E_In_Out_Parameter => True,
- E_Generic_In_Out_Parameter => False,
-
- E_Generic_In_Parameter => False,
- E_Named_Integer => False,
- E_Named_Real => False,
- E_Enumeration_Type => False,
- E_Enumeration_Subtype => False,
-
- E_Signed_Integer_Type => False,
- E_Signed_Integer_Subtype => False,
- E_Modular_Integer_Type => False,
- E_Modular_Integer_Subtype => False,
- E_Ordinary_Fixed_Point_Type => False,
-
- E_Ordinary_Fixed_Point_Subtype => False,
- E_Decimal_Fixed_Point_Type => False,
- E_Decimal_Fixed_Point_Subtype => False,
- E_Floating_Point_Type => False,
- E_Floating_Point_Subtype => False,
-
- E_Access_Type => False,
- E_Access_Subtype => False,
- E_Access_Attribute_Type => False,
- E_Allocator_Type => False,
- E_General_Access_Type => False,
-
- E_Access_Subprogram_Type => False,
- E_Access_Protected_Subprogram_Type => False,
- E_Anonymous_Access_Subprogram_Type => False,
- E_Anonymous_Access_Protected_Subprogram_Type => False,
- E_Anonymous_Access_Type => False,
-
- E_Array_Type => False,
- E_Array_Subtype => False,
- E_String_Type => False,
- E_String_Subtype => False,
- E_String_Literal_Subtype => False,
-
- E_Class_Wide_Type => False,
- E_Class_Wide_Subtype => False,
- E_Record_Type => False,
- E_Record_Subtype => False,
- E_Record_Type_With_Private => False,
-
- E_Record_Subtype_With_Private => False,
- E_Private_Type => False,
- E_Private_Subtype => False,
- E_Limited_Private_Type => False,
- E_Limited_Private_Subtype => False,
-
- E_Incomplete_Type => False,
- E_Incomplete_Subtype => False,
- E_Task_Type => False,
- E_Task_Subtype => False,
- E_Protected_Type => False,
-
- E_Protected_Subtype => False,
- E_Exception_Type => False,
- E_Subprogram_Type => False,
- E_Enumeration_Literal => False,
- E_Function => True,
-
- E_Operator => True,
- E_Procedure => True,
- E_Entry => False,
- E_Entry_Family => False,
- E_Block => False,
-
- E_Entry_Index_Parameter => False,
- E_Exception => False,
- E_Generic_Function => False,
- E_Generic_Package => False,
- E_Generic_Procedure => False,
-
- E_Label => False,
- E_Loop => False,
- E_Return_Statement => False,
- E_Package => False,
-
- E_Package_Body => False,
- E_Protected_Object => False,
- E_Protected_Body => False,
- E_Task_Body => False,
- E_Subprogram_Body => False);
+ (E_Constant => True,
+ E_Function => True,
+ E_In_Out_Parameter => True,
+ E_In_Parameter => True,
+ E_Loop_Parameter => True,
+ E_Operator => True,
+ E_Out_Parameter => True,
+ E_Procedure => True,
+ E_Variable => True,
+ others => False);
-- True for each reference type used in Alfa
+
Alfa_References : constant array (Character) of Boolean :=
('m' => True,
'r' => True,
@@ -149,12 +66,15 @@ package body Alfa is
-- Local Variables --
---------------------
+ Heap : Entity_Id := Empty;
+ -- A special entity which denotes the heap object
+
package Drefs is new Table.Table (
Table_Component_Type => Xref_Entry,
Table_Index_Type => Xref_Entry_Number,
Table_Low_Bound => 1,
- Table_Initial => Alloc.Xrefs_Initial,
- Table_Increment => Alloc.Xrefs_Increment,
+ Table_Initial => Alloc.Drefs_Initial,
+ Table_Increment => Alloc.Drefs_Increment,
Table_Name => "Drefs");
-- Table of cross-references for reads and writes through explicit
-- dereferences, that are output as reads/writes to the special variable
@@ -165,9 +85,12 @@ package body Alfa is
-- Local Subprograms --
-----------------------
- procedure Add_Alfa_File (U : Unit_Number_Type; D : Nat);
- -- Add file U and all scopes in U to the tables Alfa_File_Table and
- -- Alfa_Scope_Table.
+ procedure Add_Alfa_File (Ubody, Uspec : Unit_Number_Type; Dspec : Nat);
+ -- Add file and corresponding scopes for unit to the tables Alfa_File_Table
+ -- and Alfa_Scope_Table. When two units are present for the same
+ -- compilation unit, as it happens for library-level instantiations of
+ -- generics, then Ubody /= Uspec, and all scopes are added to the same
+ -- Alfa file. Otherwise Ubody = Uspec.
procedure Add_Alfa_Scope (N : Node_Id);
-- Add scope N to the table Alfa_Scope_Table
@@ -202,16 +125,15 @@ package body Alfa is
(N : Node_Id;
Process : Node_Processing;
Inside_Stubs : Boolean);
- -- Traverse the corresponding constructs, calling Process on all
- -- declarations.
+ -- Traverse corresponding construct, calling Process on all declarations
-------------------
-- Add_Alfa_File --
-------------------
- procedure Add_Alfa_File (U : Unit_Number_Type; D : Nat) is
+ procedure Add_Alfa_File (Ubody, Uspec : Unit_Number_Type; Dspec : Nat) is
+ File : constant Source_File_Index := Source_Index (Uspec);
From : Scope_Index;
- S : constant Source_File_Index := Source_Index (U);
File_Name : String_Ptr;
Unit_File_Name : String_Ptr;
@@ -220,69 +142,84 @@ package body Alfa is
-- Source file could be inexistant as a result of an error, if option
-- gnatQ is used.
- if S = No_Source_File then
+ if File = No_Source_File then
return;
end if;
From := Alfa_Scope_Table.Last + 1;
- Traverse_Compilation_Unit (Cunit (U), Detect_And_Add_Alfa_Scope'Access,
- Inside_Stubs => False);
+ -- Unit might not have an associated compilation unit, as seen in code
+ -- filling Sdep_Table in Write_ALI.
+
+ if Present (Cunit (Ubody)) then
+ Traverse_Compilation_Unit
+ (CU => Cunit (Ubody),
+ Process => Detect_And_Add_Alfa_Scope'Access,
+ Inside_Stubs => False);
+ end if;
+
+ -- When two units are present for the same compilation unit, as it
+ -- happens for library-level instantiations of generics, then add all
+ -- scopes to the same Alfa file.
+
+ if Ubody /= Uspec then
+ if Present (Cunit (Uspec)) then
+ Traverse_Compilation_Unit
+ (CU => Cunit (Uspec),
+ Process => Detect_And_Add_Alfa_Scope'Access,
+ Inside_Stubs => False);
+ end if;
+ end if;
-- Update scope numbers
declare
- Count : Nat;
-
+ Scope_Id : Int;
begin
- Count := 1;
- for S in From .. Alfa_Scope_Table.Last loop
+ Scope_Id := 1;
+ for Index in From .. Alfa_Scope_Table.Last loop
declare
- E : Entity_Id renames Alfa_Scope_Table.Table (S).Scope_Entity;
-
+ S : Alfa_Scope_Record renames Alfa_Scope_Table.Table (Index);
begin
- if Lib.Get_Source_Unit (E) = U then
- Alfa_Scope_Table.Table (S).Scope_Num := Count;
- Alfa_Scope_Table.Table (S).File_Num := D;
- Count := Count + 1;
-
- else
- -- Mark for removal a scope S which is not located in unit
- -- U, for example for scope inside generics that get
- -- instantiated.
-
- Alfa_Scope_Table.Table (S).Scope_Num := 0;
- end if;
+ S.Scope_Num := Scope_Id;
+ S.File_Num := Dspec;
+ Scope_Id := Scope_Id + 1;
end;
end loop;
end;
+ -- Remove those scopes previously marked for removal
+
declare
- Snew : Scope_Index;
+ Scope_Id : Scope_Index;
begin
- Snew := From;
- for S in From .. Alfa_Scope_Table.Last loop
- -- Remove those scopes previously marked for removal
-
- if Alfa_Scope_Table.Table (S).Scope_Num /= 0 then
- Alfa_Scope_Table.Table (Snew) := Alfa_Scope_Table.Table (S);
- Snew := Snew + 1;
- end if;
+ Scope_Id := From;
+ for Index in From .. Alfa_Scope_Table.Last loop
+ declare
+ S : Alfa_Scope_Record renames Alfa_Scope_Table.Table (Index);
+ begin
+ if S.Scope_Num /= 0 then
+ Alfa_Scope_Table.Table (Scope_Id) := S;
+ Scope_Id := Scope_Id + 1;
+ end if;
+ end;
end loop;
- Alfa_Scope_Table.Set_Last (Snew - 1);
+ Alfa_Scope_Table.Set_Last (Scope_Id - 1);
end;
-- Make entry for new file in file table
- Get_Name_String (Reference_Name (S));
+ Get_Name_String (Reference_Name (File));
File_Name := new String'(Name_Buffer (1 .. Name_Len));
- -- For subunits, also retrieve the file name of the unit
+ -- For subunits, also retrieve the file name of the unit. Only do so if
+ -- unit has an associated compilation unit.
- if Present (Cunit (Unit (S)))
- and then Nkind (Unit (Cunit (Unit (S)))) = N_Subunit
+ if Present (Cunit (Uspec))
+ and then Present (Cunit (Unit (File)))
+ and then Nkind (Unit (Cunit (Unit (File)))) = N_Subunit
then
Get_Name_String (Reference_Name (Main_Source_File));
Unit_File_Name := new String'(Name_Buffer (1 .. Name_Len));
@@ -291,7 +228,7 @@ package body Alfa is
Alfa_File_Table.Append (
(File_Name => File_Name,
Unit_File_Name => Unit_File_Name,
- File_Num => D,
+ File_Num => Dspec,
From_Scope => From,
To_Scope => Alfa_Scope_Table.Last));
end Add_Alfa_File;
@@ -376,55 +313,69 @@ package body Alfa is
--------------------
procedure Add_Alfa_Xrefs is
- Cur_Scope_Idx : Scope_Index;
- From_Xref_Idx : Xref_Index;
- Cur_Entity : Entity_Id;
- Cur_Entity_Name : String_Ptr;
-
- package Scopes is
- No_Scope : constant Nat := 0;
- function Get_Scope_Num (N : Entity_Id) return Nat;
- procedure Set_Scope_Num (N : Entity_Id; Num : Nat);
- end Scopes;
-
- ------------
- -- Scopes --
- ------------
-
- package body Scopes is
- type Scope is record
- Num : Nat;
- Entity : Entity_Id;
- end record;
-
- package Scopes is new GNAT.HTable.Simple_HTable
- (Header_Num => Entity_Hashed_Range,
- Element => Scope,
- No_Element => (Num => No_Scope, Entity => Empty),
- Key => Entity_Id,
- Hash => Entity_Hash,
- Equal => "=");
-
- -------------------
- -- Get_Scope_Num --
- -------------------
-
- function Get_Scope_Num (N : Entity_Id) return Nat is
- begin
- return Scopes.Get (N).Num;
- end Get_Scope_Num;
+ function Entity_Of_Scope (S : Scope_Index) return Entity_Id;
+ -- Return the entity which maps to the input scope index
- -------------------
- -- Set_Scope_Num --
- -------------------
+ function Get_Entity_Type (E : Entity_Id) return Character;
+ -- Return a character representing the type of entity
- procedure Set_Scope_Num (N : Entity_Id; Num : Nat) is
- begin
- Scopes.Set (K => N, E => Scope'(Num => Num, Entity => N));
- end Set_Scope_Num;
- end Scopes;
+ function Is_Alfa_Reference
+ (E : Entity_Id;
+ Typ : Character) return Boolean;
+ -- Return whether entity reference E meets Alfa requirements. Typ is the
+ -- reference type.
+
+ function Is_Alfa_Scope (E : Entity_Id) return Boolean;
+ -- Return whether the entity or reference scope meets requirements for
+ -- being an Alfa scope.
+
+ function Is_Future_Scope_Entity
+ (E : Entity_Id;
+ S : Scope_Index) return Boolean;
+ -- Check whether entity E is in Alfa_Scope_Table at index S or higher
+
+ function Is_Global_Constant (E : Entity_Id) return Boolean;
+ -- Return True if E is a global constant for which we should ignore
+ -- reads in Alfa.
+
+ function Lt (Op1 : Natural; Op2 : Natural) return Boolean;
+ -- Comparison function for Sort call
+
+ procedure Move (From : Natural; To : Natural);
+ -- Move procedure for Sort call
+
+ procedure Update_Scope_Range
+ (S : Scope_Index;
+ From : Xref_Index;
+ To : Xref_Index);
+ -- Update the scope which maps to S with the new range From .. To
+
+ package Sorting is new GNAT.Heap_Sort_G (Move, Lt);
+
+ function Get_Scope_Num (N : Entity_Id) return Nat;
+ -- Return the scope number associated to entity N
+
+ procedure Set_Scope_Num (N : Entity_Id; Num : Nat);
+ -- Associate entity N to scope number Num
+
+ No_Scope : constant Nat := 0;
+ -- Initial scope counter
- use Scopes;
+ type Scope_Rec is record
+ Num : Nat;
+ Entity : Entity_Id;
+ end record;
+ -- Type used to relate an entity and a scope number
+
+ package Scopes is new GNAT.HTable.Simple_HTable
+ (Header_Num => Entity_Hashed_Range,
+ Element => Scope_Rec,
+ No_Element => (Num => No_Scope, Entity => Empty),
+ Key => Entity_Id,
+ Hash => Entity_Hash,
+ Equal => "=");
+ -- Package used to build a correspondance between entities and scope
+ -- numbers used in Alfa cross references.
Nrefs : Nat := Xrefs.Last;
-- Number of references in table. This value may get reset (reduced)
@@ -432,6 +383,8 @@ package body Alfa is
-- not suitable for local cross-references.
Nrefs_Add : constant Nat := Drefs.Last;
+ -- Number of additional references which correspond to dereferences in
+ -- the source code.
Rnums : array (0 .. Nrefs + Nrefs_Add) of Nat;
-- This array contains numbers of references in the Xrefs table. This
@@ -439,13 +392,149 @@ package body Alfa is
-- for the call to sort. When we sort the table, we move the entries in
-- Rnums around, but we do not move the original table entries.
- function Lt (Op1, Op2 : Natural) return Boolean;
- -- Comparison function for Sort call
+ ---------------------
+ -- Entity_Of_Scope --
+ ---------------------
- procedure Move (From : Natural; To : Natural);
- -- Move procedure for Sort call
+ function Entity_Of_Scope (S : Scope_Index) return Entity_Id is
+ begin
+ return Alfa_Scope_Table.Table (S).Scope_Entity;
+ end Entity_Of_Scope;
- package Sorting is new GNAT.Heap_Sort_G (Move, Lt);
+ ---------------------
+ -- Get_Entity_Type --
+ ---------------------
+
+ function Get_Entity_Type (E : Entity_Id) return Character is
+ begin
+ case Ekind (E) is
+ when E_Out_Parameter => return '<';
+ when E_In_Out_Parameter => return '=';
+ when E_In_Parameter => return '>';
+ when others => return '*';
+ end case;
+ end Get_Entity_Type;
+
+ -------------------
+ -- Get_Scope_Num --
+ -------------------
+
+ function Get_Scope_Num (N : Entity_Id) return Nat is
+ begin
+ return Scopes.Get (N).Num;
+ end Get_Scope_Num;
+
+ -----------------------
+ -- Is_Alfa_Reference --
+ -----------------------
+
+ function Is_Alfa_Reference
+ (E : Entity_Id;
+ Typ : Character) return Boolean
+ is
+ begin
+ -- The only references of interest on callable entities are calls. On
+ -- non-callable entities, the only references of interest are reads
+ -- and writes.
+
+ if Ekind (E) in Overloadable_Kind then
+ return Typ = 's';
+
+ -- References to constant objects are not considered in Alfa section,
+ -- as these will be translated as constants in the intermediate
+ -- language for formal verification, and should therefore never
+ -- appear in frame conditions.
+
+ elsif Is_Constant_Object (E) then
+ return False;
+
+ -- Objects of Task type or protected type are not Alfa references
+
+ elsif Present (Etype (E))
+ and then Ekind (Etype (E)) in Concurrent_Kind
+ then
+ return False;
+
+ -- In all other cases, result is true for reference/modify cases,
+ -- and false for all other cases.
+
+ else
+ return Typ = 'r' or else Typ = 'm';
+ end if;
+ end Is_Alfa_Reference;
+
+ -------------------
+ -- Is_Alfa_Scope --
+ -------------------
+
+ function Is_Alfa_Scope (E : Entity_Id) return Boolean is
+ begin
+ return Present (E)
+ and then not Is_Generic_Unit (E)
+ and then Renamed_Entity (E) = Empty
+ and then Get_Scope_Num (E) /= No_Scope;
+ end Is_Alfa_Scope;
+
+ ----------------------------
+ -- Is_Future_Scope_Entity --
+ ----------------------------
+
+ function Is_Future_Scope_Entity
+ (E : Entity_Id;
+ S : Scope_Index) return Boolean
+ is
+ function Is_Past_Scope_Entity return Boolean;
+ -- Check whether entity E is in Alfa_Scope_Table at index strictly
+ -- lower than S.
+
+ --------------------------
+ -- Is_Past_Scope_Entity --
+ --------------------------
+
+ function Is_Past_Scope_Entity return Boolean is
+ begin
+ for Index in Alfa_Scope_Table.First .. S - 1 loop
+ if Alfa_Scope_Table.Table (Index).Scope_Entity = E then
+ declare
+ Dummy : constant Alfa_Scope_Record :=
+ Alfa_Scope_Table.Table (Index);
+ pragma Unreferenced (Dummy);
+ begin
+ return True;
+ end;
+ end if;
+ end loop;
+
+ return False;
+ end Is_Past_Scope_Entity;
+
+ -- Start of processing for Is_Future_Scope_Entity
+
+ begin
+ for Index in S .. Alfa_Scope_Table.Last loop
+ if Alfa_Scope_Table.Table (Index).Scope_Entity = E then
+ return True;
+ end if;
+ end loop;
+
+ -- If this assertion fails, this means that the scope which we are
+ -- looking for has been treated already, which reveals a problem in
+ -- the order of cross-references.
+
+ pragma Assert (not Is_Past_Scope_Entity);
+
+ return False;
+ end Is_Future_Scope_Entity;
+
+ ------------------------
+ -- Is_Global_Constant --
+ ------------------------
+
+ function Is_Global_Constant (E : Entity_Id) return Boolean is
+ begin
+ return Ekind (E) = E_Constant
+ and then Ekind_In (Scope (E), E_Package, E_Package_Body);
+ end Is_Global_Constant;
--------
-- Lt --
@@ -464,7 +553,7 @@ package body Alfa is
if T1.Ent_Scope_File /= T2.Ent_Scope_File then
return Dependency_Num (T1.Ent_Scope_File) <
- Dependency_Num (T2.Ent_Scope_File);
+ Dependency_Num (T2.Ent_Scope_File);
-- Second test: within same unit, sort by location of the scope of
-- the entity definition.
@@ -473,7 +562,7 @@ package body Alfa is
Get_Scope_Num (T2.Key.Ent_Scope)
then
return Get_Scope_Num (T1.Key.Ent_Scope) <
- Get_Scope_Num (T2.Key.Ent_Scope);
+ Get_Scope_Num (T2.Key.Ent_Scope);
-- Third test: within same unit and scope, sort by location of
-- entity definition.
@@ -481,59 +570,68 @@ package body Alfa is
elsif T1.Def /= T2.Def then
return T1.Def < T2.Def;
- -- Fourth test: if reference is in same unit as entity definition,
- -- sort first.
+ else
+ -- Both entities must be equal at this point
- elsif
- T1.Key.Lun /= T2.Key.Lun and then T1.Ent_Scope_File = T1.Key.Lun
- then
- return True;
+ pragma Assert (T1.Key.Ent = T2.Key.Ent);
- elsif
- T1.Key.Lun /= T2.Key.Lun and then T2.Ent_Scope_File = T2.Key.Lun
- then
- return False;
+ -- Fourth test: if reference is in same unit as entity definition,
+ -- sort first.
- -- Fifth test: if reference is in same unit and same scope as entity
- -- definition, sort first.
+ if T1.Key.Lun /= T2.Key.Lun
+ and then T1.Ent_Scope_File = T1.Key.Lun
+ then
+ return True;
- elsif T1.Ent_Scope_File = T1.Key.Lun
- and then T1.Key.Ref_Scope /= T2.Key.Ref_Scope
- and then T1.Key.Ent_Scope = T1.Key.Ref_Scope
- then
- return True;
- elsif T1.Ent_Scope_File = T1.Key.Lun
- and then T1.Key.Ref_Scope /= T2.Key.Ref_Scope
- and then T2.Key.Ent_Scope = T2.Key.Ref_Scope
- then
- return False;
+ elsif T1.Key.Lun /= T2.Key.Lun
+ and then T2.Ent_Scope_File = T2.Key.Lun
+ then
+ return False;
- -- Sixth test: for same entity, sort by reference location unit
+ -- Fifth test: if reference is in same unit and same scope as
+ -- entity definition, sort first.
- elsif T1.Key.Lun /= T2.Key.Lun then
- return Dependency_Num (T1.Key.Lun) < Dependency_Num (T2.Key.Lun);
+ elsif T1.Ent_Scope_File = T1.Key.Lun
+ and then T1.Key.Ref_Scope /= T2.Key.Ref_Scope
+ and then T1.Key.Ent_Scope = T1.Key.Ref_Scope
+ then
+ return True;
- -- Seventh test: for same entity, sort by reference location scope
+ elsif T2.Ent_Scope_File = T2.Key.Lun
+ and then T1.Key.Ref_Scope /= T2.Key.Ref_Scope
+ and then T2.Key.Ent_Scope = T2.Key.Ref_Scope
+ then
+ return False;
- elsif Get_Scope_Num (T1.Key.Ref_Scope) /=
- Get_Scope_Num (T2.Key.Ref_Scope)
- then
- return Get_Scope_Num (T1.Key.Ref_Scope) <
- Get_Scope_Num (T2.Key.Ref_Scope);
+ -- Sixth test: for same entity, sort by reference location unit
- -- Eighth test: order of location within referencing unit
+ elsif T1.Key.Lun /= T2.Key.Lun then
+ return Dependency_Num (T1.Key.Lun) <
+ Dependency_Num (T2.Key.Lun);
- elsif T1.Key.Loc /= T2.Key.Loc then
- return T1.Key.Loc < T2.Key.Loc;
+ -- Seventh test: for same entity, sort by reference location scope
- -- Finally, for two locations at the same address prefer the one that
- -- does NOT have the type 'r', so that a modification or extension
- -- takes preference, when there are more than one reference at the
- -- same location. As a result, in the case of entities that are
- -- in-out actuals, the read reference follows the modify reference.
+ elsif Get_Scope_Num (T1.Key.Ref_Scope) /=
+ Get_Scope_Num (T2.Key.Ref_Scope)
+ then
+ return Get_Scope_Num (T1.Key.Ref_Scope) <
+ Get_Scope_Num (T2.Key.Ref_Scope);
- else
- return T2.Key.Typ = 'r';
+ -- Eighth test: order of location within referencing unit
+
+ elsif T1.Key.Loc /= T2.Key.Loc then
+ return T1.Key.Loc < T2.Key.Loc;
+
+ -- Finally, for two locations at the same address prefer the one
+ -- that does NOT have the type 'r', so that a modification or
+ -- extension takes preference, when there are more than one
+ -- reference at the same location. As a result, in the case of
+ -- entities that are in-out actuals, the read reference follows
+ -- the modify reference.
+
+ else
+ return T2.Key.Typ = 'r';
+ end if;
end if;
end Lt;
@@ -546,308 +644,167 @@ package body Alfa is
Rnums (Nat (To)) := Rnums (Nat (From));
end Move;
- Heap : Entity_Id;
+ -------------------
+ -- Set_Scope_Num --
+ -------------------
+
+ procedure Set_Scope_Num (N : Entity_Id; Num : Nat) is
+ begin
+ Scopes.Set (K => N, E => Scope_Rec'(Num => Num, Entity => N));
+ end Set_Scope_Num;
+
+ ------------------------
+ -- Update_Scope_Range --
+ ------------------------
+
+ procedure Update_Scope_Range
+ (S : Scope_Index;
+ From : Xref_Index;
+ To : Xref_Index)
+ is
+ begin
+ Alfa_Scope_Table.Table (S).From_Xref := From;
+ Alfa_Scope_Table.Table (S).To_Xref := To;
+ end Update_Scope_Range;
+
+ -- Local variables
+
+ Col : Nat;
+ From_Index : Xref_Index;
+ Line : Nat;
+ Loc : Source_Ptr;
+ Prev_Typ : Character;
+ Ref_Count : Nat;
+ Ref_Id : Entity_Id;
+ Ref_Name : String_Ptr;
+ Scope_Id : Scope_Index;
-- Start of processing for Add_Alfa_Xrefs
begin
- for J in Alfa_Scope_Table.First .. Alfa_Scope_Table.Last loop
- Set_Scope_Num (N => Alfa_Scope_Table.Table (J).Scope_Entity,
- Num => Alfa_Scope_Table.Table (J).Scope_Num);
+ for Index in Alfa_Scope_Table.First .. Alfa_Scope_Table.Last loop
+ declare
+ S : Alfa_Scope_Record renames Alfa_Scope_Table.Table (Index);
+ begin
+ Set_Scope_Num (S.Scope_Entity, S.Scope_Num);
+ end;
end loop;
-- Set up the pointer vector for the sort
- for J in 1 .. Nrefs loop
- Rnums (J) := J;
+ for Index in 1 .. Nrefs loop
+ Rnums (Index) := Index;
end loop;
- -- Add dereferences to the set of regular references, by creating a
- -- special "Heap" variable for these special references.
-
- Name_Len := Name_Of_Heap_Variable'Length;
- Name_Buffer (1 .. Name_Len) := Name_Of_Heap_Variable;
-
- Atree.Unlock;
- Nlists.Unlock;
- Heap := Make_Defining_Identifier (Standard_Location, Name_Enter);
- Atree.Lock;
- Nlists.Lock;
-
- Set_Ekind (Heap, E_Variable);
- Set_Is_Internal (Heap, True);
- Set_Has_Fully_Qualified_Name (Heap);
-
- for J in Drefs.First .. Drefs.Last loop
- Xrefs.Append (Drefs.Table (J));
-
- -- Set entity at this point with newly created "Heap" variable
-
- Xrefs.Table (Xrefs.Last).Key.Ent := Heap;
+ for Index in Drefs.First .. Drefs.Last loop
+ Xrefs.Append (Drefs.Table (Index));
Nrefs := Nrefs + 1;
Rnums (Nrefs) := Xrefs.Last;
end loop;
+ -- Capture the definition Sloc values. As in the case of normal cross
+ -- references, we have to wait until now to get the correct value.
+
+ for Index in 1 .. Nrefs loop
+ Xrefs.Table (Index).Def := Sloc (Xrefs.Table (Index).Key.Ent);
+ end loop;
+
-- Eliminate entries not appropriate for Alfa. Done prior to sorting
-- cross-references, as it discards useless references which do not have
-- a proper format for the comparison function (like no location).
- Eliminate_Before_Sort : declare
- NR : Nat;
-
- function Is_Alfa_Reference
- (E : Entity_Id;
- Typ : Character) return Boolean;
- -- Return whether entity reference E meets Alfa requirements. Typ
- -- is the reference type.
-
- function Is_Alfa_Scope (E : Entity_Id) return Boolean;
- -- Return whether the entity or reference scope meets requirements
- -- for being an Alfa scope.
+ Ref_Count := Nrefs;
+ Nrefs := 0;
- function Is_Global_Constant (E : Entity_Id) return Boolean;
- -- Return True if E is a global constant for which we should ignore
- -- reads in Alfa.
+ for Index in 1 .. Ref_Count loop
+ declare
+ Ref : Xref_Key renames Xrefs.Table (Rnums (Index)).Key;
- -----------------------
- -- Is_Alfa_Reference --
- -----------------------
-
- function Is_Alfa_Reference
- (E : Entity_Id;
- Typ : Character) return Boolean
- is
begin
- -- The only references of interest on callable entities are calls.
- -- On non-callable entities, the only references of interest are
- -- reads and writes.
-
- if Ekind (E) in Overloadable_Kind then
- return Typ = 's';
-
- -- References to constant objects are not considered in Alfa
- -- section, as these will be translated as constants in the
- -- intermediate language for formal verification, and should
- -- therefore never appear in frame conditions.
-
- elsif Is_Constant_Object (E) then
- return False;
+ if Alfa_Entities (Ekind (Ref.Ent))
+ and then Alfa_References (Ref.Typ)
+ and then Is_Alfa_Scope (Ref.Ent_Scope)
+ and then Is_Alfa_Scope (Ref.Ref_Scope)
+ and then not Is_Global_Constant (Ref.Ent)
+ and then Is_Alfa_Reference (Ref.Ent, Ref.Typ)
- -- Objects of Task type or protected type are not Alfa references
+ -- Discard references from unknown scopes, e.g. generic scopes
- elsif Present (Etype (E))
- and then Ekind (Etype (E)) in Concurrent_Kind
- then
- return False;
-
- -- In all other cases, result is true for reference/modify cases,
- -- and false for all other cases.
-
- else
- return Typ = 'r' or else Typ = 'm';
- end if;
- end Is_Alfa_Reference;
-
- -------------------
- -- Is_Alfa_Scope --
- -------------------
-
- function Is_Alfa_Scope (E : Entity_Id) return Boolean is
- begin
- return Present (E)
- and then not Is_Generic_Unit (E)
- and then Renamed_Entity (E) = Empty
- and then Get_Scope_Num (E) /= No_Scope;
- end Is_Alfa_Scope;
-
- ------------------------
- -- Is_Global_Constant --
- ------------------------
-
- function Is_Global_Constant (E : Entity_Id) return Boolean is
- begin
- return Ekind (E) = E_Constant
- and then Ekind_In (Scope (E), E_Package, E_Package_Body);
- end Is_Global_Constant;
-
- -- Start of processing for Eliminate_Before_Sort
-
- begin
- NR := Nrefs;
- Nrefs := 0;
-
- for J in 1 .. NR loop
- if Alfa_Entities (Ekind (Xrefs.Table (Rnums (J)).Key.Ent))
- and then Alfa_References (Xrefs.Table (Rnums (J)).Key.Typ)
- and then Is_Alfa_Scope (Xrefs.Table (Rnums (J)).Key.Ent_Scope)
- and then Is_Alfa_Scope (Xrefs.Table (Rnums (J)).Key.Ref_Scope)
- and then not Is_Global_Constant (Xrefs.Table (Rnums (J)).Key.Ent)
- and then Is_Alfa_Reference (Xrefs.Table (Rnums (J)).Key.Ent,
- Xrefs.Table (Rnums (J)).Key.Typ)
+ and then Get_Scope_Num (Ref.Ent_Scope) /= No_Scope
+ and then Get_Scope_Num (Ref.Ref_Scope) /= No_Scope
then
Nrefs := Nrefs + 1;
- Rnums (Nrefs) := Rnums (J);
+ Rnums (Nrefs) := Rnums (Index);
end if;
- end loop;
- end Eliminate_Before_Sort;
+ end;
+ end loop;
-- Sort the references
Sorting.Sort (Integer (Nrefs));
- Eliminate_After_Sort : declare
- NR : Nat;
+ -- Eliminate duplicate entries
- Crloc : Source_Ptr;
- -- Current reference location
+ -- We need this test for Ref_Count because if we force ALI file
+ -- generation in case of errors detected, it may be the case that
+ -- Nrefs is 0, so we should not reset it here.
- Prevt : Character;
- -- reference kind of previous reference
+ if Nrefs >= 2 then
+ Ref_Count := Nrefs;
+ Nrefs := 1;
- begin
- -- Eliminate duplicate entries
-
- -- We need this test for NR because if we force ALI file generation
- -- in case of errors detected, it may be the case that Nrefs is 0, so
- -- we should not reset it here
-
- if Nrefs >= 2 then
- NR := Nrefs;
- Nrefs := 1;
+ for Index in 2 .. Ref_Count loop
+ if Xrefs.Table (Rnums (Index)) /=
+ Xrefs.Table (Rnums (Nrefs))
+ then
+ Nrefs := Nrefs + 1;
+ Rnums (Nrefs) := Rnums (Index);
+ end if;
+ end loop;
+ end if;
- for J in 2 .. NR loop
- if Xrefs.Table (Rnums (J)) /=
- Xrefs.Table (Rnums (Nrefs))
- then
- Nrefs := Nrefs + 1;
- Rnums (Nrefs) := Rnums (J);
- end if;
- end loop;
- end if;
+ -- Eliminate the reference if it is at the same location as the previous
+ -- one, unless it is a read-reference indicating that the entity is an
+ -- in-out actual in a call.
- -- Eliminate the reference if it is at the same location as the
- -- previous one, unless it is a read-reference indicating that the
- -- entity is an in-out actual in a call.
+ Ref_Count := Nrefs;
+ Nrefs := 0;
+ Loc := No_Location;
+ Prev_Typ := 'm';
- NR := Nrefs;
- Nrefs := 0;
- Crloc := No_Location;
- Prevt := 'm';
+ for Index in 1 .. Ref_Count loop
+ declare
+ Ref : Xref_Key renames Xrefs.Table (Rnums (Index)).Key;
- for J in 1 .. NR loop
- if Xrefs.Table (Rnums (J)).Key.Loc /= Crloc
- or else (Prevt = 'm'
- and then Xrefs.Table (Rnums (J)).Key.Typ = 'r')
+ begin
+ if Ref.Loc /= Loc
+ or else (Prev_Typ = 'm' and then Ref.Typ = 'r')
then
- Crloc := Xrefs.Table (Rnums (J)).Key.Loc;
- Prevt := Xrefs.Table (Rnums (J)).Key.Typ;
+ Loc := Ref.Loc;
+ Prev_Typ := Ref.Typ;
Nrefs := Nrefs + 1;
- Rnums (Nrefs) := Rnums (J);
+ Rnums (Nrefs) := Rnums (Index);
end if;
- end loop;
- end Eliminate_After_Sort;
-
- -- Initialize loop
+ end;
+ end loop;
- Cur_Scope_Idx := 1;
- From_Xref_Idx := 1;
- Cur_Entity := Empty;
+ -- The two steps have eliminated all references, nothing to do
if Alfa_Scope_Table.Last = 0 then
return;
end if;
+ Ref_Id := Empty;
+ Scope_Id := 1;
+ From_Index := 1;
+
-- Loop to output references
for Refno in 1 .. Nrefs loop
- Add_One_Xref : declare
-
- -----------------------
- -- Local Subprograms --
- -----------------------
-
- function Cur_Scope return Node_Id;
- -- Return scope entity which corresponds to index Cur_Scope_Idx in
- -- table Alfa_Scope_Table.
-
- function Get_Entity_Type (E : Entity_Id) return Character;
- -- Return a character representing the type of entity
-
- function Is_Future_Scope_Entity (E : Entity_Id) return Boolean;
- -- Check whether entity E is in Alfa_Scope_Table at index
- -- Cur_Scope_Idx or higher.
-
- function Is_Past_Scope_Entity (E : Entity_Id) return Boolean;
- -- Check whether entity E is in Alfa_Scope_Table at index strictly
- -- lower than Cur_Scope_Idx.
-
- ---------------
- -- Cur_Scope --
- ---------------
-
- function Cur_Scope return Node_Id is
- begin
- return Alfa_Scope_Table.Table (Cur_Scope_Idx).Scope_Entity;
- end Cur_Scope;
-
- ---------------------
- -- Get_Entity_Type --
- ---------------------
-
- function Get_Entity_Type (E : Entity_Id) return Character is
- C : Character;
- begin
- case Ekind (E) is
- when E_Out_Parameter => C := '<';
- when E_In_Out_Parameter => C := '=';
- when E_In_Parameter => C := '>';
- when others => C := '*';
- end case;
- return C;
- end Get_Entity_Type;
-
- ----------------------------
- -- Is_Future_Scope_Entity --
- ----------------------------
-
- function Is_Future_Scope_Entity (E : Entity_Id) return Boolean is
- begin
- for J in Cur_Scope_Idx .. Alfa_Scope_Table.Last loop
- if E = Alfa_Scope_Table.Table (J).Scope_Entity then
- return True;
- end if;
- end loop;
-
- -- If this assertion fails, this means that the scope which we
- -- are looking for has been treated already, which reveals a
- -- problem in the order of cross-references.
-
- pragma Assert (not Is_Past_Scope_Entity (E));
-
- return False;
- end Is_Future_Scope_Entity;
-
- --------------------------
- -- Is_Past_Scope_Entity --
- --------------------------
-
- function Is_Past_Scope_Entity (E : Entity_Id) return Boolean is
- begin
- for J in Alfa_Scope_Table.First .. Cur_Scope_Idx - 1 loop
- if E = Alfa_Scope_Table.Table (J).Scope_Entity then
- return True;
- end if;
- end loop;
-
- return False;
- end Is_Past_Scope_Entity;
-
- ---------------------
- -- Local Variables --
- ---------------------
-
- XE : Xref_Entry renames Xrefs.Table (Rnums (Refno));
+ declare
+ Ref_Entry : Xref_Entry renames Xrefs.Table (Rnums (Refno));
+ Ref : Xref_Key renames Ref_Entry.Key;
begin
-- If this assertion fails, the scope which we are looking for is
@@ -855,61 +812,57 @@ package body Alfa is
-- construction of the scope table, or an erroneous scope for the
-- current cross-reference.
- pragma Assert (Is_Future_Scope_Entity (XE.Key.Ent_Scope));
+ pragma Assert (Is_Future_Scope_Entity (Ref.Ent_Scope, Scope_Id));
-- Update the range of cross references to which the current scope
-- refers to. This may be the empty range only for the first scope
-- considered.
- if XE.Key.Ent_Scope /= Cur_Scope then
- Alfa_Scope_Table.Table (Cur_Scope_Idx).From_Xref :=
- From_Xref_Idx;
- Alfa_Scope_Table.Table (Cur_Scope_Idx).To_Xref :=
- Alfa_Xref_Table.Last;
- From_Xref_Idx := Alfa_Xref_Table.Last + 1;
+ if Ref.Ent_Scope /= Entity_Of_Scope (Scope_Id) then
+ Update_Scope_Range
+ (S => Scope_Id,
+ From => From_Index,
+ To => Alfa_Xref_Table.Last);
+
+ From_Index := Alfa_Xref_Table.Last + 1;
end if;
- while XE.Key.Ent_Scope /= Cur_Scope loop
- Cur_Scope_Idx := Cur_Scope_Idx + 1;
- pragma Assert (Cur_Scope_Idx <= Alfa_Scope_Table.Last);
+ while Ref.Ent_Scope /= Entity_Of_Scope (Scope_Id) loop
+ Scope_Id := Scope_Id + 1;
+ pragma Assert (Scope_Id <= Alfa_Scope_Table.Last);
end loop;
- if XE.Key.Ent /= Cur_Entity then
- Cur_Entity_Name :=
- new String'(Unique_Name (XE.Key.Ent));
+ if Ref.Ent /= Ref_Id then
+ Ref_Name := new String'(Unique_Name (Ref.Ent));
end if;
- if XE.Key.Ent = Heap then
- Alfa_Xref_Table.Append (
- (Entity_Name => Cur_Entity_Name,
- Entity_Line => 0,
- Etype => Get_Entity_Type (XE.Key.Ent),
- Entity_Col => 0,
- File_Num => Dependency_Num (XE.Key.Lun),
- Scope_Num => Get_Scope_Num (XE.Key.Ref_Scope),
- Line => Int (Get_Logical_Line_Number (XE.Key.Loc)),
- Rtype => XE.Key.Typ,
- Col => Int (Get_Column_Number (XE.Key.Loc))));
-
+ if Ref.Ent = Heap then
+ Line := 0;
+ Col := 0;
else
- Alfa_Xref_Table.Append (
- (Entity_Name => Cur_Entity_Name,
- Entity_Line => Int (Get_Logical_Line_Number (XE.Def)),
- Etype => Get_Entity_Type (XE.Key.Ent),
- Entity_Col => Int (Get_Column_Number (XE.Def)),
- File_Num => Dependency_Num (XE.Key.Lun),
- Scope_Num => Get_Scope_Num (XE.Key.Ref_Scope),
- Line => Int (Get_Logical_Line_Number (XE.Key.Loc)),
- Rtype => XE.Key.Typ,
- Col => Int (Get_Column_Number (XE.Key.Loc))));
+ Line := Int (Get_Logical_Line_Number (Ref_Entry.Def));
+ Col := Int (Get_Column_Number (Ref_Entry.Def));
end if;
- end Add_One_Xref;
+
+ Alfa_Xref_Table.Append (
+ (Entity_Name => Ref_Name,
+ Entity_Line => Line,
+ Etype => Get_Entity_Type (Ref.Ent),
+ Entity_Col => Col,
+ File_Num => Dependency_Num (Ref.Lun),
+ Scope_Num => Get_Scope_Num (Ref.Ref_Scope),
+ Line => Int (Get_Logical_Line_Number (Ref.Loc)),
+ Rtype => Ref.Typ,
+ Col => Int (Get_Column_Number (Ref.Loc))));
+ end;
end loop;
-- Update the range of cross references to which the scope refers to
- Alfa_Scope_Table.Table (Cur_Scope_Idx).From_Xref := From_Xref_Idx;
- Alfa_Scope_Table.Table (Cur_Scope_Idx).To_Xref := Alfa_Xref_Table.Last;
+ Update_Scope_Range
+ (S => Scope_Id,
+ From => From_Index,
+ To => Alfa_Xref_Table.Last);
end Add_Alfa_Xrefs;
------------------
@@ -917,6 +870,9 @@ package body Alfa is
------------------
procedure Collect_Alfa (Sdep_Table : Unit_Ref_Table; Num_Sdep : Nat) is
+ D1 : Nat;
+ D2 : Nat;
+
begin
-- Cross-references should have been computed first
@@ -926,8 +882,28 @@ package body Alfa is
-- Generate file and scope Alfa information
- for D in 1 .. Num_Sdep loop
- Add_Alfa_File (U => Sdep_Table (D), D => D);
+ D1 := 1;
+ while D1 <= Num_Sdep loop
+
+ -- In rare cases, when treating the library-level instantiation of a
+ -- generic, two consecutive units refer to the same compilation unit
+ -- node and entity. In that case, treat them as a single unit for the
+ -- sake of Alfa cross references by passing to Add_Alfa_File.
+
+ if D1 < Num_Sdep
+ and then Cunit_Entity (Sdep_Table (D1)) =
+ Cunit_Entity (Sdep_Table (D1 + 1))
+ then
+ D2 := D1 + 1;
+ else
+ D2 := D1;
+ end if;
+
+ Add_Alfa_File
+ (Ubody => Sdep_Table (D1),
+ Uspec => Sdep_Table (D2),
+ Dspec => D2);
+ D1 := D2 + 1;
end loop;
-- Fill in the spec information when relevant
@@ -965,8 +941,7 @@ package body Alfa is
Entity_Hash_Table.Get (Spec_Entity);
begin
- -- Spec of generic may be missing, in which case Spec_Scope is
- -- zero.
+ -- Generic spec may be missing in which case Spec_Scope is zero
if Spec_Entity /= Srec.Scope_Entity
and then Spec_Scope /= 0
@@ -1020,9 +995,7 @@ package body Alfa is
Result := N;
end if;
- loop
- exit when No (Result);
-
+ while Present (Result) loop
case Nkind (Result) is
when N_Package_Specification =>
Result := Defining_Unit_Name (Result);
@@ -1068,7 +1041,7 @@ package body Alfa is
Result := Defining_Identifier (Result);
end if;
- -- Do no return a scope without a proper location
+ -- Do not return a scope without a proper location
if Present (Result)
and then Sloc (Result) = No_Location
@@ -1097,36 +1070,67 @@ package body Alfa is
(N : Node_Id;
Typ : Character := 'r')
is
- Indx : Nat;
- Ref : Source_Ptr;
+ procedure Create_Heap;
+ -- Create and decorate the special entity which denotes the heap
+
+ -----------------
+ -- Create_Heap --
+ -----------------
+
+ procedure Create_Heap is
+ begin
+ Name_Len := Name_Of_Heap_Variable'Length;
+ Name_Buffer (1 .. Name_Len) := Name_Of_Heap_Variable;
+
+ Heap := Make_Defining_Identifier (Standard_Location, Name_Enter);
+
+ Set_Ekind (Heap, E_Variable);
+ Set_Is_Internal (Heap, True);
+ Set_Has_Fully_Qualified_Name (Heap);
+ end Create_Heap;
+
+ -- Local variables
+
+ Loc : constant Source_Ptr := Sloc (N);
+ Index : Nat;
Ref_Scope : Entity_Id;
+ -- Start of processing for Generate_Dereference
+
begin
- Ref := Original_Location (Sloc (N));
- if Ref > No_Location then
+ if Loc > No_Location then
Drefs.Increment_Last;
- Indx := Drefs.Last;
+ Index := Drefs.Last;
+
+ declare
+ Deref_Entry : Xref_Entry renames Drefs.Table (Index);
+ Deref : Xref_Key renames Deref_Entry.Key;
+
+ begin
+ if No (Heap) then
+ Create_Heap;
+ end if;
- Ref_Scope := Enclosing_Subprogram_Or_Package (N);
+ Ref_Scope := Enclosing_Subprogram_Or_Package (N);
- -- Entity is filled later on with the special "Heap" variable
+ Deref.Ent := Heap;
+ Deref.Loc := Loc;
+ Deref.Typ := Typ;
- Drefs.Table (Indx).Key.Ent := Empty;
+ -- It is as if the special "Heap" was defined in every scope where
+ -- it is referenced.
- Drefs.Table (Indx).Def := No_Location;
- Drefs.Table (Indx).Key.Loc := Ref;
- Drefs.Table (Indx).Key.Typ := Typ;
+ Deref.Eun := Get_Code_Unit (Loc);
+ Deref.Lun := Get_Code_Unit (Loc);
- -- It is as if the special "Heap" was defined in every scope where it
- -- is referenced.
+ Deref.Ref_Scope := Ref_Scope;
+ Deref.Ent_Scope := Ref_Scope;
- Drefs.Table (Indx).Key.Eun := Get_Source_Unit (Ref);
- Drefs.Table (Indx).Key.Lun := Get_Source_Unit (Ref);
+ Deref_Entry.Def := No_Location;
- Drefs.Table (Indx).Key.Ref_Scope := Ref_Scope;
- Drefs.Table (Indx).Key.Ent_Scope := Ref_Scope;
- Drefs.Table (Indx).Ent_Scope_File := Get_Source_Unit (Ref_Scope);
+ Deref_Entry.Ent_Scope_File := Get_Code_Unit (N);
+ end;
end if;
end Generate_Dereference;
@@ -1161,6 +1165,14 @@ package body Alfa is
Lu := Proper_Body (Lu);
end if;
+ -- Do not add scopes for generic units
+
+ if Nkind (Lu) = N_Package_Body
+ and then Ekind (Corresponding_Spec (Lu)) in Generic_Unit_Kind
+ then
+ return;
+ end if;
+
-- Call Process on all declarations
if Nkind (Lu) in N_Declaration
@@ -1183,18 +1195,8 @@ package body Alfa is
elsif Nkind (Lu) = N_Package_Body then
Traverse_Package_Body (Lu, Process, Inside_Stubs);
- -- ??? TBD
-
- elsif Nkind (Lu) = N_Generic_Package_Declaration then
- null;
-
- -- ??? TBD
-
- elsif Nkind (Lu) in N_Generic_Instantiation then
- null;
-
-- All other cases of compilation units (e.g. renamings), are not
- -- declarations.
+ -- declarations, or else generic declarations which are ignored.
else
null;
@@ -1233,11 +1235,6 @@ package body Alfa is
when N_Package_Declaration =>
Traverse_Package_Declaration (N, Process, Inside_Stubs);
- -- Generic package declaration ??? TBD
-
- when N_Generic_Package_Declaration =>
- null;
-
-- Package body
when N_Package_Body =>
@@ -1264,11 +1261,6 @@ package body Alfa is
when N_Subprogram_Declaration =>
null;
- -- Generic subprogram declaration ??? TBD
-
- when N_Generic_Subprogram_Declaration =>
- null;
-
-- Subprogram body
when N_Subprogram_Body =>
@@ -1355,6 +1347,8 @@ package body Alfa is
Traverse_Declarations_Or_Statements
(Statements (N), Process, Inside_Stubs);
+ -- Generic declarations are ignored
+
when others =>
null;
end case;
@@ -1429,7 +1423,8 @@ package body Alfa is
procedure Traverse_Subprogram_Body
(N : Node_Id;
Process : Node_Processing;
- Inside_Stubs : Boolean) is
+ Inside_Stubs : Boolean)
+ is
begin
Traverse_Declarations_Or_Statements
(Declarations (N), Process, Inside_Stubs);
diff --git a/gcc/ada/lib-xref.adb b/gcc/ada/lib-xref.adb
index 0e8337f70c6..b6595b336a4 100644
--- a/gcc/ada/lib-xref.adb
+++ b/gcc/ada/lib-xref.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1998-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1998-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -161,6 +161,9 @@ package body Lib.Xref is
-- Local Subprograms --
------------------------
+ procedure Add_Entry (Key : Xref_Key; Ent_Scope_File : Unit_Number_Type);
+ -- Add an entry to the tables of Xref_Entries, avoiding duplicates
+
procedure Generate_Prim_Op_References (Typ : Entity_Id);
-- For a tagged type, generate implicit references to its primitive
-- operations, for source navigation. This is done right before emitting
@@ -170,9 +173,6 @@ package body Lib.Xref is
function Lt (T1, T2 : Xref_Entry) return Boolean;
-- Order cross-references
- procedure Add_Entry (Key : Xref_Key; Ent_Scope_File : Unit_Number_Type);
- -- Add an entry to the tables of Xref_Entries, avoiding duplicates
-
---------------
-- Add_Entry --
---------------
@@ -373,23 +373,16 @@ package body Lib.Xref is
Set_Ref : Boolean := True;
Force : Boolean := False)
is
- Nod : Node_Id;
- Ref : Source_Ptr;
- Def : Source_Ptr;
- Ent : Entity_Id;
-
- Actual_Typ : Character := Typ;
-
- Ref_Scope : Entity_Id;
+ Actual_Typ : Character := Typ;
+ Call : Node_Id;
+ Def : Source_Ptr;
+ Ent : Entity_Id;
Ent_Scope : Entity_Id;
- Ent_Scope_File : Unit_Number_Type;
-
- Call : Node_Id;
- Formal : Entity_Id;
- -- Used for call to Find_Actual
-
- Kind : Entity_Kind;
- -- If Formal is non-Empty, then its Ekind, otherwise E_Void
+ Formal : Entity_Id;
+ Kind : Entity_Kind;
+ Nod : Node_Id;
+ Ref : Source_Ptr;
+ Ref_Scope : Entity_Id;
function Get_Through_Renamings (E : Entity_Id) return Entity_Id;
-- Get the enclosing entity through renamings, which may come from
@@ -639,6 +632,14 @@ package body Lib.Xref is
or else Typ = 'i'
or else Typ = 'k'
or else (Typ = 'b' and then Is_Generic_Instance (E))
+
+ -- Allow the generation of references to reads, writes and calls
+ -- in Alfa mode when the related context comes from an instance.
+
+ or else
+ (Alfa_Mode
+ and then In_Extended_Main_Code_Unit (N)
+ and then (Typ = 'm' or else Typ = 'r' or else Typ = 's'))
then
null;
else
@@ -884,37 +885,31 @@ package body Lib.Xref is
and then Sloc (E) > No_Location
and then Sloc (N) > No_Location
- -- We ignore references from within an instance, except for default
- -- subprograms, for which we generate an implicit reference.
+ -- Ignore references from within an instance. The only exceptions to
+ -- this are default subprograms, for which we generate an implicit
+ -- reference and compilations in Alfa_Mode.
and then
- (Instantiation_Location (Sloc (N)) = No_Location or else Typ = 'i')
+ (Instantiation_Location (Sloc (N)) = No_Location
+ or else Typ = 'i'
+ or else Alfa_Mode)
- -- Ignore dummy references
+ -- Ignore dummy references
and then Typ /= ' '
then
- if Nkind (N) = N_Identifier
- or else
- Nkind (N) = N_Defining_Identifier
- or else
- Nkind (N) in N_Op
- or else
- Nkind (N) = N_Defining_Operator_Symbol
- or else
- Nkind (N) = N_Operator_Symbol
- or else
- (Nkind (N) = N_Character_Literal
- and then Sloc (Entity (N)) /= Standard_Location)
- or else
- Nkind (N) = N_Defining_Character_Literal
+ if Nkind_In (N, N_Identifier,
+ N_Defining_Identifier,
+ N_Defining_Operator_Symbol,
+ N_Operator_Symbol,
+ N_Defining_Character_Literal)
+ or else Nkind (N) in N_Op
+ or else (Nkind (N) = N_Character_Literal
+ and then Sloc (Entity (N)) /= Standard_Location)
then
Nod := N;
- elsif Nkind (N) = N_Expanded_Name
- or else
- Nkind (N) = N_Selected_Component
- then
+ elsif Nkind_In (N, N_Expanded_Name, N_Selected_Component) then
Nod := Selector_Name (N);
else
@@ -999,18 +994,18 @@ package body Lib.Xref is
-- Record reference to entity
- Ref := Original_Location (Sloc (Nod));
- Def := Original_Location (Sloc (Ent));
-
if Actual_Typ = 'p'
- and then Is_Subprogram (N)
- and then Present (Overridden_Operation (N))
+ and then Is_Subprogram (Nod)
+ and then Present (Overridden_Operation (Nod))
then
Actual_Typ := 'P';
end if;
if Alfa_Mode then
- Ref_Scope := Alfa.Enclosing_Subprogram_Or_Package (N);
+ Ref := Sloc (Nod);
+ Def := Sloc (Ent);
+
+ Ref_Scope := Alfa.Enclosing_Subprogram_Or_Package (Nod);
Ent_Scope := Alfa.Enclosing_Subprogram_Or_Package (Ent);
-- Since we are reaching through renamings in Alfa mode, we may
@@ -1022,22 +1017,39 @@ package body Lib.Xref is
return;
end if;
- Ent_Scope_File := Get_Source_Unit (Ent_Scope);
+ Add_Entry
+ ((Ent => Ent,
+ Loc => Ref,
+ Typ => Actual_Typ,
+ Eun => Get_Code_Unit (Def),
+ Lun => Get_Code_Unit (Ref),
+ Ref_Scope => Ref_Scope,
+ Ent_Scope => Ent_Scope),
+ Ent_Scope_File => Get_Code_Unit (Ent));
+
else
- Ref_Scope := Empty;
- Ent_Scope := Empty;
- Ent_Scope_File := No_Unit;
- end if;
+ Ref := Original_Location (Sloc (Nod));
+ Def := Original_Location (Sloc (Ent));
- Add_Entry
- ((Ent => Ent,
- Loc => Ref,
- Typ => Actual_Typ,
- Eun => Get_Source_Unit (Def),
- Lun => Get_Source_Unit (Ref),
- Ref_Scope => Ref_Scope,
- Ent_Scope => Ent_Scope),
- Ent_Scope_File => Ent_Scope_File);
+ -- If this is an operator symbol, skip the initial
+ -- quote, for navigation purposes.
+
+ if Nkind (N) = N_Defining_Operator_Symbol
+ or else Nkind (Nod) = N_Operator_Symbol
+ then
+ Ref := Ref + 1;
+ end if;
+
+ Add_Entry
+ ((Ent => Ent,
+ Loc => Ref,
+ Typ => Actual_Typ,
+ Eun => Get_Source_Unit (Def),
+ Lun => Get_Source_Unit (Ref),
+ Ref_Scope => Empty,
+ Ent_Scope => Empty),
+ Ent_Scope_File => No_Unit);
+ end if;
end if;
end Generate_Reference;
@@ -1715,11 +1727,24 @@ package body Lib.Xref is
-- since at the time the reference or definition is made, private
-- types may be swapped, and the Sloc value may be incorrect. We
-- also set up the pointer vector for the sort.
+ -- For user-defined operators we need to skip the initial
+ -- quote and point to the first character of the name, for
+ -- navigation purposes.
for J in 1 .. Nrefs loop
- Rnums (J) := J;
- Xrefs.Table (J).Def :=
- Original_Location (Sloc (Xrefs.Table (J).Key.Ent));
+ declare
+ E : constant Entity_Id := Xrefs.Table (J).Key.Ent;
+ Loc : constant Source_Ptr := Original_Location (Sloc (E));
+
+ begin
+ Rnums (J) := J;
+
+ if Nkind (E) = N_Defining_Operator_Symbol then
+ Xrefs.Table (J).Def := Loc + 1;
+ else
+ Xrefs.Table (J).Def := Loc;
+ end if;
+ end;
end loop;
-- Sort the references
@@ -2434,6 +2459,8 @@ package body Lib.Xref is
end Output_Refs;
end Output_References;
+-- Start of elaboration for Lib.Xref
+
begin
-- Reset is necessary because Elmt_Ptr does not default to Null_Ptr,
-- because it's not an access type.
diff --git a/gcc/ada/lib-xref.ads b/gcc/ada/lib-xref.ads
index ecac26fabb3..7bdc1582b5e 100644
--- a/gcc/ada/lib-xref.ads
+++ b/gcc/ada/lib-xref.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1998-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1998-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -605,10 +605,13 @@ package Lib.Xref is
(CU : Node_Id;
Process : Node_Processing;
Inside_Stubs : Boolean);
- -- This procedure is undocumented ???
+ -- Call Process on all declarations in compilation unit CU. If
+ -- Inside_Stubs is True, then the body of stubs is also traversed.
+ -- Generic declarations are ignored.
procedure Traverse_All_Compilation_Units (Process : Node_Processing);
- -- Call Process on all declarations through all compilation units
+ -- Call Process on all declarations through all compilation units.
+ -- Generic declarations are ignored.
procedure Collect_Alfa (Sdep_Table : Unit_Ref_Table; Num_Sdep : Nat);
-- Collect Alfa information from library units (for files and scopes)
diff --git a/gcc/ada/opt.ads b/gcc/ada/opt.ads
index a1dc37cf51c..e59e67eb8e8 100644
--- a/gcc/ada/opt.ads
+++ b/gcc/ada/opt.ads
@@ -987,6 +987,11 @@ package Opt is
-- GNATMAKE
-- Set to True when an object directory is specified with option -D
+ Object_Path_File_Name : String_Ptr := null;
+ -- GNAT2WHY
+ -- Path of the temporary file that contains a list of object directories
+ -- passed by -gnateO=<obj_pat_file>.
+
One_Compilation_Per_Obj_Dir : Boolean := False;
-- GNATMAKE, GPRBUILD
-- Set to True with switch --single-compile-per-obj-dir. When True, there
diff --git a/gcc/ada/osint.adb b/gcc/ada/osint.adb
index 8da01c2468a..9a2e7ee26f3 100644
--- a/gcc/ada/osint.adb
+++ b/gcc/ada/osint.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -444,6 +444,15 @@ package body Osint is
-- Start of processing for Add_Default_Search_Dirs
begin
+ -- If there was a -gnateO switch, add all object directories from the
+ -- file given in argument to the library search list.
+
+ if Object_Path_File_Name /= null then
+ Path_File_Name := String_Access (Object_Path_File_Name);
+ pragma Assert (Path_File_Name'Length > 0);
+ Get_Dirs_From_File (Additional_Source_Dir => False);
+ end if;
+
-- After the locations specified on the command line, the next places
-- to look for files are the directories specified by the appropriate
-- environment variable. Get this value, extract the directory names
diff --git a/gcc/ada/osint.ads b/gcc/ada/osint.ads
index a4fc33412e4..48663f519e8 100644
--- a/gcc/ada/osint.ads
+++ b/gcc/ada/osint.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -324,7 +324,8 @@ package Osint is
procedure Add_Default_Search_Dirs;
-- This routine adds the default search dirs indicated by the environment
- -- variables and sdefault package.
+ -- variables and sdefault package, as well as the library search dirs set
+ -- by option -gnateO for GNAT2WHY.
procedure Add_Lib_Search_Dir (Dir : String);
-- Add Dir at the end of the library file search path
diff --git a/gcc/ada/prj-attr.adb b/gcc/ada/prj-attr.adb
index ba569e119e6..8d3d855e789 100644
--- a/gcc/ada/prj-attr.adb
+++ b/gcc/ada/prj-attr.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2001-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2001-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -226,6 +226,7 @@ package body Prj.Attr is
"Lainclude_switches#" &
"Sainclude_path#" &
"Sainclude_path_file#" &
+ "Laobject_path_switches#" &
-- package Builder
diff --git a/gcc/ada/prj-nmsc.adb b/gcc/ada/prj-nmsc.adb
index 284f9f0b6e5..01b39c69d73 100644
--- a/gcc/ada/prj-nmsc.adb
+++ b/gcc/ada/prj-nmsc.adb
@@ -1440,6 +1440,12 @@ package body Prj.Nmsc is
From_List => Element.Value.Values,
In_Tree => Data.Tree);
+ when Name_Object_Path_Switches =>
+ Put (Into_List =>
+ Lang_Index.Config.Object_Path_Switches,
+ From_List => Element.Value.Values,
+ In_Tree => Data.Tree);
+
-- Attribute Compiler_Pic_Option (<language>)
when Name_Pic_Option =>
diff --git a/gcc/ada/prj.adb b/gcc/ada/prj.adb
index c8c5958aad5..9a5e2607aa1 100644
--- a/gcc/ada/prj.adb
+++ b/gcc/ada/prj.adb
@@ -296,7 +296,7 @@ package body Prj is
when Makefile =>
return Extend_Name (Source_File_Name, Makefile_Dependency_Suffix);
- when ALI_File =>
+ when ALI_File | ALI_Closure =>
return Extend_Name (Source_File_Name, ALI_Dependency_Suffix);
end case;
end Dependency_Name;
diff --git a/gcc/ada/prj.ads b/gcc/ada/prj.ads
index 877d1b59b39..a95ac732813 100644
--- a/gcc/ada/prj.ads
+++ b/gcc/ada/prj.ads
@@ -298,9 +298,26 @@ package Prj is
-- Type for the kind of language. All languages are file based, except Ada
-- which is unit based.
- type Dependency_File_Kind is (None, Makefile, ALI_File);
- -- Type of dependency to be checked: no dependency file, Makefile fragment
- -- or ALI file (for Ada).
+ -- Type of dependency to be checked
+
+ type Dependency_File_Kind is
+ (None,
+ -- There is no dependency file, the source must always be recompiled
+
+ Makefile,
+ -- The dependency file is a Makefile fragment indicating all the files
+ -- the source depends on. If the object file or the dependency file is
+ -- more recent than any of these files, the source must be recompiled.
+
+ ALI_File,
+ -- The dependency file is an ALI file and the source must be recompiled
+ -- if the object or ALI file is more recent than any of the sources
+ -- listed in the D lines.
+
+ ALI_Closure);
+ -- The dependency file is an ALI file and the source must be recompiled
+ -- if the object or ALI file is more recent than any source in the full
+ -- closure.
Makefile_Dependency_Suffix : constant String := ".d";
ALI_Dependency_Suffix : constant String := ".ali";
@@ -472,6 +489,11 @@ package Prj is
-- are used to specify the object file. The object file name is appended
-- to the last switch in the list. Example: ("-o", "").
+ Object_Path_Switches : Name_List_Index := No_Name_List;
+ -- List of switches to specify to the compiler the path name of a
+ -- temporary file containing the list of object directories in the
+ -- correct order.
+
Compilation_PIC_Option : Name_List_Index := No_Name_List;
-- The option(s) to compile a source in Position Independent Code for
-- shared libraries. Specified in the configuration. When not specified,
@@ -602,6 +624,7 @@ package Prj is
Source_File_Switches => No_Name_List,
Object_File_Suffix => No_Name,
Object_File_Switches => No_Name_List,
+ Object_Path_Switches => No_Name_List,
Compilation_PIC_Option => No_Name_List,
Object_Generated => True,
Objects_Linked => True,
@@ -1233,6 +1256,10 @@ package Prj is
-- The path name of the exec directory of this project file. Default is
-- equal to Object_Directory.
+ Object_Path_File : Path_Name_Type := No_Path;
+ -- Store the name of the temporary file that contains the list of object
+ -- directories, when attribute Object_Path_Switches is declared.
+
-------------
-- Library --
-------------
diff --git a/gcc/ada/rtsfind.ads b/gcc/ada/rtsfind.ads
index 88e61dc893c..e02f575d7d5 100644
--- a/gcc/ada/rtsfind.ads
+++ b/gcc/ada/rtsfind.ads
@@ -211,6 +211,7 @@ package Rtsfind is
System_Arith_64,
System_AST_Handling,
System_Assertions,
+ System_Atomic_Primitives,
System_Aux_DEC,
System_Bit_Ops,
System_Boolean_Array_Operations,
@@ -730,6 +731,19 @@ package Rtsfind is
RE_Assert_Failure, -- System.Assertions
RE_Raise_Assert_Failure, -- System.Assertions
+ RE_Atomic_Compare_Exchange_8, -- System.Atomic_Primitives
+ RE_Atomic_Compare_Exchange_16, -- System.Atomic_Primitives
+ RE_Atomic_Compare_Exchange_32, -- System.Atomic_Primitives
+ RE_Atomic_Compare_Exchange_64, -- System.Atomic_Primitives
+ RE_Atomic_Load_8, -- System.Atomic_Primitives
+ RE_Atomic_Load_16, -- System.Atomic_Primitives
+ RE_Atomic_Load_32, -- System.Atomic_Primitives
+ RE_Atomic_Load_64, -- System.Atomic_Primitives
+ RE_Uint8, -- System.Atomic_Primitives
+ RE_Uint16, -- System.Atomic_Primitives
+ RE_Uint32, -- System.Atomic_Primitives
+ RE_Uint64, -- System.Atomic_Primitives
+
RE_AST_Handler, -- System.Aux_DEC
RE_Import_Value, -- System.Aux_DEC
RE_No_AST_Handler, -- System.Aux_DEC
@@ -1938,6 +1952,19 @@ package Rtsfind is
RE_Assert_Failure => System_Assertions,
RE_Raise_Assert_Failure => System_Assertions,
+ RE_Atomic_Compare_Exchange_8 => System_Atomic_Primitives,
+ RE_Atomic_Compare_Exchange_16 => System_Atomic_Primitives,
+ RE_Atomic_Compare_Exchange_32 => System_Atomic_Primitives,
+ RE_Atomic_Compare_Exchange_64 => System_Atomic_Primitives,
+ RE_Atomic_Load_8 => System_Atomic_Primitives,
+ RE_Atomic_Load_16 => System_Atomic_Primitives,
+ RE_Atomic_Load_32 => System_Atomic_Primitives,
+ RE_Atomic_Load_64 => System_Atomic_Primitives,
+ RE_Uint8 => System_Atomic_Primitives,
+ RE_Uint16 => System_Atomic_Primitives,
+ RE_Uint32 => System_Atomic_Primitives,
+ RE_Uint64 => System_Atomic_Primitives,
+
RE_AST_Handler => System_Aux_DEC,
RE_Import_Value => System_Aux_DEC,
RE_No_AST_Handler => System_Aux_DEC,
diff --git a/gcc/ada/s-atopri.ads b/gcc/ada/s-atopri.ads
new file mode 100644
index 00000000000..c8c75f2ff72
--- /dev/null
+++ b/gcc/ada/s-atopri.ads
@@ -0,0 +1,122 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . A T O M I C _ P R I M I T I V E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2012, Free Software Foundation, Inc. --
+-- --
+-- GNAT is free software; you can redistribute it and/or modify it under --
+-- terms of the GNU General Public License as published by the Free Soft- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- ??? Need header saying what this unit is!!!
+
+package System.Atomic_Primitives is
+ pragma Preelaborate;
+
+ type uint8 is mod 2**8
+ with Size => 8;
+
+ type uint16 is mod 2**16
+ with Size => 16;
+
+ type uint32 is mod 2**32
+ with Size => 32;
+
+ type uint64 is mod 2**64
+ with Size => 64;
+
+ Relaxed : constant := 0;
+ Consume : constant := 1;
+ Acquire : constant := 2;
+ Release : constant := 3;
+ Acq_Rel : constant := 4;
+ Seq_Cst : constant := 5;
+ Last : constant := 6;
+
+ subtype Mem_Model is Integer range Relaxed .. Last;
+
+ function Atomic_Compare_Exchange_8
+ (X : Address;
+ X_Old : uint8;
+ X_Copy : uint8) return Boolean;
+ pragma Import (Intrinsic,
+ Atomic_Compare_Exchange_8,
+ "__sync_bool_compare_and_swap_1");
+
+ -- ??? Should use __atomic_compare_exchange_1 (doesn't work yet):
+ -- function Atomic_Compare_Exchange_8
+ -- (X : Address;
+ -- X_Old : Address;
+ -- X_Copy : uint8;
+ -- Success_Model : Mem_Model := Seq_Cst;
+ -- Failure_Model : Mem_Model := Seq_Cst) return Boolean;
+ -- pragma Import (Intrinsic,
+ -- Atomic_Compare_Exchange_8,
+ -- "__atomic_compare_exchange_1");
+
+ function Atomic_Compare_Exchange_16
+ (X : Address;
+ X_Old : uint16;
+ X_Copy : uint16) return Boolean;
+ pragma Import (Intrinsic,
+ Atomic_Compare_Exchange_16,
+ "__sync_bool_compare_and_swap_2");
+
+ function Atomic_Compare_Exchange_32
+ (X : Address;
+ X_Old : uint32;
+ X_Copy : uint32) return Boolean;
+ pragma Import (Intrinsic,
+ Atomic_Compare_Exchange_32,
+ "__sync_bool_compare_and_swap_4");
+
+ function Atomic_Compare_Exchange_64
+ (X : Address;
+ X_Old : uint64;
+ X_Copy : uint64) return Boolean;
+ pragma Import (Intrinsic,
+ Atomic_Compare_Exchange_64,
+ "__sync_bool_compare_and_swap_8");
+
+ function Atomic_Load_8
+ (X : Address;
+ Model : Mem_Model := Seq_Cst) return uint8;
+ pragma Import (Intrinsic, Atomic_Load_8, "__atomic_load_1");
+
+ function Atomic_Load_16
+ (X : Address;
+ Model : Mem_Model := Seq_Cst) return uint16;
+ pragma Import (Intrinsic, Atomic_Load_16, "__atomic_load_2");
+
+ function Atomic_Load_32
+ (X : Address;
+ Model : Mem_Model := Seq_Cst) return uint32;
+ pragma Import (Intrinsic, Atomic_Load_32, "__atomic_load_4");
+
+ function Atomic_Load_64
+ (X : Address;
+ Model : Mem_Model := Seq_Cst) return uint64;
+ pragma Import (Intrinsic, Atomic_Load_64, "__atomic_load_8");
+
+end System.Atomic_Primitives;
diff --git a/gcc/ada/sem.adb b/gcc/ada/sem.adb
index 2e50d3dc73b..503d1f40d43 100644
--- a/gcc/ada/sem.adb
+++ b/gcc/ada/sem.adb
@@ -314,6 +314,9 @@ package body Sem is
when N_Label =>
Analyze_Label (N);
+ when N_Loop_Parameter_Specification =>
+ Analyze_Loop_Parameter_Specification (N);
+
when N_Loop_Statement =>
Analyze_Loop_Statement (N);
@@ -681,7 +684,6 @@ package body Sem is
N_Generic_Association |
N_Index_Or_Discriminant_Constraint |
N_Iteration_Scheme |
- N_Loop_Parameter_Specification |
N_Mod_Clause |
N_Modular_Type_Definition |
N_Ordinary_Fixed_Point_Definition |
diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
index 77db15ed21e..10af9e2d054 100644
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -323,7 +323,7 @@ package body Sem_Attr is
-- type or a private type for which no full view has been given.
procedure Check_Object_Reference (P : Node_Id);
- -- Check that P (the prefix of the attribute) is an object reference
+ -- Check that P is an object reference
procedure Check_Program_Unit;
-- Verify that prefix of attribute N is a program unit
@@ -5202,8 +5202,13 @@ package body Sem_Attr is
when Attribute_Valid_Scalars =>
Check_E0;
- Check_Type;
- -- More stuff TBD ???
+ Check_Object_Reference (P);
+
+ if No_Scalar_Parts (P_Type) then
+ Error_Attr_P ("?attribute % always True, no scalars to check");
+ end if;
+
+ Set_Etype (N, Standard_Boolean);
-----------
-- Value --
diff --git a/gcc/ada/sem_attr.ads b/gcc/ada/sem_attr.ads
index 71ac668c757..7258593aabf 100644
--- a/gcc/ada/sem_attr.ads
+++ b/gcc/ada/sem_attr.ads
@@ -554,12 +554,33 @@ package Sem_Attr is
-------------------
Attribute_Valid_Scalars => True,
- -- Obj'Valid_Scalars applies to objects of scalar types, on which it is
- -- equivalent to Obj'Valid, and objects of array and record types, on
- -- which it amounts to applying 'Valid to each subcomponent of Obj. It
- -- does not apply to prefixes of classwide type, or of a formal generic
- -- type that has an unknown discriminant (which could be instantiated
- -- with a classwide type).
+ -- Obj'Valid_Scalars can be applied to any object. The result depends
+ -- on the type of the object:
+ --
+ -- For a scalar type, the result is the same as obj'Valid
+ --
+ -- For an array object, the result is True if the result of applying
+ -- Valid_Scalars to every component is True. For an empty array the
+ -- result is True.
+ --
+ -- For a record object, the result is True if the result of applying
+ -- Valid_Scalars to every component is True. For class-wide types,
+ -- only the components of the base type are checked. For variant
+ -- records, only the components actually present are checked. The
+ -- discriminants, if any, are also checked. If there are no components
+ -- or discriminants, the result is True.
+ --
+ -- For any other type that has discriminants, the result is True if
+ -- the result of applying Valid_Scalars to each discriminant is True.
+ --
+ -- For all other types, the result is always True
+ --
+ -- A warning is given for a trivially True result, when the attribute
+ -- is applied to an object that is not of scalar, array, or record
+ -- type, or in the composite case if no scalar subcomponents exist. For
+ -- a variant record, the warning is given only if none of the variants
+ -- have scalar subcomponents. In addition, the warning is suppressed
+ -- for private types, or generic formal types in an instance.
----------------
-- Value_Size --
diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
index 054772964ef..d0525633681 100644
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -3704,7 +3704,6 @@ package body Sem_Ch12 is
or else Might_Inline_Subp)
and then not Is_Actual_Pack
and then not Inline_Now
- and then not Alfa_Mode
and then (Operating_Mode = Generate_Code
or else (Operating_Mode = Check_Semantics
and then ASIS_Mode));
@@ -4405,9 +4404,6 @@ package body Sem_Ch12 is
Parent_Installed : Boolean := False;
Renaming_List : List_Id;
- Save_Style_Check : constant Boolean := Style_Check;
- -- Save style check mode for restore on exit
-
procedure Analyze_Instance_And_Renamings;
-- The instance must be analyzed in a context that includes the mappings
-- of generic parameters into actuals. We create a package declaration
@@ -4588,11 +4584,13 @@ package body Sem_Ch12 is
Instantiation_Node := N;
- -- Turn off style checking in instances. If the check is enabled on the
- -- generic unit, a warning in an instance would just be noise. If not
- -- enabled on the generic, then a warning in an instance is just wrong.
+ -- For package instantiations we turn off style checks, because they
+ -- will have been emitted in the generic. For subprogram instantiations
+ -- we want to apply at least the check on overriding indicators so we
+ -- do not modify the style check status.
- Style_Check := False;
+ -- The renaming declarations for the actuals do not come from source and
+ -- will not generate spurious warnings.
Preanalyze_Actuals (N);
@@ -4860,8 +4858,6 @@ package body Sem_Ch12 is
Generic_Renamings_HTable.Reset;
end if;
- Style_Check := Save_Style_Check;
-
<<Leave>>
if Has_Aspects (N) then
Analyze_Aspect_Specifications (N, Act_Decl_Id);
@@ -4876,8 +4872,6 @@ package body Sem_Ch12 is
if Env_Installed then
Restore_Env;
end if;
-
- Style_Check := Save_Style_Check;
end Analyze_Subprogram_Instantiation;
-------------------------
@@ -7767,6 +7761,9 @@ package body Sem_Ch12 is
Item : Node_Id;
New_I : Node_Id;
+ Clause : Node_Id;
+ OK : Boolean;
+
begin
if Nkind (Parent (Gen_Decl)) = N_Compilation_Unit then
@@ -7788,17 +7785,30 @@ package body Sem_Ch12 is
while Present (Item) loop
if Nkind (Item) = N_With_Clause then
- -- Take care to prevent direct cyclic with's, which can happen
- -- if the generic body with's the current unit. Such a case
- -- would result in binder errors (or run-time errors if the
- -- -gnatE switch is in effect), but we want to prevent it here,
- -- because Sem.Walk_Library_Items doesn't like cycles. Note
- -- that we don't bother to detect indirect cycles.
+ -- Take care to prevent direct cyclic with's.
if Library_Unit (Item) /= Current_Unit then
- New_I := New_Copy (Item);
- Set_Implicit_With (New_I, True);
- Append (New_I, Current_Context);
+ -- Do not add a unit if it is already in the context
+
+ Clause := First (Current_Context);
+ OK := True;
+ while Present (Clause) loop
+ if Nkind (Clause) = N_With_Clause and then
+ Chars (Name (Clause)) = Chars (Name (Item))
+ then
+ OK := False;
+ exit;
+ end if;
+
+ Next (Clause);
+ end loop;
+
+ if OK then
+ New_I := New_Copy (Item);
+ Set_Implicit_With (New_I, True);
+ Set_Implicit_With_From_Instantiation (New_I, True);
+ Append (New_I, Current_Context);
+ end if;
end if;
end if;
diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb
index d56da36f3fa..55238e2ca11 100644
--- a/gcc/ada/sem_ch4.adb
+++ b/gcc/ada/sem_ch4.adb
@@ -47,7 +47,6 @@ with Sem_Aux; use Sem_Aux;
with Sem_Case; use Sem_Case;
with Sem_Cat; use Sem_Cat;
with Sem_Ch3; use Sem_Ch3;
-with Sem_Ch5; use Sem_Ch5;
with Sem_Ch6; use Sem_Ch6;
with Sem_Ch8; use Sem_Ch8;
with Sem_Dim; use Sem_Dim;
@@ -3403,101 +3402,38 @@ package body Sem_Ch4 is
-----------------------------------
procedure Analyze_Quantified_Expression (N : Node_Id) is
- Loc : constant Source_Ptr := Sloc (N);
- Ent : constant Entity_Id :=
- New_Internal_Entity (E_Loop, Current_Scope, Sloc (N), 'L');
-
- Need_Preanalysis : constant Boolean :=
- Operating_Mode /= Check_Semantics
- and then not Alfa_Mode;
-
- Iterator : Node_Id;
- Original_N : Node_Id;
+ QE_Scop : Entity_Id;
begin
- -- The approach in this procedure is very non-standard and at the
- -- very least, extensive comments are required saying why this very
- -- non-standard approach is needed???
-
- -- Also general comments are needed in any case saying what is going
- -- on here, since tree rewriting of this kind should normally be done
- -- by the expander and not by the analyzer ??? Probably Ent, Iterator,
- -- and Original_N, and Needs_Preanalysis, all need comments above ???
-
- -- Preserve the original node used for the expansion of the quantified
- -- expression.
-
- -- This is a very unusual use of Copy_Separate_Tree, needs looking at???
-
- if Need_Preanalysis then
- Original_N := Copy_Separate_Tree (N);
- end if;
-
- Set_Etype (Ent, Standard_Void_Type);
- Set_Scope (Ent, Current_Scope);
- Set_Parent (Ent, N);
-
Check_SPARK_Restriction ("quantified expression is not allowed", N);
- -- The following seems like expansion activity done at analysis
- -- time, which seems weird ???
+ -- Create a scope to emulate the loop-like behavior of the quantified
+ -- expression. The scope is needed to provide proper visibility of the
+ -- loop variable.
- if Present (Loop_Parameter_Specification (N)) then
- Iterator :=
- Make_Iteration_Scheme (Loc,
- Loop_Parameter_Specification =>
- Loop_Parameter_Specification (N));
- else
- Iterator :=
- Make_Iteration_Scheme (Loc,
- Iterator_Specification =>
- Iterator_Specification (N));
- end if;
+ QE_Scop := New_Internal_Entity (E_Loop, Current_Scope, Sloc (N), 'L');
+ Set_Etype (QE_Scop, Standard_Void_Type);
+ Set_Scope (QE_Scop, Current_Scope);
+ Set_Parent (QE_Scop, N);
- Push_Scope (Ent);
- Set_Parent (Iterator, N);
- Analyze_Iteration_Scheme (Iterator);
+ Push_Scope (QE_Scop);
- -- The loop specification may have been converted into an iterator
- -- specification during its analysis. Update the quantified node
- -- accordingly.
+ -- All constituents are preanalyzed and resolved to avoid untimely
+ -- generation of various temporaries and types. Full analysis and
+ -- expansion is carried out when the quantified expression is
+ -- transformed into an expression with actions.
- if Present (Iterator_Specification (Iterator)) then
- Set_Iterator_Specification
- (N, Iterator_Specification (Iterator));
- Set_Loop_Parameter_Specification (N, Empty);
- Set_Parent (Iterator_Specification (Iterator), Iterator);
- end if;
-
- if Need_Preanalysis then
-
- -- The full analysis will be performed during the expansion of the
- -- quantified expression, only a preanalysis of the condition needs
- -- to be done.
-
- -- This is strange for two reasons
-
- -- First, there is almost no situation in which Preanalyze vs
- -- Analyze should be conditioned on -gnatc mode (since error msgs
- -- must be 100% unaffected by -gnatc). Seconed doing a Preanalyze
- -- with no resolution almost certainly means that some messages are
- -- either missed, or flagged differently in the two cases.
-
- Preanalyze (Condition (N));
+ if Present (Iterator_Specification (N)) then
+ Preanalyze (Iterator_Specification (N));
else
- Analyze (Condition (N));
+ Preanalyze (Loop_Parameter_Specification (N));
end if;
+ Preanalyze_And_Resolve (Condition (N), Standard_Boolean);
+
End_Scope;
Set_Etype (N, Standard_Boolean);
-
- -- Attach the original node to the iteration scheme created above
-
- if Need_Preanalysis then
- Set_Etype (Original_N, Standard_Boolean);
- Set_Parent (Iterator, Original_N);
- end if;
end Analyze_Quantified_Expression;
-------------------
diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
index 834d2f1b143..6feb84cdefa 100644
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -76,7 +76,7 @@ package body Sem_Ch5 is
-- messages. This variable is recursively saved on entry to processing the
-- construct, and restored on exit.
- procedure Pre_Analyze_Range (R_Copy : Node_Id);
+ procedure Preanalyze_Range (R_Copy : Node_Id);
-- Determine expected type of range or domain of iteration of Ada 2012
-- loop by analyzing separate copy. Do the analysis and resolution of the
-- copy of the bound(s) with expansion disabled, to prevent the generation
@@ -1607,615 +1607,32 @@ package body Sem_Ch5 is
------------------------------
procedure Analyze_Iteration_Scheme (N : Node_Id) is
-
- procedure Process_Bounds (R : Node_Id);
- -- If the iteration is given by a range, create temporaries and
- -- assignment statements block to capture the bounds and perform
- -- required finalization actions in case a bound includes a function
- -- call that uses the temporary stack. We first pre-analyze a copy of
- -- the range in order to determine the expected type, and analyze and
- -- resolve the original bounds.
-
- procedure Check_Controlled_Array_Attribute (DS : Node_Id);
- -- If the bounds are given by a 'Range reference on a function call
- -- that returns a controlled array, introduce an explicit declaration
- -- to capture the bounds, so that the function result can be finalized
- -- in timely fashion.
-
- function Has_Call_Using_Secondary_Stack (N : Node_Id) return Boolean;
- -- N is the node for an arbitrary construct. This function searches the
- -- construct N to see if any expressions within it contain function
- -- calls that use the secondary stack, returning True if any such call
- -- is found, and False otherwise.
-
- --------------------
- -- Process_Bounds --
- --------------------
-
- procedure Process_Bounds (R : Node_Id) is
- Loc : constant Source_Ptr := Sloc (N);
- R_Copy : constant Node_Id := New_Copy_Tree (R);
- Lo : constant Node_Id := Low_Bound (R);
- Hi : constant Node_Id := High_Bound (R);
- New_Lo_Bound : Node_Id;
- New_Hi_Bound : Node_Id;
- Typ : Entity_Id;
-
- function One_Bound
- (Original_Bound : Node_Id;
- Analyzed_Bound : Node_Id) return Node_Id;
- -- Capture value of bound and return captured value
-
- ---------------
- -- One_Bound --
- ---------------
-
- function One_Bound
- (Original_Bound : Node_Id;
- Analyzed_Bound : Node_Id) return Node_Id
- is
- Assign : Node_Id;
- Decl : Node_Id;
- Id : Entity_Id;
-
- begin
- -- If the bound is a constant or an object, no need for a separate
- -- declaration. If the bound is the result of previous expansion
- -- it is already analyzed and should not be modified. Note that
- -- the Bound will be resolved later, if needed, as part of the
- -- call to Make_Index (literal bounds may need to be resolved to
- -- type Integer).
-
- if Analyzed (Original_Bound) then
- return Original_Bound;
-
- elsif Nkind_In (Analyzed_Bound, N_Integer_Literal,
- N_Character_Literal)
- or else Is_Entity_Name (Analyzed_Bound)
- then
- Analyze_And_Resolve (Original_Bound, Typ);
- return Original_Bound;
- end if;
-
- -- Normally, the best approach is simply to generate a constant
- -- declaration that captures the bound. However, there is a nasty
- -- case where this is wrong. If the bound is complex, and has a
- -- possible use of the secondary stack, we need to generate a
- -- separate assignment statement to ensure the creation of a block
- -- which will release the secondary stack.
-
- -- We prefer the constant declaration, since it leaves us with a
- -- proper trace of the value, useful in optimizations that get rid
- -- of junk range checks.
-
- if not Has_Call_Using_Secondary_Stack (Analyzed_Bound) then
- Analyze_And_Resolve (Original_Bound, Typ);
- Force_Evaluation (Original_Bound);
- return Original_Bound;
- end if;
-
- Id := Make_Temporary (Loc, 'R', Original_Bound);
-
- -- Here we make a declaration with a separate assignment
- -- statement, and insert before loop header.
-
- Decl :=
- Make_Object_Declaration (Loc,
- Defining_Identifier => Id,
- Object_Definition => New_Occurrence_Of (Typ, Loc));
-
- Assign :=
- Make_Assignment_Statement (Loc,
- Name => New_Occurrence_Of (Id, Loc),
- Expression => Relocate_Node (Original_Bound));
-
- Insert_Actions (Parent (N), New_List (Decl, Assign));
-
- -- Now that this temporary variable is initialized we decorate it
- -- as safe-to-reevaluate to inform to the backend that no further
- -- asignment will be issued and hence it can be handled as side
- -- effect free. Note that this decoration must be done when the
- -- assignment has been analyzed because otherwise it will be
- -- rejected (see Analyze_Assignment).
-
- Set_Is_Safe_To_Reevaluate (Id);
-
- Rewrite (Original_Bound, New_Occurrence_Of (Id, Loc));
-
- if Nkind (Assign) = N_Assignment_Statement then
- return Expression (Assign);
- else
- return Original_Bound;
- end if;
- end One_Bound;
-
- -- Start of processing for Process_Bounds
-
- begin
- Set_Parent (R_Copy, Parent (R));
- Pre_Analyze_Range (R_Copy);
- Typ := Etype (R_Copy);
-
- -- If the type of the discrete range is Universal_Integer, then the
- -- bound's type must be resolved to Integer, and any object used to
- -- hold the bound must also have type Integer, unless the literal
- -- bounds are constant-folded expressions with a user-defined type.
-
- if Typ = Universal_Integer then
- if Nkind (Lo) = N_Integer_Literal
- and then Present (Etype (Lo))
- and then Scope (Etype (Lo)) /= Standard_Standard
- then
- Typ := Etype (Lo);
-
- elsif Nkind (Hi) = N_Integer_Literal
- and then Present (Etype (Hi))
- and then Scope (Etype (Hi)) /= Standard_Standard
- then
- Typ := Etype (Hi);
-
- else
- Typ := Standard_Integer;
- end if;
- end if;
-
- Set_Etype (R, Typ);
-
- New_Lo_Bound := One_Bound (Lo, Low_Bound (R_Copy));
- New_Hi_Bound := One_Bound (Hi, High_Bound (R_Copy));
-
- -- Propagate staticness to loop range itself, in case the
- -- corresponding subtype is static.
-
- if New_Lo_Bound /= Lo
- and then Is_Static_Expression (New_Lo_Bound)
- then
- Rewrite (Low_Bound (R), New_Copy (New_Lo_Bound));
- end if;
-
- if New_Hi_Bound /= Hi
- and then Is_Static_Expression (New_Hi_Bound)
- then
- Rewrite (High_Bound (R), New_Copy (New_Hi_Bound));
- end if;
- end Process_Bounds;
-
- --------------------------------------
- -- Check_Controlled_Array_Attribute --
- --------------------------------------
-
- procedure Check_Controlled_Array_Attribute (DS : Node_Id) is
- begin
- if Nkind (DS) = N_Attribute_Reference
- and then Is_Entity_Name (Prefix (DS))
- and then Ekind (Entity (Prefix (DS))) = E_Function
- and then Is_Array_Type (Etype (Entity (Prefix (DS))))
- and then
- Is_Controlled (
- Component_Type (Etype (Entity (Prefix (DS)))))
- and then Expander_Active
- then
- declare
- Loc : constant Source_Ptr := Sloc (N);
- Arr : constant Entity_Id := Etype (Entity (Prefix (DS)));
- Indx : constant Entity_Id :=
- Base_Type (Etype (First_Index (Arr)));
- Subt : constant Entity_Id := Make_Temporary (Loc, 'S');
- Decl : Node_Id;
-
- begin
- Decl :=
- Make_Subtype_Declaration (Loc,
- Defining_Identifier => Subt,
- Subtype_Indication =>
- Make_Subtype_Indication (Loc,
- Subtype_Mark => New_Reference_To (Indx, Loc),
- Constraint =>
- Make_Range_Constraint (Loc,
- Relocate_Node (DS))));
- Insert_Before (Parent (N), Decl);
- Analyze (Decl);
-
- Rewrite (DS,
- Make_Attribute_Reference (Loc,
- Prefix => New_Reference_To (Subt, Loc),
- Attribute_Name => Attribute_Name (DS)));
- Analyze (DS);
- end;
- end if;
- end Check_Controlled_Array_Attribute;
-
- ------------------------------------
- -- Has_Call_Using_Secondary_Stack --
- ------------------------------------
-
- function Has_Call_Using_Secondary_Stack (N : Node_Id) return Boolean is
-
- function Check_Call (N : Node_Id) return Traverse_Result;
- -- Check if N is a function call which uses the secondary stack
-
- ----------------
- -- Check_Call --
- ----------------
-
- function Check_Call (N : Node_Id) return Traverse_Result is
- Nam : Node_Id;
- Subp : Entity_Id;
- Return_Typ : Entity_Id;
-
- begin
- if Nkind (N) = N_Function_Call then
- Nam := Name (N);
-
- -- Call using access to subprogram with explicit dereference
-
- if Nkind (Nam) = N_Explicit_Dereference then
- Subp := Etype (Nam);
-
- -- Call using a selected component notation or Ada 2005 object
- -- operation notation
-
- elsif Nkind (Nam) = N_Selected_Component then
- Subp := Entity (Selector_Name (Nam));
-
- -- Common case
-
- else
- Subp := Entity (Nam);
- end if;
-
- Return_Typ := Etype (Subp);
-
- if Is_Composite_Type (Return_Typ)
- and then not Is_Constrained (Return_Typ)
- then
- return Abandon;
-
- elsif Sec_Stack_Needed_For_Return (Subp) then
- return Abandon;
- end if;
- end if;
-
- -- Continue traversing the tree
-
- return OK;
- end Check_Call;
-
- function Check_Calls is new Traverse_Func (Check_Call);
-
- -- Start of processing for Has_Call_Using_Secondary_Stack
-
- begin
- return Check_Calls (N) = Abandon;
- end Has_Call_Using_Secondary_Stack;
-
- -- Start of processing for Analyze_Iteration_Scheme
+ Cond : Node_Id;
+ Iter_Spec : Node_Id;
+ Loop_Spec : Node_Id;
begin
- -- If this is a rewritten quantified expression, the iteration scheme
- -- has been analyzed already. Do no repeat analysis because the loop
- -- variable is already declared.
-
- if Analyzed (N) then
- return;
- end if;
-
-- For an infinite loop, there is no iteration scheme
if No (N) then
return;
end if;
- -- Iteration scheme is present
+ Cond := Condition (N);
+ Iter_Spec := Iterator_Specification (N);
+ Loop_Spec := Loop_Parameter_Specification (N);
- declare
- Cond : constant Node_Id := Condition (N);
-
- begin
- -- For WHILE loop, verify that the condition is a Boolean expression
- -- and resolve and check it.
-
- if Present (Cond) then
- Analyze_And_Resolve (Cond, Any_Boolean);
- Check_Unset_Reference (Cond);
- Set_Current_Value_Condition (N);
- return;
-
- -- For an iterator specification with "of", pre-analyze range to
- -- capture function calls that may require finalization actions.
-
- elsif Present (Iterator_Specification (N)) then
- Pre_Analyze_Range (Name (Iterator_Specification (N)));
- Analyze_Iterator_Specification (Iterator_Specification (N));
-
- -- Else we have a FOR loop
-
- else
- declare
- LP : constant Node_Id := Loop_Parameter_Specification (N);
- Id : constant Entity_Id := Defining_Identifier (LP);
- DS : constant Node_Id := Discrete_Subtype_Definition (LP);
-
- D_Copy : Node_Id;
-
- begin
- Enter_Name (Id);
-
- -- We always consider the loop variable to be referenced, since
- -- the loop may be used just for counting purposes.
-
- Generate_Reference (Id, N, ' ');
-
- -- Check for the case of loop variable hiding a local variable
- -- (used later on to give a nice warning if the hidden variable
- -- is never assigned).
-
- declare
- H : constant Entity_Id := Homonym (Id);
- begin
- if Present (H)
- and then Enclosing_Dynamic_Scope (H) =
- Enclosing_Dynamic_Scope (Id)
- and then Ekind (H) = E_Variable
- and then Is_Discrete_Type (Etype (H))
- then
- Set_Hiding_Loop_Variable (H, Id);
- end if;
- end;
-
- -- Loop parameter specification must include subtype mark in
- -- SPARK.
-
- if Nkind (DS) = N_Range then
- Check_SPARK_Restriction
- ("loop parameter specification must include subtype mark",
- N);
- end if;
-
- -- Now analyze the subtype definition. If it is a range, create
- -- temporaries for bounds.
-
- if Nkind (DS) = N_Range
- and then Expander_Active
- then
- Process_Bounds (DS);
-
- -- Expander not active or else range of iteration is a subtype
- -- indication, an entity, or a function call that yields an
- -- aggregate or a container.
-
- else
- D_Copy := New_Copy_Tree (DS);
- Set_Parent (D_Copy, Parent (DS));
- Pre_Analyze_Range (D_Copy);
-
- -- Ada 2012: If the domain of iteration is a function call,
- -- it is the new iterator form.
-
- -- We have also implemented the shorter form : for X in S
- -- for Alfa use. In this case, 'Old and 'Result must be
- -- treated as entity names over which iterators are legal.
-
- if Nkind (D_Copy) = N_Function_Call
- or else
- (Alfa_Mode
- and then (Nkind (D_Copy) = N_Attribute_Reference
- and then
- (Attribute_Name (D_Copy) = Name_Result
- or else Attribute_Name (D_Copy) = Name_Old)))
- or else
- (Is_Entity_Name (D_Copy)
- and then not Is_Type (Entity (D_Copy)))
- then
- -- This is an iterator specification. Rewrite as such
- -- and analyze, to capture function calls that may
- -- require finalization actions.
-
- declare
- I_Spec : constant Node_Id :=
- Make_Iterator_Specification (Sloc (LP),
- Defining_Identifier =>
- Relocate_Node (Id),
- Name => D_Copy,
- Subtype_Indication => Empty,
- Reverse_Present =>
- Reverse_Present (LP));
- begin
- Set_Iterator_Specification (N, I_Spec);
- Set_Loop_Parameter_Specification (N, Empty);
- Analyze_Iterator_Specification (I_Spec);
-
- -- In a generic context, analyze the original domain
- -- of iteration, for name capture.
-
- if not Expander_Active then
- Analyze (DS);
- end if;
-
- -- Set kind of loop parameter, which may be used in
- -- the subsequent analysis of the condition in a
- -- quantified expression.
-
- Set_Ekind (Id, E_Loop_Parameter);
- return;
- end;
-
- -- Domain of iteration is not a function call, and is
- -- side-effect free.
-
- else
- Analyze (DS);
- end if;
- end if;
-
- if DS = Error then
- return;
- end if;
-
- -- Some additional checks if we are iterating through a type
-
- if Is_Entity_Name (DS)
- and then Present (Entity (DS))
- and then Is_Type (Entity (DS))
- then
- -- The subtype indication may denote the completion of an
- -- incomplete type declaration.
-
- if Ekind (Entity (DS)) = E_Incomplete_Type then
- Set_Entity (DS, Get_Full_View (Entity (DS)));
- Set_Etype (DS, Entity (DS));
- end if;
-
- -- Attempt to iterate through non-static predicate
-
- if Is_Discrete_Type (Entity (DS))
- and then Present (Predicate_Function (Entity (DS)))
- and then No (Static_Predicate (Entity (DS)))
- then
- Bad_Predicated_Subtype_Use
- ("cannot use subtype& with non-static "
- & "predicate for loop iteration", DS, Entity (DS));
- end if;
- end if;
-
- -- Error if not discrete type
-
- if not Is_Discrete_Type (Etype (DS)) then
- Wrong_Type (DS, Any_Discrete);
- Set_Etype (DS, Any_Type);
- end if;
-
- Check_Controlled_Array_Attribute (DS);
-
- -- The index is not processed during analysis of a quantified
- -- expression but delayed to its expansion where the quantified
- -- expression is transformed into an expression with actions.
-
- if Nkind (Parent (N)) /= N_Quantified_Expression
- or else Operating_Mode = Check_Semantics
- or else Alfa_Mode
- then
- Make_Index (DS, LP, In_Iter_Schm => True);
- end if;
-
- Set_Ekind (Id, E_Loop_Parameter);
-
- -- If the loop is part of a predicate or precondition, it may
- -- be analyzed twice, once in the source and once on the copy
- -- used to check conformance. Preserve the original itype
- -- because the second one may be created in a different scope,
- -- e.g. a precondition procedure, leading to a crash in GIGI.
-
- if No (Etype (Id)) or else Etype (Id) = Any_Type then
- Set_Etype (Id, Etype (DS));
- end if;
-
- -- Treat a range as an implicit reference to the type, to
- -- inhibit spurious warnings.
-
- Generate_Reference (Base_Type (Etype (DS)), N, ' ');
- Set_Is_Known_Valid (Id, True);
-
- -- The loop is not a declarative part, so the only entity
- -- declared "within" must be frozen explicitly.
-
- declare
- Flist : constant List_Id := Freeze_Entity (Id, N);
- begin
- if Is_Non_Empty_List (Flist) then
- Insert_Actions (N, Flist);
- end if;
- end;
-
- -- Check for null or possibly null range and issue warning. We
- -- suppress such messages in generic templates and instances,
- -- because in practice they tend to be dubious in these cases.
-
- if Nkind (DS) = N_Range and then Comes_From_Source (N) then
- declare
- L : constant Node_Id := Low_Bound (DS);
- H : constant Node_Id := High_Bound (DS);
-
- begin
- -- If range of loop is null, issue warning
-
- if Compile_Time_Compare
- (L, H, Assume_Valid => True) = GT
- then
- -- Suppress the warning if inside a generic template
- -- or instance, since in practice they tend to be
- -- dubious in these cases since they can result from
- -- intended parametrization.
-
- if not Inside_A_Generic
- and then not In_Instance
- then
- -- Specialize msg if invalid values could make the
- -- loop non-null after all.
-
- if Compile_Time_Compare
- (L, H, Assume_Valid => False) = GT
- then
- Error_Msg_N
- ("?loop range is null, loop will not execute",
- DS);
-
- -- Since we know the range of the loop is null,
- -- set the appropriate flag to remove the loop
- -- entirely during expansion.
-
- Set_Is_Null_Loop (Parent (N));
-
- -- Here is where the loop could execute because
- -- of invalid values, so issue appropriate
- -- message and in this case we do not set the
- -- Is_Null_Loop flag since the loop may execute.
-
- else
- Error_Msg_N
- ("?loop range may be null, "
- & "loop may not execute",
- DS);
- Error_Msg_N
- ("?can only execute if invalid values "
- & "are present",
- DS);
- end if;
- end if;
-
- -- In either case, suppress warnings in the body of
- -- the loop, since it is likely that these warnings
- -- will be inappropriate if the loop never actually
- -- executes, which is likely.
-
- Set_Suppress_Loop_Warnings (Parent (N));
-
- -- The other case for a warning is a reverse loop
- -- where the upper bound is the integer literal zero
- -- or one, and the lower bound can be positive.
-
- -- For example, we have
-
- -- for J in reverse N .. 1 loop
+ if Present (Cond) then
+ Analyze_And_Resolve (Cond, Any_Boolean);
+ Check_Unset_Reference (Cond);
+ Set_Current_Value_Condition (N);
- -- In practice, this is very likely to be a case of
- -- reversing the bounds incorrectly in the range.
+ elsif Present (Iter_Spec) then
+ Analyze_Iterator_Specification (Iter_Spec);
- elsif Reverse_Present (LP)
- and then Nkind (Original_Node (H)) =
- N_Integer_Literal
- and then (Intval (Original_Node (H)) = Uint_0
- or else
- Intval (Original_Node (H)) = Uint_1)
- then
- Error_Msg_N ("?loop range may be null", DS);
- Error_Msg_N ("\?bounds may be wrong way round", DS);
- end if;
- end;
- end if;
- end;
- end if;
- end;
+ else
+ Analyze_Loop_Parameter_Specification (Loop_Spec);
+ end if;
end Analyze_Iteration_Scheme;
------------------------------------
@@ -2233,22 +1650,25 @@ package body Sem_Ch5 is
begin
Enter_Name (Def_Id);
-
Set_Ekind (Def_Id, E_Variable);
if Present (Subt) then
Analyze (Subt);
end if;
- -- If domain of iteration is an expression, create a declaration for
+ Preanalyze_Range (Iter_Name);
+
+ -- If the domain of iteration is an expression, create a declaration for
-- it, so that finalization actions are introduced outside of the loop.
-- The declaration must be a renaming because the body of the loop may
- -- assign to elements. In case of a quantified expression, this
- -- declaration is delayed to its expansion where the node is rewritten
- -- as an expression with actions.
+ -- assign to elements. When the context is a quantified expression, the
+ -- renaming declaration is delayed until the expansion phase.
if not Is_Entity_Name (Iter_Name)
- and then (Nkind (Parent (Parent (N))) /= N_Quantified_Expression
+ and then (Nkind (Parent (N)) /= N_Quantified_Expression
+
+ -- The following two tests need comments ???
+
or else Operating_Mode = Check_Semantics
or else Alfa_Mode)
then
@@ -2442,6 +1862,571 @@ package body Sem_Ch5 is
Set_Reachable (E, True);
end Analyze_Label_Entity;
+ ------------------------------------------
+ -- Analyze_Loop_Parameter_Specification --
+ ------------------------------------------
+
+ procedure Analyze_Loop_Parameter_Specification (N : Node_Id) is
+ Loop_Nod : constant Node_Id := Parent (Parent (N));
+
+ procedure Check_Controlled_Array_Attribute (DS : Node_Id);
+ -- If the bounds are given by a 'Range reference on a function call
+ -- that returns a controlled array, introduce an explicit declaration
+ -- to capture the bounds, so that the function result can be finalized
+ -- in timely fashion.
+
+ function Has_Call_Using_Secondary_Stack (N : Node_Id) return Boolean;
+ -- N is the node for an arbitrary construct. This function searches the
+ -- construct N to see if any expressions within it contain function
+ -- calls that use the secondary stack, returning True if any such call
+ -- is found, and False otherwise.
+
+ procedure Process_Bounds (R : Node_Id);
+ -- If the iteration is given by a range, create temporaries and
+ -- assignment statements block to capture the bounds and perform
+ -- required finalization actions in case a bound includes a function
+ -- call that uses the temporary stack. We first pre-analyze a copy of
+ -- the range in order to determine the expected type, and analyze and
+ -- resolve the original bounds.
+
+ --------------------------------------
+ -- Check_Controlled_Array_Attribute --
+ --------------------------------------
+
+ procedure Check_Controlled_Array_Attribute (DS : Node_Id) is
+ begin
+ if Nkind (DS) = N_Attribute_Reference
+ and then Is_Entity_Name (Prefix (DS))
+ and then Ekind (Entity (Prefix (DS))) = E_Function
+ and then Is_Array_Type (Etype (Entity (Prefix (DS))))
+ and then
+ Is_Controlled (Component_Type (Etype (Entity (Prefix (DS)))))
+ and then Expander_Active
+ then
+ declare
+ Loc : constant Source_Ptr := Sloc (N);
+ Arr : constant Entity_Id := Etype (Entity (Prefix (DS)));
+ Indx : constant Entity_Id :=
+ Base_Type (Etype (First_Index (Arr)));
+ Subt : constant Entity_Id := Make_Temporary (Loc, 'S');
+ Decl : Node_Id;
+
+ begin
+ Decl :=
+ Make_Subtype_Declaration (Loc,
+ Defining_Identifier => Subt,
+ Subtype_Indication =>
+ Make_Subtype_Indication (Loc,
+ Subtype_Mark => New_Reference_To (Indx, Loc),
+ Constraint =>
+ Make_Range_Constraint (Loc, Relocate_Node (DS))));
+ Insert_Before (Loop_Nod, Decl);
+ Analyze (Decl);
+
+ Rewrite (DS,
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Reference_To (Subt, Loc),
+ Attribute_Name => Attribute_Name (DS)));
+
+ Analyze (DS);
+ end;
+ end if;
+ end Check_Controlled_Array_Attribute;
+
+ ------------------------------------
+ -- Has_Call_Using_Secondary_Stack --
+ ------------------------------------
+
+ function Has_Call_Using_Secondary_Stack (N : Node_Id) return Boolean is
+
+ function Check_Call (N : Node_Id) return Traverse_Result;
+ -- Check if N is a function call which uses the secondary stack
+
+ ----------------
+ -- Check_Call --
+ ----------------
+
+ function Check_Call (N : Node_Id) return Traverse_Result is
+ Nam : Node_Id;
+ Subp : Entity_Id;
+ Return_Typ : Entity_Id;
+
+ begin
+ if Nkind (N) = N_Function_Call then
+ Nam := Name (N);
+
+ -- Call using access to subprogram with explicit dereference
+
+ if Nkind (Nam) = N_Explicit_Dereference then
+ Subp := Etype (Nam);
+
+ -- Call using a selected component notation or Ada 2005 object
+ -- operation notation
+
+ elsif Nkind (Nam) = N_Selected_Component then
+ Subp := Entity (Selector_Name (Nam));
+
+ -- Common case
+
+ else
+ Subp := Entity (Nam);
+ end if;
+
+ Return_Typ := Etype (Subp);
+
+ if Is_Composite_Type (Return_Typ)
+ and then not Is_Constrained (Return_Typ)
+ then
+ return Abandon;
+
+ elsif Sec_Stack_Needed_For_Return (Subp) then
+ return Abandon;
+ end if;
+ end if;
+
+ -- Continue traversing the tree
+
+ return OK;
+ end Check_Call;
+
+ function Check_Calls is new Traverse_Func (Check_Call);
+
+ -- Start of processing for Has_Call_Using_Secondary_Stack
+
+ begin
+ return Check_Calls (N) = Abandon;
+ end Has_Call_Using_Secondary_Stack;
+
+ --------------------
+ -- Process_Bounds --
+ --------------------
+
+ procedure Process_Bounds (R : Node_Id) is
+ Loc : constant Source_Ptr := Sloc (N);
+
+ function One_Bound
+ (Original_Bound : Node_Id;
+ Analyzed_Bound : Node_Id;
+ Typ : Entity_Id) return Node_Id;
+ -- Capture value of bound and return captured value
+
+ ---------------
+ -- One_Bound --
+ ---------------
+
+ function One_Bound
+ (Original_Bound : Node_Id;
+ Analyzed_Bound : Node_Id;
+ Typ : Entity_Id) return Node_Id
+ is
+ Assign : Node_Id;
+ Decl : Node_Id;
+ Id : Entity_Id;
+
+ begin
+ -- If the bound is a constant or an object, no need for a separate
+ -- declaration. If the bound is the result of previous expansion
+ -- it is already analyzed and should not be modified. Note that
+ -- the Bound will be resolved later, if needed, as part of the
+ -- call to Make_Index (literal bounds may need to be resolved to
+ -- type Integer).
+
+ if Analyzed (Original_Bound) then
+ return Original_Bound;
+
+ elsif Nkind_In (Analyzed_Bound, N_Integer_Literal,
+ N_Character_Literal)
+ or else Is_Entity_Name (Analyzed_Bound)
+ then
+ Analyze_And_Resolve (Original_Bound, Typ);
+ return Original_Bound;
+ end if;
+
+ -- Normally, the best approach is simply to generate a constant
+ -- declaration that captures the bound. However, there is a nasty
+ -- case where this is wrong. If the bound is complex, and has a
+ -- possible use of the secondary stack, we need to generate a
+ -- separate assignment statement to ensure the creation of a block
+ -- which will release the secondary stack.
+
+ -- We prefer the constant declaration, since it leaves us with a
+ -- proper trace of the value, useful in optimizations that get rid
+ -- of junk range checks.
+
+ if not Has_Call_Using_Secondary_Stack (Analyzed_Bound) then
+ Analyze_And_Resolve (Original_Bound, Typ);
+ Force_Evaluation (Original_Bound);
+ return Original_Bound;
+ end if;
+
+ Id := Make_Temporary (Loc, 'R', Original_Bound);
+
+ -- Here we make a declaration with a separate assignment
+ -- statement, and insert before loop header.
+
+ Decl :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Id,
+ Object_Definition => New_Occurrence_Of (Typ, Loc));
+
+ Assign :=
+ Make_Assignment_Statement (Loc,
+ Name => New_Occurrence_Of (Id, Loc),
+ Expression => Relocate_Node (Original_Bound));
+
+ Insert_Actions (Loop_Nod, New_List (Decl, Assign));
+
+ -- Now that this temporary variable is initialized we decorate it
+ -- as safe-to-reevaluate to inform to the backend that no further
+ -- asignment will be issued and hence it can be handled as side
+ -- effect free. Note that this decoration must be done when the
+ -- assignment has been analyzed because otherwise it will be
+ -- rejected (see Analyze_Assignment).
+
+ Set_Is_Safe_To_Reevaluate (Id);
+
+ Rewrite (Original_Bound, New_Occurrence_Of (Id, Loc));
+
+ if Nkind (Assign) = N_Assignment_Statement then
+ return Expression (Assign);
+ else
+ return Original_Bound;
+ end if;
+ end One_Bound;
+
+ Hi : constant Node_Id := High_Bound (R);
+ Lo : constant Node_Id := Low_Bound (R);
+ R_Copy : constant Node_Id := New_Copy_Tree (R);
+ New_Hi : Node_Id;
+ New_Lo : Node_Id;
+ Typ : Entity_Id;
+
+ -- Start of processing for Process_Bounds
+
+ begin
+ Set_Parent (R_Copy, Parent (R));
+ Preanalyze_Range (R_Copy);
+ Typ := Etype (R_Copy);
+
+ -- If the type of the discrete range is Universal_Integer, then the
+ -- bound's type must be resolved to Integer, and any object used to
+ -- hold the bound must also have type Integer, unless the literal
+ -- bounds are constant-folded expressions with a user-defined type.
+
+ if Typ = Universal_Integer then
+ if Nkind (Lo) = N_Integer_Literal
+ and then Present (Etype (Lo))
+ and then Scope (Etype (Lo)) /= Standard_Standard
+ then
+ Typ := Etype (Lo);
+
+ elsif Nkind (Hi) = N_Integer_Literal
+ and then Present (Etype (Hi))
+ and then Scope (Etype (Hi)) /= Standard_Standard
+ then
+ Typ := Etype (Hi);
+
+ else
+ Typ := Standard_Integer;
+ end if;
+ end if;
+
+ Set_Etype (R, Typ);
+
+ New_Lo := One_Bound (Lo, Low_Bound (R_Copy), Typ);
+ New_Hi := One_Bound (Hi, High_Bound (R_Copy), Typ);
+
+ -- Propagate staticness to loop range itself, in case the
+ -- corresponding subtype is static.
+
+ if New_Lo /= Lo
+ and then Is_Static_Expression (New_Lo)
+ then
+ Rewrite (Low_Bound (R), New_Copy (New_Lo));
+ end if;
+
+ if New_Hi /= Hi
+ and then Is_Static_Expression (New_Hi)
+ then
+ Rewrite (High_Bound (R), New_Copy (New_Hi));
+ end if;
+ end Process_Bounds;
+
+ -- Local variables
+
+ DS : constant Node_Id := Discrete_Subtype_Definition (N);
+ Id : constant Entity_Id := Defining_Identifier (N);
+
+ DS_Copy : Node_Id;
+
+ -- Start of processing for Analyze_Loop_Parameter_Specification
+
+ begin
+ Enter_Name (Id);
+
+ -- We always consider the loop variable to be referenced, since the loop
+ -- may be used just for counting purposes.
+
+ Generate_Reference (Id, N, ' ');
+
+ -- Check for the case of loop variable hiding a local variable (used
+ -- later on to give a nice warning if the hidden variable is never
+ -- assigned).
+
+ declare
+ H : constant Entity_Id := Homonym (Id);
+ begin
+ if Present (H)
+ and then Ekind (H) = E_Variable
+ and then Is_Discrete_Type (Etype (H))
+ and then Enclosing_Dynamic_Scope (H) = Enclosing_Dynamic_Scope (Id)
+ then
+ Set_Hiding_Loop_Variable (H, Id);
+ end if;
+ end;
+
+ -- Loop parameter specification must include subtype mark in SPARK
+
+ if Nkind (DS) = N_Range then
+ Check_SPARK_Restriction
+ ("loop parameter specification must include subtype mark", N);
+ end if;
+
+ -- Analyze the subtype definition and create temporaries for the bounds.
+ -- Do not evaluate the range when preanalyzing a quantified expression
+ -- because bounds expressed as function calls with side effects will be
+ -- erroneously replicated.
+
+ if Nkind (DS) = N_Range
+ and then Expander_Active
+ and then Nkind (Parent (N)) /= N_Quantified_Expression
+ then
+ Process_Bounds (DS);
+
+ -- Either the expander not active or the range of iteration is a subtype
+ -- indication, an entity, or a function call that yields an aggregate or
+ -- a container.
+
+ else
+ DS_Copy := New_Copy_Tree (DS);
+ Set_Parent (DS_Copy, Parent (DS));
+ Preanalyze_Range (DS_Copy);
+
+ -- Ada 2012: If the domain of iteration is a function call, it is the
+ -- new iterator form.
+
+ -- We have also implemented the shorter form : for X in S for Alfa
+ -- use. In this case, 'Old and 'Result must be treated as entity
+ -- names over which iterators are legal.
+
+ if Nkind (DS_Copy) = N_Function_Call
+ or else
+ (Alfa_Mode
+ and then (Nkind (DS_Copy) = N_Attribute_Reference
+ and then
+ (Attribute_Name (DS_Copy) = Name_Result
+ or else Attribute_Name (DS_Copy) = Name_Old)))
+ or else
+ (Is_Entity_Name (DS_Copy)
+ and then not Is_Type (Entity (DS_Copy)))
+ then
+ -- This is an iterator specification. Rewrite it as such and
+ -- analyze it to capture function calls that may require
+ -- finalization actions.
+
+ declare
+ I_Spec : constant Node_Id :=
+ Make_Iterator_Specification (Sloc (N),
+ Defining_Identifier => Relocate_Node (Id),
+ Name => DS_Copy,
+ Subtype_Indication => Empty,
+ Reverse_Present => Reverse_Present (N));
+ Scheme : constant Node_Id := Parent (N);
+
+ begin
+ Set_Iterator_Specification (Scheme, I_Spec);
+ Set_Loop_Parameter_Specification (Scheme, Empty);
+ Analyze_Iterator_Specification (I_Spec);
+
+ -- In a generic context, analyze the original domain of
+ -- iteration, for name capture.
+
+ if not Expander_Active then
+ Analyze (DS);
+ end if;
+
+ -- Set kind of loop parameter, which may be used in the
+ -- subsequent analysis of the condition in a quantified
+ -- expression.
+
+ Set_Ekind (Id, E_Loop_Parameter);
+ return;
+ end;
+
+ -- Domain of iteration is not a function call, and is side-effect
+ -- free.
+
+ else
+ Analyze (DS);
+ end if;
+ end if;
+
+ if DS = Error then
+ return;
+ end if;
+
+ -- Some additional checks if we are iterating through a type
+
+ if Is_Entity_Name (DS)
+ and then Present (Entity (DS))
+ and then Is_Type (Entity (DS))
+ then
+ -- The subtype indication may denote the completion of an incomplete
+ -- type declaration.
+
+ if Ekind (Entity (DS)) = E_Incomplete_Type then
+ Set_Entity (DS, Get_Full_View (Entity (DS)));
+ Set_Etype (DS, Entity (DS));
+ end if;
+
+ -- Attempt to iterate through non-static predicate
+
+ if Is_Discrete_Type (Entity (DS))
+ and then Present (Predicate_Function (Entity (DS)))
+ and then No (Static_Predicate (Entity (DS)))
+ then
+ Bad_Predicated_Subtype_Use
+ ("cannot use subtype& with non-static predicate for loop " &
+ "iteration", DS, Entity (DS));
+ end if;
+ end if;
+
+ -- Error if not discrete type
+
+ if not Is_Discrete_Type (Etype (DS)) then
+ Wrong_Type (DS, Any_Discrete);
+ Set_Etype (DS, Any_Type);
+ end if;
+
+ Check_Controlled_Array_Attribute (DS);
+
+ Make_Index (DS, N, In_Iter_Schm => True);
+ Set_Ekind (Id, E_Loop_Parameter);
+
+ -- A quantified expression which appears in a pre- or post-condition may
+ -- be analyzed multiple times. The analysis of the range creates several
+ -- itypes which reside in different scopes depending on whether the pre-
+ -- or post-condition has been expanded. Update the type of the loop
+ -- variable to reflect the proper itype at each stage of analysis.
+
+ if No (Etype (Id))
+ or else Etype (Id) = Any_Type
+ or else
+ (Present (Etype (Id))
+ and then Is_Itype (Etype (Id))
+ and then Nkind (Parent (Loop_Nod)) = N_Expression_With_Actions
+ and then Nkind (Original_Node (Parent (Loop_Nod))) =
+ N_Quantified_Expression)
+ then
+ Set_Etype (Id, Etype (DS));
+ end if;
+
+ -- Treat a range as an implicit reference to the type, to inhibit
+ -- spurious warnings.
+
+ Generate_Reference (Base_Type (Etype (DS)), N, ' ');
+ Set_Is_Known_Valid (Id, True);
+
+ -- The loop is not a declarative part, so the only entity declared
+ -- "within" must be frozen explicitly.
+
+ declare
+ Flist : constant List_Id := Freeze_Entity (Id, N);
+ begin
+ if Is_Non_Empty_List (Flist) then
+ Insert_Actions (N, Flist);
+ end if;
+ end;
+
+ -- Check for null or possibly null range and issue warning. We suppress
+ -- such messages in generic templates and instances, because in practice
+ -- they tend to be dubious in these cases.
+
+ if Nkind (DS) = N_Range and then Comes_From_Source (N) then
+ declare
+ L : constant Node_Id := Low_Bound (DS);
+ H : constant Node_Id := High_Bound (DS);
+
+ begin
+ -- If range of loop is null, issue warning
+
+ if Compile_Time_Compare (L, H, Assume_Valid => True) = GT then
+
+ -- Suppress the warning if inside a generic template or
+ -- instance, since in practice they tend to be dubious in these
+ -- cases since they can result from intended parametrization.
+
+ if not Inside_A_Generic
+ and then not In_Instance
+ then
+ -- Specialize msg if invalid values could make the loop
+ -- non-null after all.
+
+ if Compile_Time_Compare
+ (L, H, Assume_Valid => False) = GT
+ then
+ Error_Msg_N
+ ("?loop range is null, loop will not execute", DS);
+
+ -- Since we know the range of the loop is null, set the
+ -- appropriate flag to remove the loop entirely during
+ -- expansion.
+
+ Set_Is_Null_Loop (Loop_Nod);
+
+ -- Here is where the loop could execute because of invalid
+ -- values, so issue appropriate message and in this case we
+ -- do not set the Is_Null_Loop flag since the loop may
+ -- execute.
+
+ else
+ Error_Msg_N
+ ("?loop range may be null, loop may not execute", DS);
+ Error_Msg_N
+ ("?can only execute if invalid values are present", DS);
+ end if;
+ end if;
+
+ -- In either case, suppress warnings in the body of the loop,
+ -- since it is likely that these warnings will be inappropriate
+ -- if the loop never actually executes, which is likely.
+
+ Set_Suppress_Loop_Warnings (Loop_Nod);
+
+ -- The other case for a warning is a reverse loop where the
+ -- upper bound is the integer literal zero or one, and the
+ -- lower bound can be positive.
+
+ -- For example, we have
+
+ -- for J in reverse N .. 1 loop
+
+ -- In practice, this is very likely to be a case of reversing
+ -- the bounds incorrectly in the range.
+
+ elsif Reverse_Present (N)
+ and then Nkind (Original_Node (H)) = N_Integer_Literal
+ and then
+ (Intval (Original_Node (H)) = Uint_0
+ or else Intval (Original_Node (H)) = Uint_1)
+ then
+ Error_Msg_N ("?loop range may be null", DS);
+ Error_Msg_N ("\?bounds may be wrong way round", DS);
+ end if;
+ end;
+ end if;
+ end Analyze_Loop_Parameter_Specification;
+
----------------------------
-- Analyze_Loop_Statement --
----------------------------
@@ -2482,7 +2467,7 @@ package body Sem_Ch5 is
begin
Nam_Copy := New_Copy_Tree (Nam);
Set_Parent (Nam_Copy, Parent (Nam));
- Pre_Analyze_Range (Nam_Copy);
+ Preanalyze_Range (Nam_Copy);
-- The only two options here are iteration over a container or
-- an array.
@@ -2501,7 +2486,7 @@ package body Sem_Ch5 is
begin
DS_Copy := New_Copy_Tree (DS);
Set_Parent (DS_Copy, Parent (DS));
- Pre_Analyze_Range (DS_Copy);
+ Preanalyze_Range (DS_Copy);
-- Check for a call to Iterate ()
@@ -2907,11 +2892,11 @@ package body Sem_Ch5 is
end if;
end Check_Unreachable_Code;
- -----------------------
- -- Pre_Analyze_Range --
- -----------------------
+ ----------------------
+ -- Preanalyze_Range --
+ ----------------------
- procedure Pre_Analyze_Range (R_Copy : Node_Id) is
+ procedure Preanalyze_Range (R_Copy : Node_Id) is
Save_Analysis : constant Boolean := Full_Analysis;
begin
@@ -2977,6 +2962,6 @@ package body Sem_Ch5 is
Expander_Mode_Restore;
Full_Analysis := Save_Analysis;
- end Pre_Analyze_Range;
+ end Preanalyze_Range;
end Sem_Ch5;
diff --git a/gcc/ada/sem_ch5.ads b/gcc/ada/sem_ch5.ads
index fdf09db32d5..86a92b76c5e 100644
--- a/gcc/ada/sem_ch5.ads
+++ b/gcc/ada/sem_ch5.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -27,19 +27,20 @@ with Types; use Types;
package Sem_Ch5 is
- procedure Analyze_Assignment (N : Node_Id);
- procedure Analyze_Block_Statement (N : Node_Id);
- procedure Analyze_Case_Statement (N : Node_Id);
- procedure Analyze_Exit_Statement (N : Node_Id);
- procedure Analyze_Goto_Statement (N : Node_Id);
- procedure Analyze_If_Statement (N : Node_Id);
- procedure Analyze_Implicit_Label_Declaration (N : Node_Id);
- procedure Analyze_Iterator_Specification (N : Node_Id);
- procedure Analyze_Iteration_Scheme (N : Node_Id);
- procedure Analyze_Label (N : Node_Id);
- procedure Analyze_Loop_Statement (N : Node_Id);
- procedure Analyze_Null_Statement (N : Node_Id);
- procedure Analyze_Statements (L : List_Id);
+ procedure Analyze_Assignment (N : Node_Id);
+ procedure Analyze_Block_Statement (N : Node_Id);
+ procedure Analyze_Case_Statement (N : Node_Id);
+ procedure Analyze_Exit_Statement (N : Node_Id);
+ procedure Analyze_Goto_Statement (N : Node_Id);
+ procedure Analyze_If_Statement (N : Node_Id);
+ procedure Analyze_Implicit_Label_Declaration (N : Node_Id);
+ procedure Analyze_Iterator_Specification (N : Node_Id);
+ procedure Analyze_Iteration_Scheme (N : Node_Id);
+ procedure Analyze_Label (N : Node_Id);
+ procedure Analyze_Loop_Parameter_Specification (N : Node_Id);
+ procedure Analyze_Loop_Statement (N : Node_Id);
+ procedure Analyze_Null_Statement (N : Node_Id);
+ procedure Analyze_Statements (L : List_Id);
procedure Analyze_Label_Entity (E : Entity_Id);
-- This procedure performs direct analysis of the label entity E. It
diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
index 8ec60c7abb3..4c7f2e47224 100644
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -8702,7 +8702,9 @@ package body Sem_Ch6 is
Discrete_Subtype_Definition (L2));
end;
- else -- quantified expression with an iterator
+ elsif Present (Iterator_Specification (E1))
+ and then Present (Iterator_Specification (E2))
+ then
declare
I1 : constant Node_Id := Iterator_Specification (E1);
I2 : constant Node_Id := Iterator_Specification (E2);
@@ -8719,6 +8721,12 @@ package body Sem_Ch6 is
and then FCE (Subtype_Indication (I1),
Subtype_Indication (I2));
end;
+
+ -- The quantified expressions used different specifications to
+ -- walk their respective ranges.
+
+ else
+ return False;
end if;
when N_Range =>
@@ -11057,6 +11065,9 @@ package body Sem_Ch6 is
-- that an invariant check is required (for an IN OUT parameter, or
-- the returned value of a function.
+ function Last_Implicit_Declaration return Node_Id;
+ -- Return the last internally-generated declaration of N
+
-------------
-- Grab_CC --
-------------
@@ -11307,6 +11318,50 @@ package body Sem_Ch6 is
end if;
end Is_Public_Subprogram_For;
+ -------------------------------
+ -- Last_Implicit_Declaration --
+ -------------------------------
+
+ function Last_Implicit_Declaration return Node_Id is
+ Loc : constant Source_Ptr := Sloc (N);
+ Decls : List_Id := Declarations (N);
+ Decl : Node_Id;
+ Succ : Node_Id;
+
+ begin
+ if No (Decls) then
+ Decls := New_List (Make_Null_Statement (Loc));
+ Set_Declarations (N, Decls);
+
+ elsif Is_Empty_List (Declarations (N)) then
+ Append_To (Decls, Make_Null_Statement (Loc));
+ end if;
+
+ -- Implicit and source declarations may be interspersed. Search for
+ -- the last implicit declaration which is either succeeded by a
+ -- source construct or is the last node in the declarative list.
+
+ Decl := First (Declarations (N));
+ while Present (Decl) loop
+ Succ := Next (Decl);
+
+ -- The current declaration is the last one, do not return Empty
+
+ if No (Succ) then
+ exit;
+
+ -- The successor is a source construct
+
+ elsif Comes_From_Source (Succ) then
+ exit;
+ end if;
+
+ Next (Decl);
+ end loop;
+
+ return Decl;
+ end Last_Implicit_Declaration;
+
-- Start of processing for Process_PPCs
begin
@@ -11712,7 +11767,7 @@ package body Sem_Ch6 is
-- The entity for the _Postconditions procedure
begin
- Prepend_To (Declarations (N),
+ Insert_After (Last_Implicit_Declaration,
Make_Subprogram_Body (Loc,
Specification =>
Make_Procedure_Specification (Loc,
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index 46a8b194853..ef5f8b4ed50 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -193,7 +193,6 @@ package body Sem_Res is
procedure Resolve_Op_Expon (N : Node_Id; Typ : Entity_Id);
procedure Resolve_Op_Not (N : Node_Id; Typ : Entity_Id);
procedure Resolve_Qualified_Expression (N : Node_Id; Typ : Entity_Id);
- procedure Resolve_Quantified_Expression (N : Node_Id; Typ : Entity_Id);
procedure Resolve_Range (N : Node_Id; Typ : Entity_Id);
procedure Resolve_Real_Literal (N : Node_Id; Typ : Entity_Id);
procedure Resolve_Reference (N : Node_Id; Typ : Entity_Id);
@@ -1770,6 +1769,10 @@ package body Sem_Res is
-- Try and fix up a literal so that it matches its expected type. New
-- literals are manufactured if necessary to avoid cascaded errors.
+ function Proper_Current_Scope return Entity_Id;
+ -- Return the current scope. Skip loop scopes created for the purpose of
+ -- quantified expression analysis since those do not appear in the tree.
+
procedure Report_Ambiguous_Argument;
-- Additional diagnostics when an ambiguous call has an ambiguous
-- argument (typically a controlling actual).
@@ -1832,6 +1835,30 @@ package body Sem_Res is
end if;
end Patch_Up_Value;
+ --------------------------
+ -- Proper_Current_Scope --
+ --------------------------
+
+ function Proper_Current_Scope return Entity_Id is
+ S : Entity_Id := Current_Scope;
+
+ begin
+ while Present (S) loop
+
+ -- Skip a loop scope created for quantified expression analysis
+
+ if Ekind (S) = E_Loop
+ and then Nkind (Parent (S)) = N_Quantified_Expression
+ then
+ S := Scope (S);
+ else
+ exit;
+ end if;
+ end loop;
+
+ return S;
+ end Proper_Current_Scope;
+
-------------------------------
-- Report_Ambiguous_Argument --
-------------------------------
@@ -2597,10 +2624,10 @@ package body Sem_Res is
-- an error. We can't do this earlier, because it would cause legal
-- cases to get errors (when some other type has an abstract "+").
- if Ada_Version >= Ada_2005 and then
- Nkind (N) in N_Op and then
- Is_Overloaded (N) and then
- Is_Universal_Numeric_Type (Etype (Entity (N)))
+ if Ada_Version >= Ada_2005
+ and then Nkind (N) in N_Op
+ and then Is_Overloaded (N)
+ and then Is_Universal_Numeric_Type (Etype (Entity (N)))
then
Get_First_Interp (N, I, It);
while Present (It.Typ) loop
@@ -2761,8 +2788,7 @@ package body Sem_Res is
when N_Qualified_Expression
=> Resolve_Qualified_Expression (N, Ctx_Type);
- when N_Quantified_Expression
- => Resolve_Quantified_Expression (N, Ctx_Type);
+ when N_Quantified_Expression => null;
when N_Raise_xxx_Error
=> Set_Etype (N, Ctx_Type);
@@ -2857,10 +2883,9 @@ package body Sem_Res is
-- Ada 2012 (AI05-177): Expression functions do not freeze. Only
-- their use (in an expanded call) freezes.
- if Ekind (Current_Scope) /= E_Function
- or else
- Nkind (Original_Node (Unit_Declaration_Node (Current_Scope))) /=
- N_Expression_Function
+ if Ekind (Proper_Current_Scope) /= E_Function
+ or else Nkind (Original_Node (Unit_Declaration_Node
+ (Proper_Current_Scope))) /= N_Expression_Function
then
Freeze_Expression (N);
end if;
@@ -5316,7 +5341,18 @@ package body Sem_Res is
-- needs extending because we can generate procedure calls that need
-- freezing.
- if Is_Entity_Name (Subp) and then not In_Spec_Expression then
+ -- In Ada 2012, expression functions may be called within pre/post
+ -- conditions of subsequent functions or expression functions. Such
+ -- calls do not freeze when they appear within generated bodies, which
+ -- would place the freeze node in the wrong scope. An expression
+ -- function is frozen in the usual fashion, by the appearance of a real
+ -- body, or at the end of a declarative part.
+
+ if Is_Entity_Name (Subp) and then not In_Spec_Expression
+ and then
+ (not Is_Expression_Function (Entity (Subp))
+ or else Scope (Entity (Subp)) = Current_Scope)
+ then
Freeze_Expression (Subp);
end if;
@@ -6082,15 +6118,36 @@ package body Sem_Res is
Condition : constant Node_Id := First (Expressions (N));
Then_Expr : constant Node_Id := Next (Condition);
Else_Expr : Node_Id := Next (Then_Expr);
+ Else_Typ : Entity_Id;
+ Then_Typ : Entity_Id;
begin
Resolve (Condition, Any_Boolean);
Resolve (Then_Expr, Typ);
+ Then_Typ := Etype (Then_Expr);
+
+ -- When the "then" and "else" expressions are of a scalar type, insert
+ -- a conversion to ensure the generation of a constraint check.
+
+ if Is_Scalar_Type (Then_Typ)
+ and then Then_Typ /= Typ
+ then
+ Rewrite (Then_Expr, Convert_To (Typ, Then_Expr));
+ Analyze_And_Resolve (Then_Expr, Typ);
+ end if;
-- If ELSE expression present, just resolve using the determined type
if Present (Else_Expr) then
Resolve (Else_Expr, Typ);
+ Else_Typ := Etype (Else_Expr);
+
+ if Is_Scalar_Type (Else_Typ)
+ and then Else_Typ /= Typ
+ then
+ Rewrite (Else_Expr, Convert_To (Typ, Else_Expr));
+ Analyze_And_Resolve (Else_Expr, Typ);
+ end if;
-- If no ELSE expression is present, root type must be Standard.Boolean
-- and we provide a Standard.True result converted to the appropriate
@@ -8279,31 +8336,6 @@ package body Sem_Res is
Eval_Qualified_Expression (N);
end Resolve_Qualified_Expression;
- -----------------------------------
- -- Resolve_Quantified_Expression --
- -----------------------------------
-
- procedure Resolve_Quantified_Expression (N : Node_Id; Typ : Entity_Id) is
- begin
- if not Alfa_Mode then
-
- -- The loop structure is already resolved during its analysis, only
- -- the resolution of the condition needs to be done. Expansion is
- -- disabled so that checks and other generated code are inserted in
- -- the tree after expression has been rewritten as a loop.
-
- Expander_Mode_Save_And_Set (False);
- Resolve (Condition (N), Typ);
- Expander_Mode_Restore;
-
- -- In Alfa mode, we need normal expansion in order to properly introduce
- -- the necessary transient scopes.
-
- else
- Resolve (Condition (N), Typ);
- end if;
- end Resolve_Quantified_Expression;
-
-------------------
-- Resolve_Range --
-------------------
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index 6519221cbe6..b5255177b2c 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -742,11 +742,25 @@ package body Sem_Util is
Loc : constant Source_Ptr := Sloc (N);
Disc : Entity_Id;
+ Bas : Entity_Id;
+ -- The base type that is to be constrained by the defaults
+
begin
if not Has_Discriminants (T) or else Is_Constrained (T) then
return T;
end if;
+ Bas := Base_Type (T);
+
+ -- If T is non-private but its base type is private, this is the
+ -- completion of a subtype declaration whose parent type is private
+ -- (see Complete_Private_Subtype in Sem_Ch3). The proper discriminants
+ -- are to be found in the full view of the base.
+
+ if Is_Private_Type (Bas) and then Present (Full_View (Bas)) then
+ Bas := Full_View (Bas);
+ end if;
+
Disc := First_Discriminant (T);
if No (Discriminant_Default_Value (Disc)) then
@@ -768,10 +782,10 @@ package body Sem_Util is
Decl :=
Make_Subtype_Declaration (Loc,
Defining_Identifier => Act,
- Subtype_Indication =>
+ Subtype_Indication =>
Make_Subtype_Indication (Loc,
- Subtype_Mark => New_Occurrence_Of (T, Loc),
- Constraint =>
+ Subtype_Mark => New_Occurrence_Of (Bas, Loc),
+ Constraint =>
Make_Index_Or_Discriminant_Constraint (Loc,
Constraints => Constraints)));
@@ -798,8 +812,8 @@ package body Sem_Util is
-- of the prefix.
function Build_Discriminal_Record_Constraint return List_Id;
- -- Similar to previous one, for discriminated components constrained
- -- by the discriminant of the enclosing object.
+ -- Similar to previous one, for discriminated components constrained by
+ -- the discriminant of the enclosing object.
----------------------------------------
-- Build_Discriminal_Array_Constraint --
@@ -955,12 +969,7 @@ package body Sem_Util is
-- and thus will not have the unit name automatically prepended.
Set_Package_Name (Spec_Id);
-
- -- Append _E
-
- Name_Buffer (Name_Len + 1) := '_';
- Name_Buffer (Name_Len + 2) := 'E';
- Name_Len := Name_Len + 2;
+ Add_Str_To_Name_Buffer ("_E");
-- Create elaboration counter
@@ -986,9 +995,9 @@ package body Sem_Util is
Set_Current_Value (Elab_Ent, Empty);
Set_Last_Assignment (Elab_Ent, Empty);
- -- We do not want any further qualification of the name (if we did
- -- not do this, we would pick up the name of the generic package
- -- in the case of a library level generic instantiation).
+ -- We do not want any further qualification of the name (if we did not
+ -- do this, we would pick up the name of the generic package in the case
+ -- of a library level generic instantiation).
Set_Has_Qualified_Name (Elab_Ent);
Set_Has_Fully_Qualified_Name (Elab_Ent);
@@ -1073,8 +1082,7 @@ package body Sem_Util is
then
return False;
else
- return
- Cannot_Raise_Constraint_Error (Expression (Expr));
+ return Cannot_Raise_Constraint_Error (Expression (Expr));
end if;
when N_Unchecked_Type_Conversion =>
@@ -1084,8 +1092,7 @@ package body Sem_Util is
if Do_Overflow_Check (Expr) then
return False;
else
- return
- Cannot_Raise_Constraint_Error (Right_Opnd (Expr));
+ return Cannot_Raise_Constraint_Error (Right_Opnd (Expr));
end if;
when N_Op_Divide |
@@ -1142,8 +1149,7 @@ package body Sem_Util is
-- Check_Implicit_Dereference --
--------------------------------
- procedure Check_Implicit_Dereference (Nam : Node_Id; Typ : Entity_Id)
- is
+ procedure Check_Implicit_Dereference (Nam : Node_Id; Typ : Entity_Id) is
Disc : Entity_Id;
Desig : Entity_Id;
@@ -8674,7 +8680,6 @@ package body Sem_Util is
-- only affects the generation of internal expanded code, since
-- calls to instantiations of Unchecked_Conversion are never
-- considered variables (since they are function calls).
- -- This is also true for expression actions.
when N_Unchecked_Type_Conversion =>
return Is_Variable (Expression (Orig_Node));
@@ -10500,6 +10505,34 @@ package body Sem_Util is
Actual_Id := Next_Actual (Actual_Id);
end Next_Actual;
+ ---------------------
+ -- No_Scalar_Parts --
+ ---------------------
+
+ function No_Scalar_Parts (T : Entity_Id) return Boolean is
+ C : Entity_Id;
+
+ begin
+ if Is_Scalar_Type (T) then
+ return False;
+
+ elsif Is_Array_Type (T) then
+ return No_Scalar_Parts (Component_Type (T));
+
+ elsif Is_Record_Type (T) or else Has_Discriminants (T) then
+ C := First_Component_Or_Discriminant (T);
+ while Present (C) loop
+ if not No_Scalar_Parts (Etype (C)) then
+ return False;
+ else
+ Next_Component_Or_Discriminant (C);
+ end if;
+ end loop;
+ end if;
+
+ return True;
+ end No_Scalar_Parts;
+
-----------------------
-- Normalize_Actuals --
-----------------------
diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads
index 34d2fc0383c..607bd8e72e0 100644
--- a/gcc/ada/sem_util.ads
+++ b/gcc/ada/sem_util.ads
@@ -1221,6 +1221,11 @@ package Sem_Util is
-- Note that the result produced is always an expression, not a parameter
-- association node, even if named notation was used.
+ function No_Scalar_Parts (T : Entity_Id) return Boolean;
+ -- Tests if type T can be determined at compile time to have no scalar
+ -- parts in the sense of the Valid_Scalars attribute. Returns True if
+ -- this is the case, meaning that the result of Valid_Scalars is True.
+
procedure Normalize_Actuals
(N : Node_Id;
S : Entity_Id;
diff --git a/gcc/ada/sinfo.adb b/gcc/ada/sinfo.adb
index a8388b19344..a89f9b26269 100644
--- a/gcc/ada/sinfo.adb
+++ b/gcc/ada/sinfo.adb
@@ -1624,6 +1624,14 @@ package body Sinfo is
return Flag16 (N);
end Implicit_With;
+ function Implicit_With_From_Instantiation
+ (N : Node_Id) return Boolean is
+ begin
+ pragma Assert (False
+ or else NT (N).Nkind = N_With_Clause);
+ return Flag12 (N);
+ end Implicit_With_From_Instantiation;
+
function Interface_List
(N : Node_Id) return List_Id is
begin
@@ -4704,6 +4712,14 @@ package body Sinfo is
Set_Flag16 (N, Val);
end Set_Implicit_With;
+ procedure Set_Implicit_With_From_Instantiation
+ (N : Node_Id; Val : Boolean := True) is
+ begin
+ pragma Assert (False
+ or else NT (N).Nkind = N_With_Clause);
+ Set_Flag12 (N, Val);
+ end Set_Implicit_With_From_Instantiation;
+
procedure Set_Interface_List
(N : Node_Id; Val : List_Id) is
begin
diff --git a/gcc/ada/sinfo.ads b/gcc/ada/sinfo.ads
index 0972d9c1603..fa7dbee35aa 100644
--- a/gcc/ada/sinfo.ads
+++ b/gcc/ada/sinfo.ads
@@ -1226,6 +1226,9 @@ package Sinfo is
-- 'Address or 'Tag attribute. ???There are other implicit with clauses
-- as well.
+ -- Implicit_With_From_Instantiation (Flag12-Sem)
+ -- Set in N_With_Clause nodes from generic instantiations.
+
-- Import_Interface_Present (Flag16-Sem)
-- This flag is set in an Interface or Import pragma if a matching
-- pragma of the other kind is also present. This is used to avoid
@@ -1252,7 +1255,7 @@ package Sinfo is
-- to the node for the spec of the instance, inserted as part of the
-- semantic processing for instantiations in Sem_Ch12.
- -- Is_Accessibility_Actual (Flag12-Sem)
+ -- Is_Accessibility_Actual (Flag13-Sem)
-- Present in N_Parameter_Association nodes. True if the parameter is
-- an extra actual that carries the accessibility level of the actual
-- for an access parameter, in a function that dispatches on result and
@@ -5805,6 +5808,7 @@ package Sinfo is
-- Elaborate_Desirable (Flag11-Sem)
-- Private_Present (Flag15) set if with_clause has private keyword
-- Implicit_With (Flag16-Sem)
+ -- Implicit_With_From_Instantiation (Flag12-Sem)
-- Limited_Present (Flag17) set if LIMITED is present
-- Limited_View_Installed (Flag18-Sem)
-- Unreferenced_In_Spec (Flag7-Sem)
@@ -8592,6 +8596,9 @@ package Sinfo is
function Implicit_With
(N : Node_Id) return Boolean; -- Flag16
+ function Implicit_With_From_Instantiation
+ (N : Node_Id) return Boolean; -- Flag12
+
function Import_Interface_Present
(N : Node_Id) return Boolean; -- Flag16
@@ -9573,6 +9580,9 @@ package Sinfo is
procedure Set_Implicit_With
(N : Node_Id; Val : Boolean := True); -- Flag16
+ procedure Set_Implicit_With_From_Instantiation
+ (N : Node_Id; Val : Boolean := True); -- Flag12
+
procedure Set_Import_Interface_Present
(N : Node_Id; Val : Boolean := True); -- Flag16
@@ -11959,6 +11969,7 @@ package Sinfo is
pragma Inline (High_Bound);
pragma Inline (Identifier);
pragma Inline (Implicit_With);
+ pragma Inline (Implicit_With_From_Instantiation);
pragma Inline (Interface_List);
pragma Inline (Interface_Present);
pragma Inline (Includes_Infinities);
diff --git a/gcc/ada/snames.ads-tmpl b/gcc/ada/snames.ads-tmpl
index ed30b9b5aac..c85fdd01d19 100644
--- a/gcc/ada/snames.ads-tmpl
+++ b/gcc/ada/snames.ads-tmpl
@@ -1199,6 +1199,7 @@ package Snames is
Name_Object_File_Switches : constant Name_Id := N + $;
Name_Object_Generated : constant Name_Id := N + $;
Name_Object_List : constant Name_Id := N + $;
+ Name_Object_Path_Switches : constant Name_Id := N + $;
Name_Objects_Linked : constant Name_Id := N + $;
Name_Objects_Path : constant Name_Id := N + $;
Name_Objects_Path_File : constant Name_Id := N + $;
diff --git a/gcc/ada/style.adb b/gcc/ada/style.adb
index 727a0cdf452..b60370231b1 100644
--- a/gcc/ada/style.adb
+++ b/gcc/ada/style.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -236,7 +236,13 @@ package body Style is
procedure Missing_Overriding (N : Node_Id; E : Entity_Id) is
begin
- if Style_Check_Missing_Overriding and then Comes_From_Source (N) then
+
+ -- Perform the check on source subprograms and on subprogram instances,
+ -- because these can be primitives of untagged types.
+
+ if Style_Check_Missing_Overriding
+ and then (Comes_From_Source (N) or else Is_Generic_Instance (E))
+ then
if Nkind (N) = N_Subprogram_Body then
Error_Msg_NE -- CODEFIX
("(style) missing OVERRIDING indicator in body of&", N, E);
diff --git a/gcc/ada/switch-c.adb b/gcc/ada/switch-c.adb
index 789fb9b5b4d..7cb0ee06a65 100644
--- a/gcc/ada/switch-c.adb
+++ b/gcc/ada/switch-c.adb
@@ -516,6 +516,24 @@ package body Switch.C is
new String'(Switch_Chars (Ptr .. Max));
return;
+ -- -gnateO= (object path file)
+
+ when 'O' =>
+ Store_Switch := False;
+ Ptr := Ptr + 1;
+
+ -- Check for '='
+
+ if Ptr >= Max or else Switch_Chars (Ptr) /= '=' then
+ Bad_Switch ("-gnateO");
+
+ else
+ Object_Path_File_Name :=
+ new String'(Switch_Chars (Ptr + 1 .. Max));
+ end if;
+
+ return;
+
-- -gnatep (preprocessing data file)
when 'p' =>
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index fb17bad9d05..f8cdea0085d 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -830,9 +830,6 @@ extern bool inside_basic_block_p (const_rtx);
extern bool control_flow_insn_p (const_rtx);
extern rtx get_last_bb_insn (basic_block);
-/* In bb-reorder.c */
-extern void reorder_basic_blocks (void);
-
/* In dominance.c */
enum cdi_direction
diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c
index a35b8e62942..c7f9c920d76 100644
--- a/gcc/bb-reorder.c
+++ b/gcc/bb-reorder.c
@@ -1903,7 +1903,7 @@ verify_hot_cold_block_grouping (void)
/* Reorder basic blocks. The main entry point to this file. FLAGS is
the set of flags to pass to cfg_layout_initialize(). */
-void
+static void
reorder_basic_blocks (void)
{
int n_traces;
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c
index 1dca79a70cf..bc1b7a2f582 100644
--- a/gcc/cfghooks.c
+++ b/gcc/cfghooks.c
@@ -1009,18 +1009,28 @@ duplicate_block (basic_block bb, edge e, basic_block after)
{
struct loop *cloop = bb->loop_father;
struct loop *copy = get_loop_copy (cloop);
- add_bb_to_loop (new_bb, copy ? copy : cloop);
- /* If we copied the loop latch block but not the loop, adjust
- loop state.
- ??? If we copied the loop header block but not the loop
- we might either have created a loop copy or a loop with
- multiple entries. In both cases we probably have to
- ditch the loops and arrange for a fixup. */
+ /* If we copied the loop header block but not the loop
+ we have created a loop with multiple entries. Ditch the loop,
+ add the new block to the outer loop and arrange for a fixup. */
if (!copy
- && cloop->latch == bb)
+ && cloop->header == bb)
{
+ add_bb_to_loop (new_bb, loop_outer (cloop));
+ cloop->header = NULL;
cloop->latch = NULL;
- loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
+ loops_state_set (LOOPS_NEED_FIXUP);
+ }
+ else
+ {
+ add_bb_to_loop (new_bb, copy ? copy : cloop);
+ /* If we copied the loop latch block but not the loop, adjust
+ loop state. */
+ if (!copy
+ && cloop->latch == bb)
+ {
+ cloop->latch = NULL;
+ loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
+ }
}
}
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 93efd94d9ba..726285989fc 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -613,13 +613,11 @@ struct cgraph_2edge_hook_list *cgraph_add_edge_duplication_hook (cgraph_2edge_ho
void cgraph_remove_edge_duplication_hook (struct cgraph_2edge_hook_list *);
struct cgraph_2node_hook_list *cgraph_add_node_duplication_hook (cgraph_2node_hook, void *);
void cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *);
-void cgraph_materialize_all_clones (void);
gimple cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *);
bool cgraph_propagate_frequency (struct cgraph_node *node);
/* In cgraphbuild.c */
unsigned int rebuild_cgraph_edges (void);
void cgraph_rebuild_references (void);
-void reset_inline_failed (struct cgraph_node *);
int compute_call_stmt_bb_frequency (tree, basic_block bb);
/* In ipa.c */
diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c
index 8bf88300593..d7ef7f9d99d 100644
--- a/gcc/cgraphbuild.c
+++ b/gcc/cgraphbuild.c
@@ -200,20 +200,6 @@ record_eh_tables (struct cgraph_node *node, struct function *fun)
}
}
-/* Reset inlining information of all incoming call edges of NODE. */
-
-void
-reset_inline_failed (struct cgraph_node *node)
-{
- struct cgraph_edge *e;
-
- for (e = node->callers; e; e = e->next_caller)
- {
- e->callee->global.inlined_to = NULL;
- initialize_inline_failed (e);
- }
-}
-
/* Computes the frequency of the call statement so that it can be stored in
cgraph_edge. BB is the basic block of the call statement. */
int
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 516f187fedd..9e5820fc901 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1294,59 +1294,6 @@ handle_alias_pairs (void)
}
-/* Analyze the whole compilation unit once it is parsed completely. */
-
-void
-cgraph_finalize_compilation_unit (void)
-{
- timevar_push (TV_CGRAPH);
-
- /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
- if (flag_lto)
- lto_streamer_hooks_init ();
-
- /* If we're here there's no current function anymore. Some frontends
- are lazy in clearing these. */
- current_function_decl = NULL;
- set_cfun (NULL);
-
- /* Do not skip analyzing the functions if there were errors, we
- miss diagnostics for following functions otherwise. */
-
- /* Emit size functions we didn't inline. */
- finalize_size_functions ();
-
- /* Mark alias targets necessary and emit diagnostics. */
- finish_aliases_1 ();
- handle_alias_pairs ();
-
- if (!quiet_flag)
- {
- fprintf (stderr, "\nAnalyzing compilation unit\n");
- fflush (stderr);
- }
-
- if (flag_dump_passes)
- dump_passes ();
-
- /* Gimplify and lower all functions, compute reachability and
- remove unreachable nodes. */
- cgraph_analyze_functions ();
-
- /* Mark alias targets necessary and emit diagnostics. */
- finish_aliases_1 ();
- handle_alias_pairs ();
-
- /* Gimplify and lower thunks. */
- cgraph_analyze_functions ();
-
- /* Finally drive the pass manager. */
- cgraph_optimize ();
-
- timevar_pop (TV_CGRAPH);
-}
-
-
/* Figure out what functions we want to assemble. */
static void
@@ -2134,124 +2081,6 @@ output_weakrefs (void)
}
-/* Perform simple optimizations based on callgraph. */
-
-void
-cgraph_optimize (void)
-{
- if (seen_error ())
- return;
-
-#ifdef ENABLE_CHECKING
- verify_cgraph ();
-#endif
-
- /* Frontend may output common variables after the unit has been finalized.
- It is safe to deal with them here as they are always zero initialized. */
- varpool_analyze_pending_decls ();
-
- timevar_push (TV_CGRAPHOPT);
- if (pre_ipa_mem_report)
- {
- fprintf (stderr, "Memory consumption before IPA\n");
- dump_memory_report (false);
- }
- if (!quiet_flag)
- fprintf (stderr, "Performing interprocedural optimizations\n");
- cgraph_state = CGRAPH_STATE_IPA;
-
- /* Don't run the IPA passes if there was any error or sorry messages. */
- if (!seen_error ())
- ipa_passes ();
-
- /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
- if (seen_error ()
- || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
- {
- timevar_pop (TV_CGRAPHOPT);
- return;
- }
-
- /* This pass remove bodies of extern inline functions we never inlined.
- Do this later so other IPA passes see what is really going on. */
- cgraph_remove_unreachable_nodes (false, dump_file);
- cgraph_global_info_ready = true;
- if (cgraph_dump_file)
- {
- fprintf (cgraph_dump_file, "Optimized ");
- dump_cgraph (cgraph_dump_file);
- dump_varpool (cgraph_dump_file);
- }
- if (post_ipa_mem_report)
- {
- fprintf (stderr, "Memory consumption after IPA\n");
- dump_memory_report (false);
- }
- timevar_pop (TV_CGRAPHOPT);
-
- /* Output everything. */
- (*debug_hooks->assembly_start) ();
- if (!quiet_flag)
- fprintf (stderr, "Assembling functions:\n");
-#ifdef ENABLE_CHECKING
- verify_cgraph ();
-#endif
-
- cgraph_materialize_all_clones ();
- bitmap_obstack_initialize (NULL);
- execute_ipa_pass_list (all_late_ipa_passes);
- cgraph_remove_unreachable_nodes (true, dump_file);
-#ifdef ENABLE_CHECKING
- verify_cgraph ();
-#endif
- bitmap_obstack_release (NULL);
- cgraph_mark_functions_to_output ();
- output_weakrefs ();
-
- cgraph_state = CGRAPH_STATE_EXPANSION;
- if (!flag_toplevel_reorder)
- cgraph_output_in_order ();
- else
- {
- cgraph_output_pending_asms ();
-
- cgraph_expand_all_functions ();
- varpool_remove_unreferenced_decls ();
-
- varpool_assemble_pending_decls ();
- }
-
- cgraph_process_new_functions ();
- cgraph_state = CGRAPH_STATE_FINISHED;
-
- if (cgraph_dump_file)
- {
- fprintf (cgraph_dump_file, "\nFinal ");
- dump_cgraph (cgraph_dump_file);
- dump_varpool (cgraph_dump_file);
- }
-#ifdef ENABLE_CHECKING
- verify_cgraph ();
- /* Double check that all inline clones are gone and that all
- function bodies have been released from memory. */
- if (!seen_error ())
- {
- struct cgraph_node *node;
- bool error_found = false;
-
- for (node = cgraph_nodes; node; node = node->next)
- if (node->analyzed
- && (node->global.inlined_to
- || gimple_has_body_p (node->decl)))
- {
- error_found = true;
- dump_cgraph_node (stderr, node);
- }
- if (error_found)
- internal_error ("nodes with unreleased memory found");
- }
-#endif
-}
void
init_cgraph (void)
@@ -2549,7 +2378,7 @@ cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
bring all functions to memory prior compilation, but current WHOPR
implementation does that and it is is bit easier to keep everything right in
this order. */
-void
+static void
cgraph_materialize_all_clones (void)
{
struct cgraph_node *node;
@@ -2628,4 +2457,178 @@ cgraph_materialize_all_clones (void)
cgraph_remove_unreachable_nodes (false, cgraph_dump_file);
}
+
+/* Perform simple optimizations based on callgraph. */
+
+void
+cgraph_optimize (void)
+{
+ if (seen_error ())
+ return;
+
+#ifdef ENABLE_CHECKING
+ verify_cgraph ();
+#endif
+
+ /* Frontend may output common variables after the unit has been finalized.
+ It is safe to deal with them here as they are always zero initialized. */
+ varpool_analyze_pending_decls ();
+
+ timevar_push (TV_CGRAPHOPT);
+ if (pre_ipa_mem_report)
+ {
+ fprintf (stderr, "Memory consumption before IPA\n");
+ dump_memory_report (false);
+ }
+ if (!quiet_flag)
+ fprintf (stderr, "Performing interprocedural optimizations\n");
+ cgraph_state = CGRAPH_STATE_IPA;
+
+ /* Don't run the IPA passes if there was any error or sorry messages. */
+ if (!seen_error ())
+ ipa_passes ();
+
+ /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
+ if (seen_error ()
+ || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
+ {
+ timevar_pop (TV_CGRAPHOPT);
+ return;
+ }
+
+ /* This pass remove bodies of extern inline functions we never inlined.
+ Do this later so other IPA passes see what is really going on. */
+ cgraph_remove_unreachable_nodes (false, dump_file);
+ cgraph_global_info_ready = true;
+ if (cgraph_dump_file)
+ {
+ fprintf (cgraph_dump_file, "Optimized ");
+ dump_cgraph (cgraph_dump_file);
+ dump_varpool (cgraph_dump_file);
+ }
+ if (post_ipa_mem_report)
+ {
+ fprintf (stderr, "Memory consumption after IPA\n");
+ dump_memory_report (false);
+ }
+ timevar_pop (TV_CGRAPHOPT);
+
+ /* Output everything. */
+ (*debug_hooks->assembly_start) ();
+ if (!quiet_flag)
+ fprintf (stderr, "Assembling functions:\n");
+#ifdef ENABLE_CHECKING
+ verify_cgraph ();
+#endif
+
+ cgraph_materialize_all_clones ();
+ bitmap_obstack_initialize (NULL);
+ execute_ipa_pass_list (all_late_ipa_passes);
+ cgraph_remove_unreachable_nodes (true, dump_file);
+#ifdef ENABLE_CHECKING
+ verify_cgraph ();
+#endif
+ bitmap_obstack_release (NULL);
+ cgraph_mark_functions_to_output ();
+ output_weakrefs ();
+
+ cgraph_state = CGRAPH_STATE_EXPANSION;
+ if (!flag_toplevel_reorder)
+ cgraph_output_in_order ();
+ else
+ {
+ cgraph_output_pending_asms ();
+
+ cgraph_expand_all_functions ();
+ varpool_remove_unreferenced_decls ();
+
+ varpool_assemble_pending_decls ();
+ }
+
+ cgraph_process_new_functions ();
+ cgraph_state = CGRAPH_STATE_FINISHED;
+
+ if (cgraph_dump_file)
+ {
+ fprintf (cgraph_dump_file, "\nFinal ");
+ dump_cgraph (cgraph_dump_file);
+ dump_varpool (cgraph_dump_file);
+ }
+#ifdef ENABLE_CHECKING
+ verify_cgraph ();
+ /* Double check that all inline clones are gone and that all
+ function bodies have been released from memory. */
+ if (!seen_error ())
+ {
+ struct cgraph_node *node;
+ bool error_found = false;
+
+ for (node = cgraph_nodes; node; node = node->next)
+ if (node->analyzed
+ && (node->global.inlined_to
+ || gimple_has_body_p (node->decl)))
+ {
+ error_found = true;
+ dump_cgraph_node (stderr, node);
+ }
+ if (error_found)
+ internal_error ("nodes with unreleased memory found");
+ }
+#endif
+}
+
+
+/* Analyze the whole compilation unit once it is parsed completely. */
+
+void
+cgraph_finalize_compilation_unit (void)
+{
+ timevar_push (TV_CGRAPH);
+
+ /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
+ if (flag_lto)
+ lto_streamer_hooks_init ();
+
+ /* If we're here there's no current function anymore. Some frontends
+ are lazy in clearing these. */
+ current_function_decl = NULL;
+ set_cfun (NULL);
+
+ /* Do not skip analyzing the functions if there were errors, we
+ miss diagnostics for following functions otherwise. */
+
+ /* Emit size functions we didn't inline. */
+ finalize_size_functions ();
+
+ /* Mark alias targets necessary and emit diagnostics. */
+ finish_aliases_1 ();
+ handle_alias_pairs ();
+
+ if (!quiet_flag)
+ {
+ fprintf (stderr, "\nAnalyzing compilation unit\n");
+ fflush (stderr);
+ }
+
+ if (flag_dump_passes)
+ dump_passes ();
+
+ /* Gimplify and lower all functions, compute reachability and
+ remove unreachable nodes. */
+ cgraph_analyze_functions ();
+
+ /* Mark alias targets necessary and emit diagnostics. */
+ finish_aliases_1 ();
+ handle_alias_pairs ();
+
+ /* Gimplify and lower thunks. */
+ cgraph_analyze_functions ();
+
+ /* Finally drive the pass manager. */
+ cgraph_optimize ();
+
+ timevar_pop (TV_CGRAPH);
+}
+
+
#include "gt-cgraphunit.h"
diff --git a/gcc/combine-stack-adj.c b/gcc/combine-stack-adj.c
index 3cffd662f92..6b6f74b4b25 100644
--- a/gcc/combine-stack-adj.c
+++ b/gcc/combine-stack-adj.c
@@ -320,6 +320,107 @@ maybe_move_args_size_note (rtx last, rtx insn, bool after)
add_reg_note (last, REG_ARGS_SIZE, XEXP (note, 0));
}
+/* Return the next (or previous) active insn within BB. */
+
+static rtx
+prev_active_insn_bb (basic_block bb, rtx insn)
+{
+ for (insn = PREV_INSN (insn);
+ insn != PREV_INSN (BB_HEAD (bb));
+ insn = PREV_INSN (insn))
+ if (active_insn_p (insn))
+ return insn;
+ return NULL_RTX;
+}
+
+static rtx
+next_active_insn_bb (basic_block bb, rtx insn)
+{
+ for (insn = NEXT_INSN (insn);
+ insn != NEXT_INSN (BB_END (bb));
+ insn = NEXT_INSN (insn))
+ if (active_insn_p (insn))
+ return insn;
+ return NULL_RTX;
+}
+
+/* If INSN has a REG_ARGS_SIZE note, if possible move it to PREV. Otherwise
+ search for a nearby candidate within BB where we can stick the note. */
+
+static void
+force_move_args_size_note (basic_block bb, rtx prev, rtx insn)
+{
+ rtx note, test, next_candidate, prev_candidate;
+
+ /* If PREV exists, tail-call to the logic in the other function. */
+ if (prev)
+ {
+ maybe_move_args_size_note (prev, insn, false);
+ return;
+ }
+
+ /* First, make sure there's anything that needs doing. */
+ note = find_reg_note (insn, REG_ARGS_SIZE, NULL_RTX);
+ if (note == NULL)
+ return;
+
+ /* We need to find a spot between the previous and next exception points
+ where we can place the note and "properly" deallocate the arguments. */
+ next_candidate = prev_candidate = NULL;
+
+ /* It is often the case that we have insns in the order:
+ call
+ add sp (previous deallocation)
+ sub sp (align for next arglist)
+ push arg
+ and the add/sub cancel. Therefore we begin by searching forward. */
+
+ test = insn;
+ while ((test = next_active_insn_bb (bb, test)) != NULL)
+ {
+ /* Found an existing note: nothing to do. */
+ if (find_reg_note (test, REG_ARGS_SIZE, NULL_RTX))
+ return;
+ /* Found something that affects unwinding. Stop searching. */
+ if (CALL_P (test) || !insn_nothrow_p (test))
+ break;
+ if (next_candidate == NULL)
+ next_candidate = test;
+ }
+
+ test = insn;
+ while ((test = prev_active_insn_bb (bb, test)) != NULL)
+ {
+ rtx tnote;
+ /* Found a place that seems logical to adjust the stack. */
+ tnote = find_reg_note (test, REG_ARGS_SIZE, NULL_RTX);
+ if (tnote)
+ {
+ XEXP (tnote, 0) = XEXP (note, 0);
+ return;
+ }
+ if (prev_candidate == NULL)
+ prev_candidate = test;
+ /* Found something that affects unwinding. Stop searching. */
+ if (CALL_P (test) || !insn_nothrow_p (test))
+ break;
+ }
+
+ if (prev_candidate)
+ test = prev_candidate;
+ else if (next_candidate)
+ test = next_candidate;
+ else
+ {
+ /* ??? We *must* have a place, lest we ICE on the lost adjustment.
+ Options are: dummy clobber insn, nop, or prevent the removal of
+ the sp += 0 insn. Defer that decision until we can prove this
+ can actually happen. */
+ gcc_unreachable ();
+ }
+ add_reg_note (test, REG_ARGS_SIZE, XEXP (note, 0));
+}
+
/* Subroutine of combine_stack_adjustments, called for each basic block. */
static void
@@ -327,6 +428,7 @@ combine_stack_adjustments_for_block (basic_block bb)
{
HOST_WIDE_INT last_sp_adjust = 0;
rtx last_sp_set = NULL_RTX;
+ rtx last2_sp_set = NULL_RTX;
struct csa_reflist *reflist = NULL;
rtx insn, next, set;
struct record_stack_refs_data data;
@@ -391,9 +493,8 @@ combine_stack_adjustments_for_block (basic_block bb)
last_sp_adjust + this_adjust,
this_adjust))
{
- maybe_move_args_size_note (last_sp_set, insn, false);
-
/* It worked! */
+ maybe_move_args_size_note (last_sp_set, insn, false);
delete_insn (insn);
last_sp_adjust += this_adjust;
continue;
@@ -409,9 +510,8 @@ combine_stack_adjustments_for_block (basic_block bb)
last_sp_adjust + this_adjust,
-last_sp_adjust))
{
- maybe_move_args_size_note (insn, last_sp_set, true);
-
/* It worked! */
+ maybe_move_args_size_note (insn, last_sp_set, true);
delete_insn (last_sp_set);
last_sp_set = insn;
last_sp_adjust += this_adjust;
@@ -424,8 +524,16 @@ combine_stack_adjustments_for_block (basic_block bb)
/* Combination failed. Restart processing from here. If
deallocation+allocation conspired to cancel, we can
delete the old deallocation insn. */
- if (last_sp_set && last_sp_adjust == 0)
- delete_insn (last_sp_set);
+ if (last_sp_set)
+ {
+ if (last_sp_adjust == 0)
+ {
+ maybe_move_args_size_note (insn, last_sp_set, true);
+ delete_insn (last_sp_set);
+ }
+ else
+ last2_sp_set = last_sp_set;
+ }
free_csa_reflist (reflist);
reflist = NULL;
last_sp_set = insn;
@@ -461,6 +569,10 @@ combine_stack_adjustments_for_block (basic_block bb)
&& try_apply_stack_adjustment (insn, reflist, 0,
-last_sp_adjust))
{
+ if (last2_sp_set)
+ maybe_move_args_size_note (last2_sp_set, last_sp_set, false);
+ else
+ maybe_move_args_size_note (insn, last_sp_set, true);
delete_insn (last_sp_set);
free_csa_reflist (reflist);
reflist = NULL;
@@ -487,16 +599,23 @@ combine_stack_adjustments_for_block (basic_block bb)
|| reg_mentioned_p (stack_pointer_rtx, PATTERN (insn))))
{
if (last_sp_set && last_sp_adjust == 0)
- delete_insn (last_sp_set);
+ {
+ force_move_args_size_note (bb, last2_sp_set, last_sp_set);
+ delete_insn (last_sp_set);
+ }
free_csa_reflist (reflist);
reflist = NULL;
+ last2_sp_set = NULL_RTX;
last_sp_set = NULL_RTX;
last_sp_adjust = 0;
}
}
if (last_sp_set && last_sp_adjust == 0)
- delete_insn (last_sp_set);
+ {
+ force_move_args_size_note (bb, last2_sp_set, last_sp_set);
+ delete_insn (last_sp_set);
+ }
if (reflist)
free_csa_reflist (reflist);
diff --git a/gcc/combine.c b/gcc/combine.c
index e3c8209a153..7eaaf476c6e 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -9698,7 +9698,7 @@ extended_count (const_rtx x, enum machine_mode mode, int unsignedp)
: 0)
: num_sign_bit_copies (x, mode) - 1);
}
-
+
/* This function is called from `simplify_shift_const' to merge two
outer operations. Specifically, we have already found that we need
to perform operation *POP0 with constant *PCONST0 at the outermost
@@ -13912,7 +13912,7 @@ unmentioned_reg_p (rtx equiv, rtx expr)
return for_each_rtx (&equiv, unmentioned_reg_p_1, expr);
}
-void
+DEBUG_FUNCTION void
dump_combine_stats (FILE *file)
{
fprintf
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 1f2baeec05a..3eb2c7002df 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -488,6 +488,10 @@ fi
case ${target} in
i[34567]86-*-*)
+ if test "x$with_abi" != x; then
+ echo "This target does not support --with-abi."
+ exit 1
+ fi
if test "x$enable_cld" = xyes; then
tm_defines="${tm_defines} USE_IX86_CLD=1"
fi
@@ -497,7 +501,24 @@ i[34567]86-*-*)
tm_file="vxworks-dummy.h ${tm_file}"
;;
x86_64-*-*)
- tm_file="i386/biarch64.h ${tm_file}"
+ case ${with_abi} in
+ "")
+ if test "x$with_multilib_list" = xmx32; then
+ tm_file="i386/biarchx32.h ${tm_file}"
+ else
+ tm_file="i386/biarch64.h ${tm_file}"
+ fi
+ ;;
+ 64 | m64)
+ tm_file="i386/biarch64.h ${tm_file}"
+ ;;
+ x32 | mx32)
+ tm_file="i386/biarchx32.h ${tm_file}"
+ ;;
+ *)
+ echo "Unknown ABI used in --with-abi=$with_abi"
+ exit 1
+ esac
if test "x$enable_cld" = xyes; then
tm_defines="${tm_defines} USE_IX86_CLD=1"
fi
@@ -740,6 +761,7 @@ case ${target} in
xm_file="vms/xm-vms.h"
c_target_objs="vms-c.o"
cxx_target_objs="vms-c.o"
+ fortran_target_objs="vms-f.o"
use_gcc_stdint=provide
tm_file="${tm_file} vms/vms-stdint.h"
if test x$gnu_ld != xyes; then
@@ -3137,7 +3159,7 @@ case "${target}" in
;;
i[34567]86-*-* | x86_64-*-*)
- supported_defaults="arch arch_32 arch_64 cpu cpu_32 cpu_64 tune tune_32 tune_64"
+ supported_defaults="abi arch arch_32 arch_64 cpu cpu_32 cpu_64 tune tune_32 tune_64"
for which in arch arch_32 arch_64 cpu cpu_32 cpu_64 tune tune_32 tune_64; do
eval "val=\$with_$which"
case ${val} in
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 9af66dd8ace..5522fc12172 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -82,6 +82,7 @@ static int arm_legitimate_index_p (enum machine_mode, rtx, RTX_CODE, int);
static int thumb2_legitimate_index_p (enum machine_mode, rtx, int);
static int thumb1_base_register_rtx_p (rtx, enum machine_mode, int);
static rtx arm_legitimize_address (rtx, rtx, enum machine_mode);
+static reg_class_t arm_preferred_reload_class (rtx, reg_class_t);
static rtx thumb_legitimize_address (rtx, rtx, enum machine_mode);
inline static int thumb1_index_register_rtx_p (rtx, int);
static bool arm_legitimate_address_p (enum machine_mode, rtx, bool);
@@ -576,6 +577,9 @@ static const struct attribute_spec arm_attribute_table[] =
#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P arm_legitimate_address_p
+#undef TARGET_PREFERRED_RELOAD_CLASS
+#define TARGET_PREFERRED_RELOAD_CLASS arm_preferred_reload_class
+
#undef TARGET_INVALID_PARAMETER_TYPE
#define TARGET_INVALID_PARAMETER_TYPE arm_invalid_parameter_type
@@ -6226,6 +6230,30 @@ arm_legitimate_address_p (enum machine_mode mode, rtx x, bool strict_p)
return thumb1_legitimate_address_p (mode, x, strict_p);
}
+/* Worker function for TARGET_PREFERRED_RELOAD_CLASS.
+
+ Given an rtx X being reloaded into a reg required to be
+ in class CLASS, return the class of reg to actually use.
+ In general this is just CLASS, but for the Thumb core registers and
+ immediate constants we prefer a LO_REGS class or a subset. */
+
+static reg_class_t
+arm_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, reg_class_t rclass)
+{
+ if (TARGET_32BIT)
+ return rclass;
+ else
+ {
+ if (rclass == GENERAL_REGS
+ || rclass == HI_REGS
+ || rclass == NO_REGS
+ || rclass == STACK_REG)
+ return LO_REGS;
+ else
+ return rclass;
+ }
+}
+
/* Build the SYMBOL_REF for __tls_get_addr. */
static GTY(()) rtx tls_get_addr_libfunc;
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 443d2ed168d..c6b4cc09a46 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -1151,16 +1151,6 @@ enum reg_class
#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P \
arm_small_register_classes_for_mode_p
-/* Given an rtx X being reloaded into a reg required to be
- in class CLASS, return the class of reg to actually use.
- In general this is just CLASS, but for the Thumb core registers and
- immediate constants we prefer a LO_REGS class or a subset. */
-#define PREFERRED_RELOAD_CLASS(X, CLASS) \
- (TARGET_32BIT ? (CLASS) : \
- ((CLASS) == GENERAL_REGS || (CLASS) == HI_REGS \
- || (CLASS) == NO_REGS || (CLASS) == STACK_REG \
- ? LO_REGS : (CLASS)))
-
/* Must leave BASE_REGS reloads alone */
#define THUMB_SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \
((CLASS) != LO_REGS && (CLASS) != BASE_REGS \
diff --git a/gcc/config/i386/biarchx32.h b/gcc/config/i386/biarchx32.h
new file mode 100644
index 00000000000..69d672216ac
--- /dev/null
+++ b/gcc/config/i386/biarchx32.h
@@ -0,0 +1,28 @@
+/* Make configure files to produce biarch compiler defaulting to x32 mode.
+ This file must be included very first, while the OS specific file later
+ to overwrite otherwise wrong defaults.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#define TARGET_64BIT_DEFAULT (OPTION_MASK_ISA_64BIT | OPTION_MASK_ABI_X32)
+#define TARGET_BI_ARCH 2
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 42746e474d3..d58dafc157d 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -3118,8 +3118,8 @@ ix86_option_override_internal (bool main_args_p)
#endif
/* Turn off both OPTION_MASK_ABI_64 and OPTION_MASK_ABI_X32 if
- TARGET_64BIT is false. */
- if (!TARGET_64BIT)
+ TARGET_64BIT_DEFAULT is true and TARGET_64BIT is false. */
+ if (TARGET_64BIT_DEFAULT && !TARGET_64BIT)
ix86_isa_flags &= ~(OPTION_MASK_ABI_64 | OPTION_MASK_ABI_X32);
#ifdef TARGET_BI_ARCH
else
@@ -32938,6 +32938,7 @@ struct expand_vec_perm_d
unsigned char perm[MAX_VECT_LEN];
enum machine_mode vmode;
unsigned char nelt;
+ bool one_operand_p;
bool testing_p;
};
@@ -33038,6 +33039,7 @@ ix86_expand_vector_init_duplicate (bool mmx_ok, enum machine_mode mode,
dperm.vmode = mode;
dperm.nelt = GET_MODE_NUNITS (mode);
dperm.op0 = dperm.op1 = gen_reg_rtx (mode);
+ dperm.one_operand_p = true;
/* Extend to SImode using a paradoxical SUBREG. */
tmp1 = gen_reg_rtx (SImode);
@@ -35735,7 +35737,7 @@ expand_vec_perm_blend (struct expand_vec_perm_d *d)
rtx target, op0, op1, x;
rtx rperm[32], vperm;
- if (d->op0 == d->op1)
+ if (d->one_operand_p)
return false;
if (TARGET_AVX2 && GET_MODE_SIZE (vmode) == 32)
;
@@ -35922,7 +35924,7 @@ expand_vec_perm_vpermil (struct expand_vec_perm_d *d)
rtx rperm[8], vperm;
unsigned i;
- if (!TARGET_AVX || d->vmode != V8SFmode || d->op0 != d->op1)
+ if (!TARGET_AVX || d->vmode != V8SFmode || !d->one_operand_p)
return false;
/* We can only permute within the 128-bit lane. */
@@ -35998,7 +36000,7 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
nelt = d->nelt;
- if (d->op0 != d->op1)
+ if (!d->one_operand_p)
{
if (!TARGET_XOP || GET_MODE_SIZE (d->vmode) != 16)
{
@@ -36086,7 +36088,7 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
else
{
eltsz = GET_MODE_SIZE (GET_MODE_INNER (d->vmode));
- if (d->op0 != d->op1)
+ if (!d->one_operand_p)
mask = 2 * nelt - 1;
else if (vmode == V16QImode)
mask = nelt - 1;
@@ -36113,7 +36115,7 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
target = gen_lowpart (vmode, d->target);
op0 = gen_lowpart (vmode, d->op0);
- if (d->op0 == d->op1)
+ if (d->one_operand_p)
{
if (vmode == V16QImode)
emit_insn (gen_ssse3_pshufbv16qi3 (target, op0, vperm));
@@ -36145,7 +36147,7 @@ expand_vec_perm_1 (struct expand_vec_perm_d *d)
/* Check plain VEC_SELECT first, because AVX has instructions that could
match both SEL and SEL+CONCAT, but the plain SEL will allow a memory
input where SEL+CONCAT may not. */
- if (d->op0 == d->op1)
+ if (d->one_operand_p)
{
int mask = nelt - 1;
bool identity_perm = true;
@@ -36242,7 +36244,7 @@ expand_vec_perm_1 (struct expand_vec_perm_d *d)
return true;
/* Recognize interleave style patterns with reversed operands. */
- if (d->op0 != d->op1)
+ if (!d->one_operand_p)
{
for (i = 0; i < nelt; ++i)
{
@@ -36285,7 +36287,7 @@ expand_vec_perm_pshuflw_pshufhw (struct expand_vec_perm_d *d)
unsigned i;
bool ok;
- if (d->vmode != V8HImode || d->op0 != d->op1)
+ if (d->vmode != V8HImode || !d->one_operand_p)
return false;
/* The two permutations only operate in 64-bit lanes. */
@@ -36357,6 +36359,7 @@ expand_vec_perm_palignr (struct expand_vec_perm_d *d)
gen_lowpart (TImode, d->op0), shift));
d->op0 = d->op1 = d->target;
+ d->one_operand_p = true;
in_order = true;
for (i = 0; i < nelt; ++i)
@@ -36396,14 +36399,14 @@ expand_vec_perm_interleave2 (struct expand_vec_perm_d *d)
if (GET_MODE_SIZE (d->vmode) == 16)
{
- if (d->op0 == d->op1)
+ if (d->one_operand_p)
return false;
}
else if (GET_MODE_SIZE (d->vmode) == 32)
{
if (!TARGET_AVX)
return false;
- /* For 32-byte modes allow even d->op0 == d->op1.
+ /* For 32-byte modes allow even d->one_operand_p.
The lack of cross-lane shuffling in some instructions
might prevent a single insn shuffle. */
dfinal = *d;
@@ -36528,11 +36531,11 @@ expand_vec_perm_interleave2 (struct expand_vec_perm_d *d)
if (nzcnt == 1)
{
- gcc_assert (d->op0 == d->op1);
+ gcc_assert (d->one_operand_p);
nonzero_halves[1] = nonzero_halves[0];
same_halves = true;
}
- else if (d->op0 == d->op1)
+ else if (d->one_operand_p)
{
gcc_assert (nonzero_halves[0] == 0);
gcc_assert (nonzero_halves[1] == 1);
@@ -36571,7 +36574,7 @@ expand_vec_perm_interleave2 (struct expand_vec_perm_d *d)
}
}
}
- else if (d->op0 == d->op1)
+ else if (d->one_operand_p)
return false;
else if (TARGET_AVX2
&& (contents & (q[0] | q[2] | q[4] | q[6])) == contents)
@@ -36628,6 +36631,7 @@ expand_vec_perm_interleave2 (struct expand_vec_perm_d *d)
}
dfinal.op0 = gen_reg_rtx (dfinal.vmode);
dfinal.op1 = dfinal.op0;
+ dfinal.one_operand_p = true;
dremap.target = dfinal.op0;
/* Test if the final remap can be done with a single insn. For V4SFmode or
@@ -36671,7 +36675,7 @@ expand_vec_perm_vpermq_perm_1 (struct expand_vec_perm_d *d)
if (!(TARGET_AVX2
&& (d->vmode == V32QImode || d->vmode == V16HImode)
- && d->op0 == d->op1))
+ && d->one_operand_p))
return false;
contents[0] = 0;
@@ -36699,6 +36703,7 @@ expand_vec_perm_vpermq_perm_1 (struct expand_vec_perm_d *d)
dremap.target = gen_reg_rtx (V4DImode);
dremap.op0 = gen_lowpart (V4DImode, d->op0);
dremap.op1 = dremap.op0;
+ dremap.one_operand_p = true;
for (i = 0; i < 2; ++i)
{
unsigned int cnt = 0;
@@ -36712,6 +36717,7 @@ expand_vec_perm_vpermq_perm_1 (struct expand_vec_perm_d *d)
dfinal = *d;
dfinal.op0 = gen_lowpart (dfinal.vmode, dremap.target);
dfinal.op1 = dfinal.op0;
+ dfinal.one_operand_p = true;
for (i = 0, j = 0; i < nelt; ++i)
{
if (i == nelt2)
@@ -36751,8 +36757,7 @@ expand_vec_perm_vperm2f128 (struct expand_vec_perm_d *d)
return false;
dsecond = *d;
- if (d->op0 == d->op1)
- dsecond.op1 = gen_reg_rtx (d->vmode);
+ dsecond.one_operand_p = false;
dsecond.testing_p = true;
/* ((perm << 2)|perm) & 0x33 is the vperm2[fi]128
@@ -36821,10 +36826,7 @@ expand_vec_perm_vperm2f128 (struct expand_vec_perm_d *d)
vperm2f128 on d->op0 and d->op1. */
dsecond.testing_p = false;
dfirst = *d;
- if (d->op0 == d->op1)
- dfirst.target = dsecond.op1;
- else
- dfirst.target = gen_reg_rtx (d->vmode);
+ dfirst.target = gen_reg_rtx (d->vmode);
for (i = 0; i < nelt; i++)
dfirst.perm[i] = (i & (nelt2 - 1))
+ ((perm >> (2 * (i >= nelt2))) & 3) * nelt2;
@@ -36845,9 +36847,8 @@ expand_vec_perm_vperm2f128 (struct expand_vec_perm_d *d)
return true;
}
- /* For d->op0 == d->op1 the only useful vperm2f128 permutation
- is 0x10. */
- if (d->op0 == d->op1)
+ /* For one operand, the only useful vperm2f128 permutation is 0x10. */
+ if (d->one_operand_p)
return false;
}
@@ -36864,7 +36865,7 @@ expand_vec_perm_interleave3 (struct expand_vec_perm_d *d)
unsigned i, nelt;
rtx (*gen) (rtx, rtx, rtx);
- if (d->op0 == d->op1)
+ if (d->one_operand_p)
return false;
if (TARGET_AVX2 && GET_MODE_SIZE (d->vmode) == 32)
;
@@ -36947,7 +36948,7 @@ expand_vec_perm_vperm2f128_vblend (struct expand_vec_perm_d *d)
if (!TARGET_AVX
|| TARGET_AVX2
|| (d->vmode != V8SFmode && d->vmode != V4DFmode)
- || d->op0 != d->op1)
+ || !d->one_operand_p)
return false;
dfirst = *d;
@@ -36985,6 +36986,7 @@ expand_vec_perm_vperm2f128_vblend (struct expand_vec_perm_d *d)
dsecond = *d;
dsecond.op0 = dfirst.target;
dsecond.op1 = dfirst.target;
+ dsecond.one_operand_p = true;
dsecond.target = gen_reg_rtx (dsecond.vmode);
for (i = 0; i < nelt; i++)
dsecond.perm[i] = i ^ nelt2;
@@ -37009,7 +37011,7 @@ expand_vec_perm_pshufb2 (struct expand_vec_perm_d *d)
if (!TARGET_SSSE3 || GET_MODE_SIZE (d->vmode) != 16)
return false;
- gcc_assert (d->op0 != d->op1);
+ gcc_assert (!d->one_operand_p);
nelt = d->nelt;
eltsz = GET_MODE_SIZE (GET_MODE_INNER (d->vmode));
@@ -37064,7 +37066,7 @@ expand_vec_perm_vpshufb2_vpermq (struct expand_vec_perm_d *d)
unsigned int i, nelt, eltsz;
if (!TARGET_AVX2
- || d->op0 != d->op1
+ || !d->one_operand_p
|| (d->vmode != V32QImode && d->vmode != V16HImode))
return false;
@@ -37132,7 +37134,7 @@ expand_vec_perm_vpshufb2_vpermq_even_odd (struct expand_vec_perm_d *d)
unsigned int i, nelt, eltsz;
if (!TARGET_AVX2
- || d->op0 == d->op1
+ || d->one_operand_p
|| (d->vmode != V32QImode && d->vmode != V16HImode))
return false;
@@ -37491,7 +37493,7 @@ expand_vec_perm_broadcast (struct expand_vec_perm_d *d)
{
unsigned i, elt, nelt = d->nelt;
- if (d->op0 != d->op1)
+ if (!d->one_operand_p)
return false;
elt = d->perm[0];
@@ -37514,7 +37516,7 @@ expand_vec_perm_vpshufb4_vpermq2 (struct expand_vec_perm_d *d)
bool used[4];
if (!TARGET_AVX2
- || d->op0 == d->op1
+ || d->one_operand_p
|| (d->vmode != V32QImode && d->vmode != V16HImode))
return false;
@@ -37715,6 +37717,7 @@ ix86_expand_vec_perm_const (rtx operands[4])
perm[i] = ei;
}
+ d.one_operand_p = true;
switch (which)
{
default:
@@ -37722,51 +37725,39 @@ ix86_expand_vec_perm_const (rtx operands[4])
case 3:
if (!rtx_equal_p (d.op0, d.op1))
- break;
-
+ {
+ d.one_operand_p = false;
+ break;
+ }
/* The elements of PERM do not suggest that only the first operand
is used, but both operands are identical. Allow easier matching
of the permutation by folding the permutation into the single
input vector. */
- for (i = 0; i < nelt; ++i)
- if (d.perm[i] >= nelt)
- d.perm[i] -= nelt;
/* FALLTHRU */
- case 1:
- d.op1 = d.op0;
- break;
-
case 2:
for (i = 0; i < nelt; ++i)
- d.perm[i] -= nelt;
+ d.perm[i] &= nelt - 1;
d.op0 = d.op1;
break;
+
+ case 1:
+ d.op1 = d.op0;
+ break;
}
if (ix86_expand_vec_perm_const_1 (&d))
return true;
- /* If the mask says both arguments are needed, but they are the same,
- the above tried to expand with d.op0 == d.op1. If that didn't work,
- retry with d.op0 != d.op1 as that is what testing has been done with. */
- if (which == 3 && d.op0 == d.op1)
+ /* If the selector says both arguments are needed, but the operands are the
+ same, the above tried to expand with one_operand_p and flattened selector.
+ If that didn't work, retry without one_operand_p; we succeeded with that
+ during testing. */
+ if (which == 3 && d.one_operand_p)
{
- rtx seq;
- bool ok;
-
+ d.one_operand_p = false;
memcpy (d.perm, perm, sizeof (perm));
- d.op1 = gen_reg_rtx (d.vmode);
- start_sequence ();
- ok = ix86_expand_vec_perm_const_1 (&d);
- seq = get_insns ();
- end_sequence ();
- if (ok)
- {
- emit_move_insn (d.op1, d.op0);
- emit_insn (seq);
- return true;
- }
+ return ix86_expand_vec_perm_const_1 (&d);
}
return false;
@@ -37780,7 +37771,7 @@ ix86_vectorize_vec_perm_const_ok (enum machine_mode vmode,
{
struct expand_vec_perm_d d;
unsigned int i, nelt, which;
- bool ret, one_vec;
+ bool ret;
d.vmode = vmode;
d.nelt = nelt = GET_MODE_NUNITS (d.vmode);
@@ -37817,17 +37808,17 @@ ix86_vectorize_vec_perm_const_ok (enum machine_mode vmode,
d.perm[i] -= nelt;
/* Check whether the mask can be applied to the vector type. */
- one_vec = (which != 3);
+ d.one_operand_p = (which != 3);
/* Implementable with shufps or pshufd. */
- if (one_vec && (d.vmode == V4SFmode || d.vmode == V4SImode))
+ if (d.one_operand_p && (d.vmode == V4SFmode || d.vmode == V4SImode))
return true;
/* Otherwise we have to go through the motions and see if we can
figure out how to generate the requested permutation. */
d.target = gen_raw_REG (d.vmode, LAST_VIRTUAL_REGISTER + 1);
d.op1 = d.op0 = gen_raw_REG (d.vmode, LAST_VIRTUAL_REGISTER + 2);
- if (!one_vec)
+ if (!d.one_operand_p)
d.op1 = gen_raw_REG (d.vmode, LAST_VIRTUAL_REGISTER + 3);
start_sequence ();
@@ -37848,6 +37839,7 @@ ix86_expand_vec_extract_even_odd (rtx targ, rtx op0, rtx op1, unsigned odd)
d.op1 = op1;
d.vmode = GET_MODE (targ);
d.nelt = nelt = GET_MODE_NUNITS (d.vmode);
+ d.one_operand_p = false;
d.testing_p = false;
for (i = 0; i < nelt; ++i)
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 96e43a22ca9..b63d774e43f 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -1175,14 +1175,14 @@
(parallel [(const_int 0)]))
(vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
(plusminus:DF
- (vec_select:DF (match_dup 1) (parallel [(const_int 2)]))
- (vec_select:DF (match_dup 1) (parallel [(const_int 3)]))))
- (vec_concat:V2DF
- (plusminus:DF
(vec_select:DF
(match_operand:V4DF 2 "nonimmediate_operand" "xm")
(parallel [(const_int 0)]))
- (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))
+ (vec_select:DF (match_dup 2) (parallel [(const_int 1)]))))
+ (vec_concat:V2DF
+ (plusminus:DF
+ (vec_select:DF (match_dup 1) (parallel [(const_int 2)]))
+ (vec_select:DF (match_dup 1) (parallel [(const_int 3)])))
(plusminus:DF
(vec_select:DF (match_dup 2) (parallel [(const_int 2)]))
(vec_select:DF (match_dup 2) (parallel [(const_int 3)]))))))]
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 98a6120c975..4b8a6929b1e 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -740,9 +740,6 @@ ia64_handle_model_attribute (tree *node, tree name, tree args,
return NULL_TREE;
}
-/* The section must have global and overlaid attributes. */
-#define SECTION_VMS_OVERLAY SECTION_MACH_DEP
-
/* Part of the low level implementation of DEC Ada pragma Common_Object which
enables the shared use of variables stored in overlaid linker areas
corresponding to the use of Fortran COMMON. */
@@ -753,24 +750,18 @@ ia64_vms_common_object_attribute (tree *node, tree name, tree args,
bool *no_add_attrs)
{
tree decl = *node;
- tree id, val;
- if (! DECL_P (decl))
- abort ();
+ tree id;
+
+ gcc_assert (DECL_P (decl));
DECL_COMMON (decl) = 1;
id = TREE_VALUE (args);
- if (TREE_CODE (id) == IDENTIFIER_NODE)
- val = build_string (IDENTIFIER_LENGTH (id), IDENTIFIER_POINTER (id));
- else if (TREE_CODE (id) == STRING_CST)
- val = id;
- else
+ if (TREE_CODE (id) != IDENTIFIER_NODE && TREE_CODE (id) != STRING_CST)
{
- warning (OPT_Wattributes,
- "%qE attribute requires a string constant argument", name);
+ error ("%qE attribute requires a string constant argument", name);
*no_add_attrs = true;
return NULL_TREE;
}
- DECL_SECTION_NAME (decl) = val;
return NULL_TREE;
}
@@ -783,50 +774,31 @@ ia64_vms_output_aligned_decl_common (FILE *file, tree decl, const char *name,
{
tree attr = DECL_ATTRIBUTES (decl);
- /* As common_object attribute set DECL_SECTION_NAME check it before
- looking up the attribute. */
- if (DECL_SECTION_NAME (decl) && attr)
+ if (attr)
attr = lookup_attribute ("common_object", attr);
- else
- attr = NULL_TREE;
-
- if (!attr)
- {
- /* Code from elfos.h. */
- fprintf (file, "%s", COMMON_ASM_OP);
- assemble_name (file, name);
- fprintf (file, ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",
- size, align / BITS_PER_UNIT);
- }
- else
+ if (attr)
{
- ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
- ASM_OUTPUT_LABEL (file, name);
- ASM_OUTPUT_SKIP (file, size ? size : 1);
- }
-}
+ tree id = TREE_VALUE (TREE_VALUE (attr));
+ const char *name;
-/* Definition of TARGET_ASM_NAMED_SECTION for VMS. */
+ if (TREE_CODE (id) == IDENTIFIER_NODE)
+ name = IDENTIFIER_POINTER (id);
+ else if (TREE_CODE (id) == STRING_CST)
+ name = TREE_STRING_POINTER (id);
+ else
+ abort ();
-void
-ia64_vms_elf_asm_named_section (const char *name, unsigned int flags,
- tree decl)
-{
- if (!(flags & SECTION_VMS_OVERLAY))
- {
- default_elf_asm_named_section (name, flags, decl);
- return;
+ fprintf (file, "\t.vms_common\t\"%s\",", name);
}
- if (flags != (SECTION_VMS_OVERLAY | SECTION_WRITE))
- abort ();
+ else
+ fprintf (file, "%s", COMMON_ASM_OP);
- if (flags & SECTION_DECLARED)
- {
- fprintf (asm_out_file, "\t.section\t%s\n", name);
- return;
- }
+ /* Code from elfos.h. */
+ assemble_name (file, name);
+ fprintf (file, ","HOST_WIDE_INT_PRINT_UNSIGNED",%u",
+ size, align / BITS_PER_UNIT);
- fprintf (asm_out_file, "\t.section\t%s,\"awgO\"\n", name);
+ fputc ('\n', file);
}
static void
@@ -10536,12 +10508,6 @@ ia64_section_type_flags (tree decl, const char *name, int reloc)
|| strncmp (name, ".gnu.linkonce.sb.", 17) == 0)
flags = SECTION_SMALL;
-#if TARGET_ABI_OPEN_VMS
- if (decl && DECL_ATTRIBUTES (decl)
- && lookup_attribute ("common_object", DECL_ATTRIBUTES (decl)))
- flags |= SECTION_VMS_OVERLAY;
-#endif
-
flags |= default_section_type_flags (decl, name, reloc);
return flags;
}
diff --git a/gcc/config/ia64/vms.h b/gcc/config/ia64/vms.h
index 11f017663b5..3e81d769897 100644
--- a/gcc/config/ia64/vms.h
+++ b/gcc/config/ia64/vms.h
@@ -121,9 +121,6 @@ STATIC func_ptr __CTOR_LIST__[1] \
#undef TARGET_VALID_POINTER_MODE
#define TARGET_VALID_POINTER_MODE ia64_vms_valid_pointer_mode
-#undef TARGET_ASM_NAMED_SECTION
-#define TARGET_ASM_NAMED_SECTION ia64_vms_elf_asm_named_section
-
/* Define this macro if it is advisable to hold scalars in registers
in a wider mode than that declared by the program. In such cases,
the value is constrained to be within the bounds of the declared
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 19973005be7..3e85fcf3e6c 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -6487,7 +6487,9 @@ push_regs (HARD_REG_SET *mask, int interrupt_handler)
use_movml = true;
}
- if (use_movml)
+ if (sh_cfun_resbank_handler_p ())
+ ; /* Do nothing. */
+ else if (use_movml)
{
rtx x, mem, reg, set;
rtx sp_reg = gen_rtx_REG (SImode, STACK_POINTER_REGNUM);
@@ -7485,7 +7487,9 @@ sh_expand_epilogue (bool sibcall_p)
use_movml = true;
}
- if (use_movml)
+ if (sh_cfun_resbank_handler_p ())
+ ; /* Do nothing. */
+ else if (use_movml)
{
rtx sp_reg = gen_rtx_REG (SImode, STACK_POINTER_REGNUM);
diff --git a/gcc/config/vms/make-crtlmap.awk b/gcc/config/vms/make-crtlmap.awk
index 6f82dee7aa8..63be6e708ab 100644
--- a/gcc/config/vms/make-crtlmap.awk
+++ b/gcc/config/vms/make-crtlmap.awk
@@ -40,13 +40,13 @@ BEGIN {
print "{ \"" $1 "\", "
if (NF == 1)
print "0 }"
- else if (NF == 2)
- printf "VMS_CRTL_" $2 " }"
- else if (NF == 3)
- printf "VMS_CRTL_" $2 " | VMS_CRTL_" $3 " }"
else
- # To be fixed.
- exit 1
+ {
+ printf "VMS_CRTL_" $2
+ for (i = 3; i <= NF; i++)
+ printf " | VMS_CRTL_" $i
+ printf " }"
+ }
}
END {
diff --git a/gcc/config/vms/t-vms b/gcc/config/vms/t-vms
index 4e20bde8070..f2161b7861b 100644
--- a/gcc/config/vms/t-vms
+++ b/gcc/config/vms/t-vms
@@ -34,3 +34,8 @@ vms-c.o: $(srcdir)/config/vms/vms-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_P_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(PREPROCESSOR_DEFINES) $< -o $@
+
+vms-f.o: $(srcdir)/config/vms/vms-f.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(PREPROCESSOR_DEFINES) $< -o $@
diff --git a/gcc/config/vms/vms-c.c b/gcc/config/vms/vms-c.c
index 6f8a1cf6138..09172b261ab 100644
--- a/gcc/config/vms/vms-c.c
+++ b/gcc/config/vms/vms-c.c
@@ -120,7 +120,9 @@ vms_pragma_nomember_alignment (cpp_reader *pfile ATTRIBUTE_UNUSED)
if (arg[0] == '_' && arg[1] == '_')
arg += 2;
- if (strcmp (arg, "word") == 0)
+ if (strcmp (arg, "byte") == 0)
+ maximum_field_alignment = 1 * BITS_PER_UNIT;
+ else if (strcmp (arg, "word") == 0)
maximum_field_alignment = 2 * BITS_PER_UNIT;
else if (strcmp (arg, "longword") == 0)
maximum_field_alignment = 4 * BITS_PER_UNIT;
@@ -453,6 +455,9 @@ vms_c_register_includes (const char *sysroot,
void
vms_c_common_override_options (void)
{
+ /* Allow variadic functions without parameters (as declared in starlet). */
+ flag_allow_parameterless_variadic_functions = TRUE;
+
/* Initialize c_default_pointer_mode. */
switch (flag_vms_pointer_size)
{
diff --git a/gcc/config/vms/vms-crtlmap.map b/gcc/config/vms/vms-crtlmap.map
index d98afacc17f..e80e2afe493 100644
--- a/gcc/config/vms/vms-crtlmap.map
+++ b/gcc/config/vms/vms-crtlmap.map
@@ -12,130 +12,483 @@
# - Comment lines start with '#' in the first column.
# - map lines consist in an identifier optionnaly followed by at most 2
# space-separated flags.
-# Flags are:
-# FLOAT: will be prefixed by 't'/'g'/'d'.
-# 64: There is a 64-bit variant.
-# GLOBAL: name will be prefixed by ga_
-# BSD44: name will be prefixed by __bsd44__.
-# LDBL: a 'x' prefix will be added if 128 bit long doubles are enabled.
-# MALLOC: malloc related function.
+# Flags are described in vms.c (prefixed by VMS_CRTL_).
#
# Keep entries alpha-sorted - this is enforced by the awk script.
#
+__32_getpwent
+__32_getpwnam
+__32_getpwuid
+__32_sigaction
__32_signal
__32_ssignal
+__64_getpwent
+__64_getpwnam
+__64_getpwuid
+__64_sigaction
__64_signal
__64_ssignal
+__assert
+__dl__xpv
+__freeaddrinfo32
+__freeaddrinfo64
+__getaddrinfo32
+__getaddrinfo64
+__getaddrinfo_compat4332
+__getaddrinfo_compat4364
+__getgrent64
+__getgrgid64
+__getgrgid_r64
+__getgrnam64
+__getgrnam_r64
+__lgamma FLOAT64 FLOATV2
+__lgammaf FLOAT32 FLOATV2
+__lgammal FLOAT64 FLOAT128 FLOATV2
+__long_gid___32_getpwnam
+__long_gid___32_getpwuid
+__long_gid___64_getpwnam
+__long_gid___64_getpwuid
+__long_gid_access
+__long_gid_chmod
+__long_gid_chown
+__long_gid_fchmod
+__long_gid_fchown
+__long_gid_fstat
+__long_gid_ftw
+__long_gid_getegid
+__long_gid_geteuid
+__long_gid_getgid
+__long_gid_getgroups
+__long_gid_getpwnam
+__long_gid_getpwnam_r 64
+__long_gid_getpwuid
+__long_gid_getpwuid_r 64
+__long_gid_getuid
+__long_gid_lchown
+__long_gid_lstat
+__long_gid_setgid
+__long_gid_setuid
+__long_gid_stat
+__non_utc_ftw
+__nw__xui
+__off64_fcntl
+__off64_fseeko
+__off64_fstat
+__off64_ftello
+__off64_ftruncate
+__off64_ftw
+__off64_long_gid_fstat
+__off64_long_gid_ftw
+__off64_long_gid_lstat
+__off64_long_gid_stat
+__off64_lseek
+__off64_lstat
+__off64_mmap 64
+__off64_non_utc_ftw
+__off64_pread
+__off64_pwrite
+__off64_stat
+__off64_truncate
+__off64_utc_fstat
+__off64_utc_lstat
+__off64_utc_stat
+__pdam_wcsftime
+__pdam_wcstok 64
__posix__exit
__posix_exit
__posix_kill
__posix_long_gid_kill
+__posix_system
+__posix_wait
+__read_rnd
+__recvmsg32 BSD44
+__recvmsg64 BSD44
+__sendmsg32 BSD44
+__sendmsg64 BSD44
+__short_gid___32_getpwent
+__short_gid___64_getpwent
+__short_gid_getpwent
+__std_fstat
+__std_ftw
+__std_lstat
+__std_stat
+__unix_geteuid
__unix_getuid
+__utc_ctime
+__utc_ctime_r
__utc_fstat
+__utc_ftime
+__utc_gmtime
+__utc_gmtime_r
__utc_localtime
__utc_localtime_r
__utc_lstat
+__utc_mktime
+__utc_pdam_wcsftime
__utc_stat
__utc_strftime
__utc_time
+__utc_utime
+__utc_utimes
+__utc_wcsftime
__utctz_gmtime
+__utctz_gmtime_r
__utctz_localtime
__utctz_localtime_r
+__vms_pclose
+__vms_wait3
+__vms_wait4
+__vms_waitpid
+__writev32
+__writev64
+_exit
+_fstat
+a64l
abort
abs
-accept
+accept BSD44
access
-acos FLOAT
+acos FLOAT64 DPML
+acosd FLOAT64_VAXD DPML
+acosdl FLOAT64_VAXD
+acosh FLOAT64_VAXD DPML
+acoshl FLOAT64_VAXD
+acosl FLOAT64_VAXD
alarm
asctime
asctime_r
-asin FLOAT
-atan FLOAT
-atan2 FLOAT
+asin FLOAT64 DPML
+asind FLOAT64_VAXD DPML
+asindl FLOAT64_VAXD
+asinh FLOAT64_VAXD DPML
+asinhl FLOAT64_VAXD
+asinl FLOAT64_VAXD
+atan FLOAT64 DPML
+atan2 FLOAT64 DPML
+atan2l FLOAT64_VAXD
+atand FLOAT64_VAXD DPML
+atand2 FLOAT64_VAXD DPML
+atand2l FLOAT64_VAXD
+atandl FLOAT64_VAXD
+atanh FLOAT64_VAXD DPML
+atanhl FLOAT64_VAXD
+atanl FLOAT64_VAXD
atexit
-atof FLOAT
+atof FLOAT64
atoi
atol
atoll
atoq
-basename 64
+basename 64
bcmp
bcopy
-bsearch 64
+bind BSD44
+box
+# brk
+bsd_mh GA
+bsd_waddbytes
+bsd_waddstr
+bsearch 64
+btowc
bzero
-calloc 64 MALLOC
-ceil FLOAT
+cabs FLOAT64 FLOATV2
+cabsf FLOAT32 FLOATV2
+cabsl FLOAT64 FLOAT128 FLOATV2
+cacos DPML
+cacosh DPML
+calloc 64 MALLOC
+calloc_opt
+carg DPML
+casin DPML
+casinh DPML
+catan DPML
+catanh DPML
+catclose
+catgets 64
+catopen
+cbrt FLOAT64_VAXD
+cbrtl FLOAT64_VAXD
+ccos DPML
+ccosh DPML
+cdiv DPML
+ceil FLOAT64 DPML
+ceill FLOAT64_VAXD
+cexp DPML
+cfree
+cfree_opt
chdir
chmod
chown
clearerr
+clearerr_unlocked
clock
+clock_getres
+clock_gettime
+clock_settime
+clog DPML
close
closedir
-connect
-cos FLOAT
-ctermid 64
+cmul DPML
+cols GA
+confstr
+connect BSD44
+copysign FLOAT64_VAXD DPML
+copysignl FLOAT64_VAXD
+cos FLOAT64 DPML
+cosd FLOAT64_VAXD DPML
+cosdl FLOAT64_VAXD
+cosh FLOAT64 DPML
+coshl FLOAT64_VAXD
+cosl FLOAT64_VAXD
+cot FLOAT64_VAXD DPML
+cotd FLOAT64_VAXD DPML
+cotdl FLOAT64_VAXD
+cotl FLOAT64_VAXD
+cpow DPML
+creat
+crtl_init
+crypt 64
+csin DPML
+csinh DPML
+csqrt DPML
+ctan DPML
+ctanh DPML
+ctermid 64
ctime
+ctime_r
+cuserid 64
+daylight GL
+delete
+delwin
+difftime FLOAT64
+dirname 64
+div
dlclose
dlerror
dlopen
dlsym
+drand48 FLOAT64
+drem DPML
dup
dup2
-environ GLOBAL
+ecvt FLOAT64
+encrypt
+endgrent
+endhostent
+endnetent
+endprotoent
+endpwent
+endservent
+endwin
+environ GA
+erand48 FLOAT64
+erf FLOAT64_VAXD DPML
+erfc FLOAT64_VAXD DPML
+erfcl FLOAT64_VAXD
+erfl FLOAT64_VAXD
+errno GA
+execl
+execle
+execlp
execv
execve
execvp
exit
-exp FLOAT
-fabs FLOAT
+exp FLOAT64 DPML
+expl FLOAT64_VAXD
+expm1 FLOAT64_VAXD DPML
+expm1l FLOAT64_VAXD
+fabs FLOAT64 DPML
+fabsl FLOAT64_VAXD
+fchmod
+fchown
fclose
fcntl
+fcvt FLOAT64
fdopen
feof
+feof_unlocked
ferror
+ferror_unlocked
fflush
ffs
fgetc
-fgetname 64 MALLOC
-fgets 64
+fgetc_unlocked
+fgetname 64
+fgetpos
+fgets 64
+fgetwc
+fgetws 64
fileno
-floor FLOAT
+finite FLOAT64_VAXD DPML
+finitel FLOAT64_VAXD
+flockfile
+floor FLOAT64 DPML
+floorl FLOAT64_VAXD
+fmod FLOAT64 DPML NODPML FLOATV2
+fmodf FLOAT32 NODPML FLOATV2
+fmodl FLOAT64 FLOAT128 NODPML FLOATV2
+# fnmatch # Overridden by libiberty.
fopen
+fp_class FLOAT64_VAXD DPML
+fp_classl FLOAT64_VAXD
fpathconf
-fprintf FLOAT LDBL
+fprintf FLOAT64 FLOAT128
+fprintf__cf FLOAT64 FLOAT128
fputc
+fputc_unlocked
fputs
+fputwc
+fputws
fread
free
+free_opt
+freeaddrinfo
+freehostent
freopen
-frexp FLOAT
+frexp FLOAT64 DPML
+frexpl FLOAT64_VAXD
+fscanf FLOAT64 FLOAT128
fseek
+fseeko
+fsetpos
+fstat
+fstatvfs
+fsync
ftell
+ftello
+ftime
+ftruncate
+ftrylockfile
+ftw
+funlockfile
+fwait
+fwide
+fwprintf FLOAT64 FLOAT128
fwrite
+fwscanf FLOAT64 FLOAT128
+gai_strerror
+gamma FLOAT64 FLOATV2
+gammaf FLOAT32 FLOATV2
+gammal FLOAT64 FLOAT128 FLOATV2
+gbsd_mvprintw
+gbsd_mvscanw
+gbsd_mvwprintw
+gbsd_mvwscanw
+gbsd_printw
+gbsd_scanw
+gbsd_wprintw
+gbsd_wscanw
+gcvt FLOAT64 64
+get_errno_addr
+get_vms_errno_addr
+getaddrinfo
+getaddrinfo_compat43
getc
+getc_unlocked
getchar
-getcwd 64
+getchar_unlocked
+getclock
+getcwd 64
+getdtablesize
getegid
getenv
geteuid
getgid
-gethostbyaddr
-gethostbyname
-getname
+getgrent
+getgrgid
+getgrgid_r
+getgrnam
+getgrnam_r
+getgroups
+gethostaddr
+gethostbyaddr BSD44
+gethostbyname BSD44
+gethostent
+gethostname
+getipnodebyaddr
+getipnodebyname
+getitimer
+getlogin
+getlogin_r
+getname 64
+getnameinfo
+getnetbyaddr
+getnetbyname
+getnetent
+getopt 32ONLY
getpagesize
+getpeername BSD44
+getpgid
+getpgrp
getpid
+getppid
+getprotobyname
+getprotobynumber
+getprotoent
getpwent
getpwnam
+getpwnam_r 64
+getpwuid
+getpwuid_r 64
+gets 64
getservbyname
getservbyport
+getservent
+getsid
+getsockname BSD44
getsockopt
gettimeofday
getuid
+getw
+getwc
+getwchar
+glob 64
+globfree 64
gmtime
+gmtime_r
+gsignal
+herror
+hostalias
+hstrerror
+htonl
htons
+hypot FLOAT64 DPML NODPML FLOATV2
+hypotf FLOAT32 NODPML FLOATV2
+hypotl FLOAT64 FLOAT128 NODPML FLOATV2
iconv
-index 64
+iconv_close
+iconv_open
+if_freenameindex
+if_indextoname
+if_nameindex
+if_nametoindex
+ilogb DPML
+index 64
+inet6_opt_append
+inet6_opt_find
+inet6_opt_finish
+inet6_opt_get_val
+inet6_opt_init
+inet6_opt_next
+inet6_opt_set_val
+inet6_rth_add
+inet6_rth_getaddr
+inet6_rth_init
+inet6_rth_reverse
+inet6_rth_segments
+inet6_rth_space
+inet_addr
+inet_aton
+inet_lnaof
+inet_makeaddr
+inet_netof
+inet_network
+inet_ntoa
+inet_ntop
+inet_pton
+initscr
+initstate
ioctl
isalnum
isalpha
@@ -146,128 +499,432 @@ iscntrl
isdigit
isgraph
islower
+isnan FLOAT64_VAXD DPML
+isnanl FLOAT64_VAXD
isprint
ispunct
isspace
isupper
+iswalnum
+iswalpha
+iswcntrl
+iswctype
+iswdigit
+iswgraph
+iswlower
+iswprint
+iswpunct
+iswspace
+iswupper
+iswxdigit
isxdigit
+j0 FLOAT64_VAXD DPML
+j0l FLOAT64_VAXD
+j1 FLOAT64_VAXD DPML
+j1l FLOAT64_VAXD
+jn FLOAT64_VAXD DPML
+jnl FLOAT64_VAXD
+jrand48
kill
-ldexp FLOAT
+l64a
+l64a_r
+labs
+lchown
+lcong48
+ldexp FLOAT64 DPML
+ldexpl FLOAT64_VAXD
+ldiv
+lgamma FLOAT64 DPML NODPML FLOATV2
+lgammaf FLOAT32 NODPML FLOATV2
+lgammal FLOAT64 FLOAT128 NODPML FLOATV2
+lines GA
+link
+listen
+llabs
+lldiv
locale
localeconv
localtime
localtime_r
-log FLOAT
-log10 FLOAT
+# ln -> log DPML
+log FLOAT64 FLOATV2
+log10 FLOAT64 DPML
+log10l FLOAT64_VAXD
+log1p FLOAT64_VAXD DPML
+log1pl FLOAT64_VAXD
+log2 FLOAT64_VAXD DPML
+log2l FLOAT64_VAXD
+logb FLOAT64_VAXD DPML
+logbl FLOAT64_VAXD
+logf FLOAT32 FLOATV2
+logl FLOAT64 FLOAT128 FLOATV2
longjmp
+longname 64
+lrand48
+lround DPML
lseek
-malloc 64 MALLOC
-mbstowcs 64
-memchr 64
+lstat
+lwait
+malloc 64 MALLOC
+malloc_opt
+mblen
+mbrlen
+mbrtowc
+mbsinit
+mbsrtowcs 64
+mbstowcs
+mbtowc
+memccpy 64
+memchr 64
memcmp
-memcpy 64
-memmove 64
-memset 64
+memcpy 64
+memmove 64
+memset 64
mkdir
mkstemp
-mktemp 64
-mmap 64
+mktemp 64
+mktime
+mmap 64
+modf FLOAT64 DPML
+modfl FLOAT64_VAXD
+mprotect
+mrand48
+msync
munmap
+mvwaddstr
+mvwin
nanosleep
+newwin
+nextafter FLOAT64_VAXD DPML
+nextafterl FLOAT64_VAXD
+nice
+nint FLOAT64_VAXD DPML
+nintl FLOAT64_VAXD
nl_langinfo
+nrand48
+ntohl
+ntohs
open
opendir
+optarg GA 32ONLY
+opterr GL 32ONLY
+optind GL 32ONLY
+optopt GL 32ONLY
+overlay
+overwrite
pathconf
+pause
pclose
perror
pipe
+poll
popen
-pow FLOAT
-printf FLOAT LDBL
+# pow DPML version ???
+pow FLOAT64 FLOATV2
+powf FLOAT32 FLOATV2
+powl FLOAT64 FLOAT128 FLOATV2
+pread
+printf FLOAT64 FLOAT128
+printf__cf FLOAT64 FLOAT128
+printw FLOAT64 FLOAT128
putc
+putc_unlocked
putchar
+putchar_unlocked
putenv
puts
-qsort 64
+putw
+putwc
+putwchar
+pwrite
+qabs
+qdiv
+qsort 64
raise
+rand
+rand_r
random
read
readdir
-realloc 64 MALLOC
+readdir_r 64
+readlink
+readv 64
+realloc 64 MALLOC
+realloc_opt
+realpath 64
+record_read
recv
-recvfrom
-recvmsg BSD44 64
+recvfrom BSD44
+recvmsg BSD44
+remainder DPML
remove
rename
rewind
-rindex 64
+rewinddir
+rindex 64
+rint FLOAT64_VAXD DPML
+rintl FLOAT64_VAXD
rmdir
-scanf FLOAT LDBL
+rtl_private
+# sbrk # Makes libiberty/xmalloc.c fails to build.
+scalb FLOAT64_VAXD DPML
+scalbl FLOAT64_VAXD
+scanf FLOAT64 FLOAT128
+scanw FLOAT64 FLOAT128
+scroll
+seed48
+seekdir
select
send
-sendmsg BSD44 64
-sendto
+sendmsg BSD44
+sendto BSD44
+set_new_handler__xpxv_v
setbuf
setenv
+seteuid
+setgid
+setgrent
+sethostent
+setitimer
+setkey
setlocale
+setnetent
+setpgid
+setpgrp
+setprotoent
setpwent
+setregid
+setreuid
+setservent
+setsid
setsockopt
+setstate
+setuid
setvbuf
+shm_open
+shm_unlink
+shutdown
+sigaction
+sigaddset
+sigblock
+sigdelset
+sigemptyset
+sigfillset
+sighold
+sigignore
+sigismember
siglongjmp
+sigmask
signal
+signgam GL
+sigpause
+sigpending
+sigprocmask
+sigrelse
sigsetjmp
sigsetmask
-sin FLOAT
+sigstack
+sigsuspend
+sigtimedwait
+sigvec
+sigwait
+sigwaitinfo
+sin FLOAT64 DPML
+sincos DPML
+sincosd DPML
+sind FLOAT64_VAXD DPML
+sindl FLOAT64_VAXD
+sinh FLOAT64 DPML
+sinhcosh DPML
+sinhl FLOAT64_VAXD
+sinl FLOAT64_VAXD
sleep
-snprintf FLOAT LDBL
+snprintf FLOAT64 FLOAT128
socket
-sprintf FLOAT LDBL
-sqrt FLOAT
-sscanf FLOAT LDBL
+socketpair
+sprintf FLOAT64 FLOAT128
+sprintf__cf FLOAT64 FLOAT128
+sqrt FLOAT64 DPML
+sqrtl FLOAT64_VAXD
+srand
+srand48
+srandom
+sscanf FLOAT64 FLOAT128
+ssignal
stat
+statvfs
strcasecmp
-strcat 64
-strchr 64
+strcat 64
+strchr 64
strcmp
-strcpy 64
+strcoll
+strcpy 64
strcspn
-strdup 64 MALLOC
+strdup 64 MALLOC
strerror
+strfmon FLOAT64
+strftime
strlen
strncasecmp
-strncat 64
+strncat 64
strncmp
-strncpy 64
-strpbrk 64
-strrchr 64
+strncpy 64
+strnlen
+strpbrk 64
+strptime 64
+strptime_xpg4
+strrchr 64
+strsep 64
strspn
-strstr 64
-strtod 64 FLOAT
-strtok 64 MALLOC
-strtok_r 64 MALLOC
-strtol 64
-strtoul 64
+strstr 64
+strtod FLOAT64 64
+strtok 64
+strtok_r 64
+strtol 64
+strtoll 64
+strtoq 64
+strtoul 64
+strtoull 64
+strtouq 64
+strxfrm
+subwin
+swab
+swprintf FLOAT64 FLOAT128
+swscanf FLOAT64 FLOAT128
+symlink
+sys_errlist GA
+sys_nerr GL
sysconf
system
-tan FLOAT
+tan FLOAT64 DPML
+tand FLOAT64_VAXD DPML
+tandl FLOAT64_VAXD
+tanh FLOAT64 DPML
+tanhl FLOAT64_VAXD
+tanl FLOAT64_VAXD
+telldir
tempnam
+tgamma DPML
time
times
+timezone GL
tmpfile
-tmpnam 64
+tmpnam 64
+toascii
tolower
+touchwin
toupper
+towctrans
+towlower
+towupper
+trunc FLOAT64_VAXD DPML
+truncate
+truncl FLOAT64_VAXD
ttyname
+ttyname_r
+tzname GA
+tzset
+ualarm
umask
+uname
ungetc
+ungetwc
unlink
+unordered FLOAT64_VAXD DPML
+unorderedl FLOAT64_VAXD
+unsetenv
usleep
utime
-vfprintf FLOAT LDBL
-vprintf FLOAT LDBL
-vsnprintf FLOAT LDBL
-vsprintf FLOAT LDBL
+utimes
+vaxc$calloc_opt
+vaxc$cfree_opt
+vaxc$crtl_init
+vaxc$errno GA
+vaxc$free_opt
+vaxc$get_sdc
+vaxc$malloc_opt
+vaxc$realloc_opt
+vfprintf FLOAT64 FLOAT128
+vfscanf FLOAT64 FLOAT128
+vfwprintf FLOAT64 FLOAT128
+vfwscanf FLOAT64 FLOAT128
+vprintf FLOAT64 FLOAT128
+vscanf FLOAT64 FLOAT128
+vsnprintf FLOAT64 FLOAT128
+vsprintf FLOAT64 FLOAT128
+vsscanf FLOAT64 FLOAT128
+vswprintf FLOAT64 FLOAT128
+vswscanf FLOAT64 FLOAT128
+vwprintf FLOAT64 FLOAT128
+vwscanf FLOAT64 FLOAT128
+waddch
+waddstr
wait
+wait3
+wait4
waitpid
+wclear
+wclrattr
+wclrtobot
+wclrtoeol
+wcrtomb
+wcscat 64
+wcschr 64
+wcscmp
+wcscoll
+wcscpy 64
+wcscspn
+wcsftime
+wcslen
+wcsncat 64
+wcsncmp
+wcsncpy 64
+wcspbrk 64
+wcsrchr 64
+wcsrtombs 64
+wcsspn
+wcsstr 64
+wcstod FLOAT64 64
+wcstok 64
+wcstol 64
+wcstombs
+wcstoul 64
+wcswcs 64
wcswidth
+wcsxfrm
+wctob
+wctomb
+wctrans
+wctype
+wcwidth
+wdelch
+wdeleteln
+werase
+wgetch
+wgetstr
+winch
+winsch
+winsertln
+winsstr
+wmemchr 64
+wmemcmp
+wmemcpy 64
+wmemmove 64
+wmemset 64
+wmove
+wprintf FLOAT64 FLOAT128
+wprintw FLOAT64 FLOAT128
+wrefresh
write
+writev
+wscanf FLOAT64 FLOAT128
+wscanw FLOAT64 FLOAT128
+wsetattr
+wstandend
+wstandout
+y0 FLOAT64_VAXD DPML
+y0l FLOAT64_VAXD
+y1 FLOAT64_VAXD DPML
+y1l FLOAT64_VAXD
+yn FLOAT64_VAXD DPML
+ynl FLOAT64_VAXD
diff --git a/gcc/config/vms/vms-f.c b/gcc/config/vms/vms-f.c
new file mode 100644
index 00000000000..3c3ba414380
--- /dev/null
+++ b/gcc/config/vms/vms-f.c
@@ -0,0 +1,31 @@
+/* VMS support needed only by Fortran frontends.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+
+void
+vms_c_register_includes (const char *sysroot ATTRIBUTE_UNUSED,
+ const char *iprefix ATTRIBUTE_UNUSED,
+ int stdinc ATTRIBUTE_UNUSED)
+{
+ /* No-op for fortran. */
+}
diff --git a/gcc/config/vms/vms.c b/gcc/config/vms/vms.c
index a85fb3fb209..d4ebd18730b 100644
--- a/gcc/config/vms/vms.c
+++ b/gcc/config/vms/vms.c
@@ -26,6 +26,8 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h"
#include "target.h"
#include "output.h"
+#include "tm.h"
+#include "dwarf2out.h"
/* Correlation of standard CRTL names with DECCRTL function names. */
@@ -36,19 +38,46 @@ along with GCC; see the file COPYING3. If not see
/* If long pointer are enabled, use _NAME64 instead. */
#define VMS_CRTL_64 (1 << 1)
-/* Use tNAME instead. To be applied after the previous rule. */
-#define VMS_CRTL_FLOAT (1 << 2)
+/* Prepend s/f before the name. To be applied after the previous rule.
+ use 's' for S float, 'f' for IEEE 32. */
+#define VMS_CRTL_FLOAT32 (1 << 2)
-/* Prepend __bsd44__ before the name. To be applied after the P64
- rule. */
-#define VMS_CRTL_BSD44 (1 << 3)
+/* Prepend t/g/d before the name. To be applied after the previous rule.
+ use 'g' for VAX G float, 'd' for VAX D float, 't' for IEEE 64. */
+#define VMS_CRTL_FLOAT64 (1 << 3)
+
+/* Prepend d before the name, only if using VAX fp. */
+#define VMS_CRTL_FLOAT64_VAXD (1 << 4)
/* Prepend x before the name for if 128 bit long doubles are enabled. This
concern mostly 'printf'-like functions. */
-#define VMS_CRTL_LDBL (1 << 4)
+#define VMS_CRTL_FLOAT128 (1 << 5)
+
+/* From xxx, create xxx, xxxf, xxxl using MATH$XXX_T, MATH$XXX_S
+ and MATH$XXX{_X} if DPML is used. */
+#define VMS_CRTL_DPML (1 << 6)
-/* Prepend ga_ for global data. */
-#define VMS_CRTL_GLOBAL (1 << 5)
+/* Together with DPML, it means that all variant (ie xxx, xxxf and xxxl) are
+ overridden by decc. Without DPML, it means this is a variant (ie xxxf
+ or xxxl) of a function. */
+#define VMS_CRTL_NODPML (1 << 7)
+
+/* Prepend __bsd44_ before the name. To be applied after the P64
+ rule. */
+#define VMS_CRTL_BSD44 (1 << 8)
+
+/* Define only in 32 bits mode, as this has no 64 bit variants.
+ Concerns getopt/getarg. */
+#define VMS_CRTL_32ONLY (1 << 9)
+
+/* GLobal data prefix (ga_, gl_...) */
+#define VMS_CRTL_G_MASK (7 << 10)
+#define VMS_CRTL_G_NONE (0 << 10)
+#define VMS_CRTL_GA (1 << 10)
+#define VMS_CRTL_GL (2 << 10)
+
+/* Append '_2'. Not compatible with 64. */
+#define VMS_CRTL_FLOATV2 (1 << 13)
struct vms_crtl_name
{
@@ -84,14 +113,14 @@ vms_add_crtl_xlat (const char *name, size_t nlen,
{
tree targ;
+ /* printf ("vms crtl: %.*s -> %.*s\n", nlen, name, id_len, id_str); */
+
targ = get_identifier_with_length (name, nlen);
gcc_assert (!IDENTIFIER_TRANSPARENT_ALIAS (targ));
IDENTIFIER_TRANSPARENT_ALIAS (targ) = 1;
TREE_CHAIN (targ) = get_identifier_with_length (id_str, id_len);
VEC_safe_push (tree, gc, aliases_id, targ);
-
- /* printf ("vms: %s (%p) -> %.*s\n", name, targ, id_len, id_str); */
}
/* Do VMS specific stuff on builtins: disable the ones that are not
@@ -116,7 +145,48 @@ vms_patch_builtins (void)
const struct vms_crtl_name *n = &vms_crtl_names[i];
char res[VMS_CRTL_MAXLEN + 3 + 9 + 1 + 1];
int rlen;
- int nlen;
+ int nlen = strlen (n->name);
+
+ /* Discard 32ONLY if using 64 bit pointers. */
+ if ((n->flags & VMS_CRTL_32ONLY)
+ && flag_vms_pointer_size == VMS_POINTER_SIZE_64)
+ continue;
+
+ /* Handle DPML unless overridden by decc. */
+ if ((n->flags & VMS_CRTL_DPML)
+ && !(n->flags & VMS_CRTL_NODPML))
+ {
+ const char *p;
+ char alt[VMS_CRTL_MAXLEN + 3];
+
+ memcpy (res, "MATH$", 5);
+ rlen = 5;
+ for (p = n->name; *p; p++)
+ res[rlen++] = TOUPPER (*p);
+ res[rlen++] = '_';
+ res[rlen++] = 'T';
+
+ /* Double version. */
+ if (!(n->flags & VMS_CRTL_FLOAT64))
+ vms_add_crtl_xlat (n->name, nlen, res, rlen);
+
+ /* Float version. */
+ res[rlen - 1] = 'S';
+ memcpy (alt, n->name, nlen);
+ alt[nlen] = 'f';
+ vms_add_crtl_xlat (alt, nlen + 1, res, rlen);
+
+ /* Long double version. */
+ res[rlen - 1] = (LONG_DOUBLE_TYPE_SIZE == 128 ? 'X' : 'T');
+ alt[nlen] = 'l';
+ vms_add_crtl_xlat (alt, nlen + 1, res, rlen);
+
+ if (!(n->flags & (VMS_CRTL_FLOAT32 | VMS_CRTL_FLOAT64)))
+ continue;
+ }
+
+ if (n->flags & VMS_CRTL_FLOAT64_VAXD)
+ continue;
/* Add the dec-c prefix. */
memcpy (res, "decc$", 5);
@@ -124,27 +194,49 @@ vms_patch_builtins (void)
if (n->flags & VMS_CRTL_BSD44)
{
- memcpy (res + rlen, "__bsd44__", 9);
- rlen += 9;
+ memcpy (res + rlen, "__bsd44_", 8);
+ rlen += 8;
}
- if (n->flags & VMS_CRTL_GLOBAL)
+ if ((n->flags & VMS_CRTL_G_MASK) != VMS_CRTL_G_NONE)
{
- memcpy (res + rlen, "ga_", 3);
- rlen += 3;
+ res[rlen++] = 'g';
+ switch (n->flags & VMS_CRTL_G_MASK)
+ {
+ case VMS_CRTL_GA:
+ res[rlen++] = 'a';
+ break;
+ case VMS_CRTL_GL:
+ res[rlen++] = 'l';
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ res[rlen++] = '_';
}
- if (n->flags & VMS_CRTL_FLOAT)
+ if (n->flags & VMS_CRTL_FLOAT32)
+ res[rlen++] = 'f';
+
+ if (n->flags & VMS_CRTL_FLOAT64)
res[rlen++] = 't';
- if (n->flags & VMS_CRTL_LDBL)
+ if ((n->flags & VMS_CRTL_FLOAT128) && LONG_DOUBLE_TYPE_SIZE == 128)
res[rlen++] = 'x';
- nlen = strlen (n->name);
memcpy (res + rlen, n->name, nlen);
if ((n->flags & VMS_CRTL_64) == 0)
- vms_add_crtl_xlat (n->name, nlen, res, rlen + nlen);
+ {
+ rlen += nlen;
+
+ if (n->flags & VMS_CRTL_FLOATV2)
+ {
+ res[rlen++] = '_';
+ res[rlen++] = '2';
+ }
+ vms_add_crtl_xlat (n->name, nlen, res, rlen);
+ }
else
{
char alt[VMS_CRTL_MAXLEN + 3];
diff --git a/gcc/configure b/gcc/configure
index db5459a42ad..c1b0e465c35 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -9182,7 +9182,7 @@ else
# read() to the same fd. The only system known to have a problem here
# is VMS, where text files have record structure.
case "$host_os" in
- vms* | ultrix*)
+ *vms* | ultrix*)
gcc_cv_func_mmap_file=no ;;
*)
gcc_cv_func_mmap_file=yes;;
@@ -9206,7 +9206,7 @@ else
# Systems known to be in this category are Windows (all variants),
# VMS, and Darwin.
case "$host_os" in
- vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00)
+ *vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00)
gcc_cv_func_mmap_dev_zero=no ;;
*)
gcc_cv_func_mmap_dev_zero=yes;;
@@ -9263,7 +9263,7 @@ else
# above for use of /dev/zero.
# Systems known to be in this category are Windows, VMS, and SCO Unix.
case "$host_os" in
- vms* | cygwin* | pe | mingw* | sco* | udk* )
+ *vms* | cygwin* | pe | mingw* | sco* | udk* )
gcc_cv_func_mmap_anon=no ;;
*)
gcc_cv_func_mmap_anon=yes;;
diff --git a/gcc/configure.ac b/gcc/configure.ac
index d860b2b153f..8869121f768 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -1059,7 +1059,7 @@ fi
AC_CHECK_TYPE(ssize_t, int)
AC_CHECK_TYPE(caddr_t, char *)
-gcc_AC_FUNC_MMAP_BLACKLIST
+GCC_AC_FUNC_MMAP_BLACKLIST
case "${host}" in
*-*-*vms*)
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b8a6b5cb4c5..89ea02d1935 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,36 @@
+2012-04-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50043
+ * class.c (deduce_noexcept_on_destructor,
+ deduce_noexcept_on_destructors): New.
+ (check_bases_and_members): Call the latter.
+ * decl.c (grokfndecl): Call the former.
+ * method.c (implicitly_declare_fn): Not static.
+ * cp-tree.h (deduce_noexcept_on_destructor, implicitly_declare_fn):
+ Declare
+
+2012-03-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/52718
+ * decl.c (check_default_argument): With -Wzero-as-null-pointer-constant
+ warn for a zero as null pointer constant default argument.
+
+2012-03-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/52685
+ * tree.c (copy_binfo): Handle BINFO_DEPENDENT_BASE_P.
+
+2012-03-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/52759
+ * decl.c (start_decl): Don't call maybe_apply_pragma_weak
+ if processing_template_decl.
+
+2012-03-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/52743
+ * call.c (compare_ics): Handle ck_aggr like ck_list.
+
2012-03-28 Jason Merrill <jason@redhat.com>
PR c++/52746
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 88733f50227..3c3dabb74a0 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -7620,7 +7620,7 @@ compare_ics (conversion *ics1, conversion *ics2)
Specifically, we need to do the reference binding comparison at the
end of this function. */
- if (ics1->user_conv_p || ics1->kind == ck_list)
+ if (ics1->user_conv_p || ics1->kind == ck_list || ics1->kind == ck_aggr)
{
conversion *t1;
conversion *t2;
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index bc17c82c6a0..7b6559c4231 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -4321,6 +4321,41 @@ clone_constructors_and_destructors (tree t)
clone_function_decl (OVL_CURRENT (fns), /*update_method_vec_p=*/1);
}
+/* Deduce noexcept for a destructor DTOR. */
+
+void
+deduce_noexcept_on_destructor (tree dtor)
+{
+ if (!TYPE_RAISES_EXCEPTIONS (TREE_TYPE (dtor)))
+ {
+ tree ctx = DECL_CONTEXT (dtor);
+ tree implicit_fn = implicitly_declare_fn (sfk_destructor, ctx,
+ /*const_p=*/false);
+ tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn));
+ TREE_TYPE (dtor) = build_exception_variant (TREE_TYPE (dtor), eh_spec);
+ }
+}
+
+/* For each destructor in T, deduce noexcept:
+
+ 12.4/3: A declaration of a destructor that does not have an
+ exception-specification is implicitly considered to have the
+ same exception-specification as an implicit declaration (15.4). */
+
+static void
+deduce_noexcept_on_destructors (tree t)
+{
+ tree fns;
+
+ /* If for some reason we don't have a CLASSTYPE_METHOD_VEC, we bail
+ out now. */
+ if (!CLASSTYPE_METHOD_VEC (t))
+ return;
+
+ for (fns = CLASSTYPE_DESTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+ deduce_noexcept_on_destructor (OVL_CURRENT (fns));
+}
+
/* Subroutine of set_one_vmethod_tm_attributes. Search base classes
of TYPE for virtual functions which FNDECL overrides. Return a
mask of the tm attributes found therein. */
@@ -4994,6 +5029,10 @@ check_bases_and_members (tree t)
cant_have_const_ctor = 0;
no_const_asn_ref = 0;
+ /* Deduce noexcept on destructors. */
+ if (cxx_dialect >= cxx0x)
+ deduce_noexcept_on_destructors (t);
+
/* Check all the base-classes. */
check_bases (t, &cant_have_const_ctor,
&no_const_asn_ref);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 7d986a8cf73..8bca1fa0b63 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4978,6 +4978,7 @@ extern void fixup_attribute_variants (tree);
extern tree* decl_cloned_function_p (const_tree, bool);
extern void clone_function_decl (tree, int);
extern void adjust_clone_args (tree);
+extern void deduce_noexcept_on_destructor (tree);
/* in cvt.c */
extern tree convert_to_reference (tree, tree, int, int, tree);
@@ -5264,6 +5265,8 @@ extern tree get_copy_assign (tree);
extern tree get_default_ctor (tree);
extern tree get_dtor (tree, tsubst_flags_t);
extern tree locate_ctor (tree);
+extern tree implicitly_declare_fn (special_function_kind, tree,
+ bool);
/* In optimize.c */
extern bool maybe_clone_body (tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index f021edf36e5..d210f199a2d 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -4431,7 +4431,8 @@ start_decl (const cp_declarator *declarator,
}
/* If #pragma weak was used, mark the decl weak now. */
- maybe_apply_pragma_weak (decl);
+ if (!processing_template_decl)
+ maybe_apply_pragma_weak (decl);
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_DECLARED_INLINE_P (decl)
@@ -7447,6 +7448,13 @@ grokfndecl (tree ctype,
if (ctype != NULL_TREE)
grokclassfn (ctype, decl, flags);
+ /* 12.4/3 */
+ if (cxx_dialect >= cxx0x
+ && DECL_DESTRUCTOR_P (decl)
+ && !TYPE_BEING_DEFINED (DECL_CONTEXT (decl))
+ && !processing_template_decl)
+ deduce_noexcept_on_destructor (decl);
+
decl = check_explicit_specialization (orig_declarator, decl,
template_count,
2 * funcdef_flag +
@@ -10595,6 +10603,17 @@ check_default_argument (tree decl, tree arg)
return error_mark_node;
}
+ if (warn_zero_as_null_pointer_constant
+ && c_inhibit_evaluation_warnings == 0
+ && (POINTER_TYPE_P (decl_type) || TYPE_PTR_TO_MEMBER_P (decl_type))
+ && null_ptr_cst_p (arg)
+ && !NULLPTR_TYPE_P (TREE_TYPE (arg)))
+ {
+ warning (OPT_Wzero_as_null_pointer_constant,
+ "zero as null pointer constant");
+ return nullptr_node;
+ }
+
/* [dcl.fct.default]
Local variables shall not be used in default argument
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 0d4793eb23b..79bed4a053f 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1444,7 +1444,7 @@ explain_implicit_non_constexpr (tree decl)
reference argument or a non-const reference. Returns the
FUNCTION_DECL for the implicitly declared function. */
-static tree
+tree
implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
{
tree fn;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 9b410a75fd4..04ba37d25e7 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -17132,46 +17132,6 @@ more_specialized_fn (tree pat1, tree pat2, int len)
quals2 = cp_type_quals (arg2);
}
- if ((quals1 < 0) != (quals2 < 0))
- {
- /* Only of the args is a reference, see if we should apply
- array/function pointer decay to it. This is not part of
- DR214, but is, IMHO, consistent with the deduction rules
- for the function call itself, and with our earlier
- implementation of the underspecified partial ordering
- rules. (nathan). */
- if (quals1 >= 0)
- {
- switch (TREE_CODE (arg1))
- {
- case ARRAY_TYPE:
- arg1 = TREE_TYPE (arg1);
- /* FALLTHROUGH. */
- case FUNCTION_TYPE:
- arg1 = build_pointer_type (arg1);
- break;
-
- default:
- break;
- }
- }
- else
- {
- switch (TREE_CODE (arg2))
- {
- case ARRAY_TYPE:
- arg2 = TREE_TYPE (arg2);
- /* FALLTHROUGH. */
- case FUNCTION_TYPE:
- arg2 = build_pointer_type (arg2);
- break;
-
- default:
- break;
- }
- }
- }
-
arg1 = TYPE_MAIN_VARIANT (arg1);
arg2 = TYPE_MAIN_VARIANT (arg2);
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 87e9be84ecc..30ad5e1b7be 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1237,12 +1237,11 @@ copy_binfo (tree binfo, tree type, tree t, tree *igo_prev, int virt)
TREE_CHAIN (*igo_prev) = new_binfo;
*igo_prev = new_binfo;
- if (binfo)
+ if (binfo && !BINFO_DEPENDENT_BASE_P (binfo))
{
int ix;
tree base_binfo;
- gcc_assert (!BINFO_DEPENDENT_BASE_P (binfo));
gcc_assert (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), type));
BINFO_OFFSET (new_binfo) = BINFO_OFFSET (binfo);
@@ -1255,8 +1254,6 @@ copy_binfo (tree binfo, tree type, tree t, tree *igo_prev, int virt)
for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
{
tree new_base_binfo;
-
- gcc_assert (!BINFO_DEPENDENT_BASE_P (base_binfo));
new_base_binfo = copy_binfo (base_binfo, BINFO_TYPE (base_binfo),
t, igo_prev,
BINFO_VIRTUAL_P (base_binfo));
diff --git a/gcc/cprop.c b/gcc/cprop.c
index 024dd207655..ea6909195ac 100644
--- a/gcc/cprop.c
+++ b/gcc/cprop.c
@@ -1916,7 +1916,7 @@ execute_rtl_cprop (void)
changed = one_cprop_pass ();
flag_rerun_cse_after_global_opts |= changed;
if (changed)
- cleanup_cfg (0);
+ cleanup_cfg (CLEANUP_CFG_CHANGED);
return 0;
}
diff --git a/gcc/cse.c b/gcc/cse.c
index d8f07e95eac..5c32336c596 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -653,7 +653,7 @@ fixed_base_plus_p (rtx x)
/* Dump the expressions in the equivalence class indicated by CLASSP.
This function is used only for debugging. */
-void
+DEBUG_FUNCTION void
dump_class (struct table_elt *classp)
{
struct table_elt *elt;
@@ -6519,7 +6519,7 @@ cse_extended_basic_block (struct cse_basic_block_data *ebb_data)
Return 1 if the CFG should be cleaned up because it has been modified.
Return 0 otherwise. */
-int
+static int
cse_main (rtx f ATTRIBUTE_UNUSED, int nregs)
{
struct cse_basic_block_data ebb_data;
diff --git a/gcc/double-int.c b/gcc/double-int.c
index 0f954425093..d0fde0ed89f 100644
--- a/gcc/double-int.c
+++ b/gcc/double-int.c
@@ -228,7 +228,7 @@ rshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
/* Zero / sign extend all bits that are beyond the precision. */
- if (count >= (HOST_WIDE_INT)prec)
+ if (count >= prec)
{
*hv = signmask;
*lv = signmask;
diff --git a/gcc/dse.c b/gcc/dse.c
index a9fe9249369..d6c8de7fad8 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -44,7 +44,6 @@ along with GCC; see the file COPYING3. If not see
#include "insn-config.h"
#include "expr.h"
#include "recog.h"
-#include "dse.h"
#include "optabs.h"
#include "dbgcnt.h"
#include "target.h"
@@ -614,7 +613,6 @@ static bitmap kill_on_calls;
static unsigned int current_position;
-static bool gate_dse (void);
static bool gate_dse1 (void);
static bool gate_dse2 (void);
@@ -625,28 +623,6 @@ static bool gate_dse2 (void);
Initialization.
----------------------------------------------------------------------------*/
-/* Hashtable callbacks for maintaining the "bases" field of
- store_group_info, given that the addresses are function invariants. */
-
-static int
-clear_alias_mode_eq (const void *p1, const void *p2)
-{
- const struct clear_alias_mode_holder * h1
- = (const struct clear_alias_mode_holder *) p1;
- const struct clear_alias_mode_holder * h2
- = (const struct clear_alias_mode_holder *) p2;
- return h1->alias_set == h2->alias_set;
-}
-
-
-static hashval_t
-clear_alias_mode_hash (const void *p)
-{
- const struct clear_alias_mode_holder *holder
- = (const struct clear_alias_mode_holder *) p;
- return holder->alias_set;
-}
-
/* Find the entry associated with ALIAS_SET. */
@@ -3044,85 +3020,6 @@ dse_step2_spill (void)
----------------------------------------------------------------------------*/
-/* Note that this is NOT a general purpose function. Any mem that has
- an alias set registered here expected to be COMPLETELY unaliased:
- i.e it's addresses are not and need not be examined.
-
- It is known that all references to this address will have this
- alias set and there are NO other references to this address in the
- function.
-
- Currently the only place that is known to be clean enough to use
- this interface is the code that assigns the spill locations.
-
- All of the mems that have alias_sets registered are subjected to a
- very powerful form of dse where function calls, volatile reads and
- writes, and reads from random location are not taken into account.
-
- It is also assumed that these locations go dead when the function
- returns. This assumption could be relaxed if there were found to
- be places that this assumption was not correct.
-
- The MODE is passed in and saved. The mode of each load or store to
- a mem with ALIAS_SET is checked against MEM. If the size of that
- load or store is different from MODE, processing is halted on this
- alias set. For the vast majority of aliases sets, all of the loads
- and stores will use the same mode. But vectors are treated
- differently: the alias set is established for the entire vector,
- but reload will insert loads and stores for individual elements and
- we do not necessarily have the information to track those separate
- elements. So when we see a mode mismatch, we just bail. */
-
-
-void
-dse_record_singleton_alias_set (alias_set_type alias_set,
- enum machine_mode mode)
-{
- struct clear_alias_mode_holder tmp_holder;
- struct clear_alias_mode_holder *entry;
- void **slot;
-
- /* If we are not going to run dse, we need to return now or there
- will be problems with allocating the bitmaps. */
- if ((!gate_dse()) || !alias_set)
- return;
-
- if (!clear_alias_sets)
- {
- clear_alias_sets = BITMAP_ALLOC (NULL);
- disqualified_clear_alias_sets = BITMAP_ALLOC (NULL);
- clear_alias_mode_table = htab_create (11, clear_alias_mode_hash,
- clear_alias_mode_eq, NULL);
- clear_alias_mode_pool = create_alloc_pool ("clear_alias_mode_pool",
- sizeof (struct clear_alias_mode_holder), 100);
- }
-
- bitmap_set_bit (clear_alias_sets, alias_set);
-
- tmp_holder.alias_set = alias_set;
-
- slot = htab_find_slot (clear_alias_mode_table, &tmp_holder, INSERT);
- gcc_assert (*slot == NULL);
-
- *slot = entry =
- (struct clear_alias_mode_holder *) pool_alloc (clear_alias_mode_pool);
- entry->alias_set = alias_set;
- entry->mode = mode;
-}
-
-
-/* Remove ALIAS_SET from the sets of stack slots being considered. */
-
-void
-dse_invalidate_singleton_alias_set (alias_set_type alias_set)
-{
- if ((!gate_dse()) || !alias_set)
- return;
-
- bitmap_clear_bit (clear_alias_sets, alias_set);
-}
-
-
/* Look up the bitmap index for OFFSET in GROUP_INFO. If it is not
there, return 0. */
@@ -4015,12 +3912,6 @@ rest_of_handle_dse (void)
}
static bool
-gate_dse (void)
-{
- return gate_dse1 () || gate_dse2 ();
-}
-
-static bool
gate_dse1 (void)
{
return optimize > 0 && flag_dse
diff --git a/gcc/dse.h b/gcc/dse.h
deleted file mode 100644
index dca6ea04f9b..00000000000
--- a/gcc/dse.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* RTL dead store elimination.
- Copyright (C) 2007, 2010 Free Software Foundation, Inc.
-
- Contributed by Richard Sandiford <rsandifor@codesourcery.com>
- and Kenneth Zadeck <zadeck@naturalbridge.com>
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-#ifndef GCC_DSE_H
-#define GCC_DSE_H
-
-extern void dse_record_singleton_alias_set (alias_set_type, enum machine_mode);
-extern void dse_invalidate_singleton_alias_set (alias_set_type);
-
-#endif /* GCC_DSE_H */
-
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 828e996edb4..ca88fc56b10 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -17765,7 +17765,7 @@ common_block_die_table_eq (const void *x, const void *y)
static void
gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
{
- HOST_WIDE_INT off;
+ HOST_WIDE_INT off = 0;
tree com_decl;
tree decl_or_origin = decl ? decl : origin;
tree ultimate_origin;
diff --git a/gcc/except.c b/gcc/except.c
index ddc865217bd..e3a9ef07422 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -918,12 +918,6 @@ emit_to_new_bb_before (rtx seq, rtx insn)
bb = create_basic_block (seq, last, prev_bb);
update_bb_for_insn (bb);
bb->flags |= BB_SUPERBLOCK;
- if (current_loops)
- {
- add_bb_to_loop (bb, prev_bb->loop_father);
- if (prev_bb->loop_father->header == prev_bb)
- prev_bb->loop_father->header = bb;
- }
return bb;
}
@@ -995,6 +989,16 @@ dw2_build_landing_pads (void)
e = make_edge (bb, bb->next_bb, e_flags);
e->count = bb->count;
e->probability = REG_BR_PROB_BASE;
+ if (current_loops)
+ {
+ struct loop *loop = bb->next_bb->loop_father;
+ /* If we created a pre-header block, add the new block to the
+ outer loop, otherwise to the loop itself. */
+ if (bb->next_bb == loop->header)
+ add_bb_to_loop (bb, loop_outer (loop));
+ else
+ add_bb_to_loop (bb, loop);
+ }
}
}
diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c
index ee796cbb7e9..ff23092b1d7 100644
--- a/gcc/ggc-page.c
+++ b/gcc/ggc-page.c
@@ -121,14 +121,14 @@ along with GCC; see the file COPYING3. If not see
#define PAGE_L1_BITS (8)
#define PAGE_L2_BITS (32 - PAGE_L1_BITS - G.lg_pagesize)
-#define PAGE_L1_SIZE ((size_t) 1 << PAGE_L1_BITS)
-#define PAGE_L2_SIZE ((size_t) 1 << PAGE_L2_BITS)
+#define PAGE_L1_SIZE ((uintptr_t) 1 << PAGE_L1_BITS)
+#define PAGE_L2_SIZE ((uintptr_t) 1 << PAGE_L2_BITS)
#define LOOKUP_L1(p) \
- (((size_t) (p) >> (32 - PAGE_L1_BITS)) & ((1 << PAGE_L1_BITS) - 1))
+ (((uintptr_t) (p) >> (32 - PAGE_L1_BITS)) & ((1 << PAGE_L1_BITS) - 1))
#define LOOKUP_L2(p) \
- (((size_t) (p) >> G.lg_pagesize) & ((1 << PAGE_L2_BITS) - 1))
+ (((uintptr_t) (p) >> G.lg_pagesize) & ((1 << PAGE_L2_BITS) - 1))
/* The number of objects per allocation page, for objects on a page of
the indicated ORDER. */
@@ -560,7 +560,7 @@ ggc_allocated_p (const void *p)
base = &G.lookup[0];
#else
page_table table = G.lookup;
- size_t high_bits = (size_t) p & ~ (size_t) 0xffffffff;
+ uintptr_t high_bits = (uintptr_t) p & ~ (uintptr_t) 0xffffffff;
while (1)
{
if (table == NULL)
@@ -592,7 +592,7 @@ lookup_page_table_entry (const void *p)
base = &G.lookup[0];
#else
page_table table = G.lookup;
- size_t high_bits = (size_t) p & ~ (size_t) 0xffffffff;
+ uintptr_t high_bits = (uintptr_t) p & ~ (uintptr_t) 0xffffffff;
while (table->high_bits != high_bits)
table = table->next;
base = &table->table[0];
@@ -617,7 +617,7 @@ set_page_table_entry (void *p, page_entry *entry)
base = &G.lookup[0];
#else
page_table table;
- size_t high_bits = (size_t) p & ~ (size_t) 0xffffffff;
+ uintptr_t high_bits = (uintptr_t) p & ~ (uintptr_t) 0xffffffff;
for (table = G.lookup; table; table = table->next)
if (table->high_bits == high_bits)
goto found;
@@ -826,7 +826,7 @@ alloc_page (unsigned order)
alloc_size = entry_size + G.pagesize - 1;
allocation = XNEWVEC (char, alloc_size);
- page = (char *) (((size_t) allocation + G.pagesize - 1) & -G.pagesize);
+ page = (char *) (((uintptr_t) allocation + G.pagesize - 1) & -G.pagesize);
head_slop = page - allocation;
if (multiple_pages)
tail_slop = ((size_t) allocation + alloc_size) & (G.pagesize - 1);
@@ -1662,13 +1662,13 @@ init_ggc (void)
{
char *p = alloc_anon (NULL, G.pagesize, true);
struct page_entry *e;
- if ((size_t)p & (G.pagesize - 1))
+ if ((uintptr_t)p & (G.pagesize - 1))
{
/* How losing. Discard this one and try another. If we still
can't get something useful, give up. */
p = alloc_anon (NULL, G.pagesize, true);
- gcc_assert (!((size_t)p & (G.pagesize - 1)));
+ gcc_assert (!((uintptr_t)p & (G.pagesize - 1)));
}
/* We have a good page, might as well hold onto it... */
@@ -1782,7 +1782,7 @@ clear_marks (void)
size_t bitmap_size = BITMAP_SIZE (num_objects + 1);
/* The data should be page-aligned. */
- gcc_assert (!((size_t) p->page & (G.pagesize - 1)));
+ gcc_assert (!((uintptr_t) p->page & (G.pagesize - 1)));
/* Pages that aren't in the topmost context are not collected;
nevertheless, we need their in-use bit vectors to store GC
@@ -2204,7 +2204,7 @@ struct ggc_pch_ondisk
struct ggc_pch_data
{
struct ggc_pch_ondisk d;
- size_t base[NUM_ORDERS];
+ uintptr_t base[NUM_ORDERS];
size_t written[NUM_ORDERS];
};
@@ -2247,7 +2247,7 @@ ggc_pch_total_size (struct ggc_pch_data *d)
void
ggc_pch_this_base (struct ggc_pch_data *d, void *base)
{
- size_t a = (size_t) base;
+ uintptr_t a = (uintptr_t) base;
unsigned i;
for (i = 0; i < NUM_ORDERS; i++)
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 06e85eb8de2..baff0c9a5d9 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -10967,9 +10967,15 @@ class Struct_construction_expression : public Expression
Struct_construction_expression(Type* type, Expression_list* vals,
Location location)
: Expression(EXPRESSION_STRUCT_CONSTRUCTION, location),
- type_(type), vals_(vals)
+ type_(type), vals_(vals), traverse_order_(NULL)
{ }
+ // Set the traversal order, used to ensure that we implement the
+ // order of evaluation rules. Takes ownership of the argument.
+ void
+ set_traverse_order(std::vector<int>* traverse_order)
+ { this->traverse_order_ = traverse_order; }
+
// Return whether this is a constant initializer.
bool
is_constant_struct() const;
@@ -10991,8 +10997,12 @@ class Struct_construction_expression : public Expression
Expression*
do_copy()
{
- return new Struct_construction_expression(this->type_, this->vals_->copy(),
- this->location());
+ Struct_construction_expression* ret =
+ new Struct_construction_expression(this->type_, this->vals_->copy(),
+ this->location());
+ if (this->traverse_order_ != NULL)
+ ret->set_traverse_order(this->traverse_order_);
+ return ret;
}
tree
@@ -11010,6 +11020,9 @@ class Struct_construction_expression : public Expression
// The list of values, in order of the fields in the struct. A NULL
// entry means that the field should be zero-initialized.
Expression_list* vals_;
+ // If not NULL, the order in which to traverse vals_. This is used
+ // so that we implement the order of evaluation rules correctly.
+ std::vector<int>* traverse_order_;
};
// Traversal.
@@ -11017,9 +11030,26 @@ class Struct_construction_expression : public Expression
int
Struct_construction_expression::do_traverse(Traverse* traverse)
{
- if (this->vals_ != NULL
- && this->vals_->traverse(traverse) == TRAVERSE_EXIT)
- return TRAVERSE_EXIT;
+ if (this->vals_ != NULL)
+ {
+ if (this->traverse_order_ == NULL)
+ {
+ if (this->vals_->traverse(traverse) == TRAVERSE_EXIT)
+ return TRAVERSE_EXIT;
+ }
+ else
+ {
+ for (std::vector<int>::const_iterator p =
+ this->traverse_order_->begin();
+ p != this->traverse_order_->end();
+ ++p)
+ {
+ if (Expression::traverse(&this->vals_->at(*p), traverse)
+ == TRAVERSE_EXIT)
+ return TRAVERSE_EXIT;
+ }
+ }
+ }
if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
return TRAVERSE_EXIT;
return TRAVERSE_CONTINUE;
@@ -12198,6 +12228,7 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
size_t field_count = st->field_count();
std::vector<Expression*> vals(field_count);
+ std::vector<int>* traverse_order = new(std::vector<int>);
Expression_list::const_iterator p = this->vals_->begin();
while (p != this->vals_->end())
{
@@ -12350,6 +12381,7 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
type->named_type()->message_name().c_str());
vals[index] = val;
+ traverse_order->push_back(index);
}
Expression_list* list = new Expression_list;
@@ -12357,7 +12389,10 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
for (size_t i = 0; i < field_count; ++i)
list->push_back(vals[i]);
- return new Struct_construction_expression(type, list, location);
+ Struct_construction_expression* ret =
+ new Struct_construction_expression(type, list, location);
+ ret->set_traverse_order(traverse_order);
+ return ret;
}
// Lower an array composite literal.
diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h
index 090e893f25e..d58e6c5fcb0 100644
--- a/gcc/go/gofrontend/expressions.h
+++ b/gcc/go/gofrontend/expressions.h
@@ -842,6 +842,11 @@ class Expression_list
bool
contains_error() const;
+ // Retrieve an element by index.
+ Expression*&
+ at(size_t i)
+ { return this->entries_.at(i); }
+
// Return the first and last elements.
Expression*&
front()
diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index a01d050fbb7..45f52444122 100644
--- a/gcc/ira-color.c
+++ b/gcc/ira-color.c
@@ -821,7 +821,6 @@ setup_left_conflict_sizes_p (ira_allocno_t a)
node_preorder_num = node->preorder_num;
COPY_HARD_REG_SET (node_set, node->hard_regs->set);
node_check_tick++;
- curr_allocno_process++;
for (k = 0; k < nobj; k++)
{
ira_object_t obj = ALLOCNO_OBJECT (a, k);
@@ -838,12 +837,10 @@ setup_left_conflict_sizes_p (ira_allocno_t a)
conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
if (! ALLOCNO_COLOR_DATA (conflict_a)->in_graph_p
- || conflict_data->last_process == curr_allocno_process
|| ! hard_reg_set_intersect_p (profitable_hard_regs,
conflict_data
->profitable_hard_regs))
continue;
- conflict_data->last_process = curr_allocno_process;
conflict_node = conflict_data->hard_regs_node;
COPY_HARD_REG_SET (conflict_node_set, conflict_node->hard_regs->set);
if (hard_reg_set_subset_p (node_set, conflict_node_set))
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 974b83f15ec..3e6cb4d9dc9 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,16 @@
+2012-04-02 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * class.c (emit_register_classes_in_jcr_section): Set DECL_USER_ALIGN.
+ Clear TREE_READONLY.
+
+2012-03-29 Steven Bosscher <steven@gcc.gnu.org>
+
+ PR java/52730
+ * class.c (emit_register_classes_in_jcr_section): New function.
+ (emit_Jv_RegisterClass_calls): New function, split out from ...
+ (emit_register_classes): ... here. Reorganize. Do not call
+ output_constant.
+
2012-01-23 Andreas Schwab <schwab@linux-m68k.org>
* lang.c (java_init_options_struct): Set
diff --git a/gcc/java/class.c b/gcc/java/class.c
index ac69319349a..3c34abad7fe 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -2786,10 +2786,79 @@ emit_indirect_register_classes (tree *list_p)
append_to_statement_list (t, list_p);
}
+/* Emit a list of pointers to all classes we have emitted to JCR_SECTION. */
+
+static void
+emit_register_classes_in_jcr_section (void)
+{
+ tree klass, cdecl, class_array_type;
+ int i;
+ int size = VEC_length (tree, registered_class);
+ VEC(constructor_elt,gc) *init = VEC_alloc (constructor_elt, gc, size);
+
+#ifndef JCR_SECTION_NAME
+ /* A target has defined TARGET_USE_JCR_SECTION,
+ but doesn't have a JCR_SECTION_NAME. */
+ gcc_unreachable ();
+#endif
+
+ FOR_EACH_VEC_ELT (tree, registered_class, i, klass)
+ CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, build_fold_addr_expr (klass));
+
+ /* ??? I would like to use tree_output_constant_def() but there is no way
+ to put the data in a named section name, or to set the alignment,
+ via that function. So do everything manually here. */
+ class_array_type = build_prim_array_type (ptr_type_node, size);
+ cdecl = build_decl (UNKNOWN_LOCATION,
+ VAR_DECL, get_identifier ("_Jv_JCR_SECTION_data"),
+ class_array_type);
+ DECL_SECTION_NAME (cdecl) = build_string (strlen (JCR_SECTION_NAME),
+ JCR_SECTION_NAME);
+ DECL_ALIGN (cdecl) = POINTER_SIZE;
+ DECL_USER_ALIGN (cdecl) = 1;
+ DECL_INITIAL (cdecl) = build_constructor (class_array_type, init);
+ TREE_CONSTANT (DECL_INITIAL (cdecl)) = 1;
+ TREE_STATIC (cdecl) = 1;
+ TREE_READONLY (cdecl) = 0;
+ TREE_CONSTANT (cdecl) = 1;
+ DECL_ARTIFICIAL (cdecl) = 1;
+ DECL_IGNORED_P (cdecl) = 1;
+ pushdecl_top_level (cdecl);
+ relayout_decl (cdecl);
+ rest_of_decl_compilation (cdecl, 1, 0);
+ mark_decl_referenced (cdecl);
+}
+
+
+/* Emit a series of calls to _Jv_RegisterClass for every class we emitted.
+ A series of calls is added to LIST_P. */
+
+static void
+emit_Jv_RegisterClass_calls (tree *list_p)
+{
+ tree klass, t, register_class_fn;
+ int i;
+
+ t = build_function_type_list (void_type_node, class_ptr_type, NULL);
+ t = build_decl (input_location,
+ FUNCTION_DECL, get_identifier ("_Jv_RegisterClass"), t);
+ TREE_PUBLIC (t) = 1;
+ DECL_EXTERNAL (t) = 1;
+ register_class_fn = t;
+
+ FOR_EACH_VEC_ELT (tree, registered_class, i, klass)
+ {
+ t = build_fold_addr_expr (klass);
+ t = build_call_expr (register_class_fn, 1, t);
+ append_to_statement_list (t, list_p);
+ }
+}
/* Emit something to register classes at start-up time.
- The preferred mechanism is through the .jcr section, which contain
+ The default mechanism is to generate instances at run-time.
+
+ An alternative mechanism is through the .jcr section, which contain
a list of pointers to classes which get registered during constructor
invocation time.
@@ -2803,55 +2872,18 @@ emit_register_classes (tree *list_p)
if (registered_class == NULL)
return;
+ /* By default, generate instances of Class at runtime. */
if (flag_indirect_classes)
- {
- emit_indirect_register_classes (list_p);
- return;
- }
-
+ emit_indirect_register_classes (list_p);
/* TARGET_USE_JCR_SECTION defaults to 1 if SUPPORTS_WEAK and
TARGET_ASM_NAMED_SECTION, else 0. Some targets meet those conditions
but lack suitable crtbegin/end objects or linker support. These
targets can override the default in tm.h to use the fallback mechanism. */
- if (TARGET_USE_JCR_SECTION)
- {
- tree klass, t;
- int i;
-
-#ifdef JCR_SECTION_NAME
- switch_to_section (get_section (JCR_SECTION_NAME, SECTION_WRITE, NULL));
-#else
- /* A target has defined TARGET_USE_JCR_SECTION,
- but doesn't have a JCR_SECTION_NAME. */
- gcc_unreachable ();
-#endif
- assemble_align (POINTER_SIZE);
-
- FOR_EACH_VEC_ELT (tree, registered_class, i, klass)
- {
- t = build_fold_addr_expr (klass);
- output_constant (t, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE);
- }
- }
+ else if (TARGET_USE_JCR_SECTION)
+ emit_register_classes_in_jcr_section ();
+ /* Use the fallback mechanism. */
else
- {
- tree klass, t, register_class_fn;
- int i;
-
- t = build_function_type_list (void_type_node, class_ptr_type, NULL);
- t = build_decl (input_location,
- FUNCTION_DECL, get_identifier ("_Jv_RegisterClass"), t);
- TREE_PUBLIC (t) = 1;
- DECL_EXTERNAL (t) = 1;
- register_class_fn = t;
-
- FOR_EACH_VEC_ELT (tree, registered_class, i, klass)
- {
- t = build_fold_addr_expr (klass);
- t = build_call_expr (register_class_fn, 1, t);
- append_to_statement_list (t, list_p);
- }
- }
+ emit_Jv_RegisterClass_calls (list_p);
}
/* Build a constructor for an entry in the symbol table. */
diff --git a/gcc/loop-init.c b/gcc/loop-init.c
index b8d7b7ee7ce..03f8f610c97 100644
--- a/gcc/loop-init.c
+++ b/gcc/loop-init.c
@@ -158,15 +158,24 @@ loop_optimizer_finalize (void)
static bool
gate_handle_loop2 (void)
{
- return (optimize > 0
- && (flag_move_loop_invariants
- || flag_unswitch_loops
- || flag_peel_loops
- || flag_unroll_loops
+ if (optimize > 0
+ && (flag_move_loop_invariants
+ || flag_unswitch_loops
+ || flag_peel_loops
+ || flag_unroll_loops
#ifdef HAVE_doloop_end
- || (flag_branch_on_count_reg && HAVE_doloop_end)
+ || (flag_branch_on_count_reg && HAVE_doloop_end)
#endif
- ));
+ ))
+ return true;
+ else
+ {
+ /* No longer preserve loops, remove them now. */
+ cfun->curr_properties &= ~PROP_loops;
+ if (current_loops)
+ loop_optimizer_finalize ();
+ return false;
+ }
}
struct rtl_opt_pass pass_loop2 =
diff --git a/gcc/rtl.h b/gcc/rtl.h
index bf1e26d66c5..30931b74df7 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2373,7 +2373,6 @@ extern int rtx_to_tree_code (enum rtx_code);
/* In cse.c */
extern int delete_trivially_dead_insns (rtx, int);
-extern int cse_main (rtx, int);
extern int exp_equiv_p (const_rtx, const_rtx, int, bool);
extern unsigned hash_rtx (const_rtx x, enum machine_mode, int *, int *, bool);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 954e8fb1b4b..c757d42d177 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,87 @@
+2012-04-03 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/52808
+ * gcc.dg/pr52808.c: New testcase.
+
+2012-04-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/52835
+ * gfortran.dg/pr52835.f90: New test.
+
+2012-04-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/specs/aggr5.ads: New test.
+
+2012-04-02 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/52756
+ * gcc.dg/torture/pr52756.c: New testcase.
+
+2012-04-02 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/52803
+ * gcc.dg/pr52803.c: New testcase.
+
+2012-04-02 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/40942
+ * g++.old-deja/g++.pt/spec40.C: Adjust to take the resolution of
+ DR 214 in account.
+
+2012-04-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50043
+ * g++.dg/cpp0x/noexcept17.C: New.
+ * g++.old-deja/g++.eh/cleanup1.C: Adjust.
+ * g++.dg/tree-ssa/ehcleanup-1.C: Likewise.
+ * g++.dg/cpp0x/noexcept01.C: Likewise.
+ * g++.dg/eh/init-temp1.C: Likewise.
+ * g++.dg/eh/ctor1.C: Likwise.
+
+2012-03-31 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/controlled6.adb: New test.
+ * gnat.dg/controlled6_pkg.ads: New helper.
+ * gnat.dg/controlled6_pkg-iterators.ad[sb]: Likewise.
+
+2012-03-30 Richard Henderson <rth@redhat.com>
+
+ PR debug/52727
+ * g++.dg/opt/pr52727.C: New testcase.
+
+2012-03-30 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/52754
+ * gcc.target/i386/pr52754.c: New testcase.
+
+2012-03-30 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/52772
+ * g++.dg/torture/pr52772.C: New testcase.
+
+2012-03-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/52718
+ * g++.dg/warn/Wzero-as-null-pointer-constant-5.C: New.
+
+2012-03-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/52685
+ * g++.dg/template/inherit8.C: New.
+
+2012-03-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/52759
+ * g++.dg/ext/weak4.C: New test.
+
+ PR tree-optimization/52760
+ * gcc.c-torture/execute/pr52760.c: New test.
+
+2012-03-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/52743
+ * g++.dg/cpp0x/initlist-array3.C: New.
+
2012-03-28 Jason Merrill <jason@redhat.com>
PR c++/52746
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-array3.C b/gcc/testsuite/g++.dg/cpp0x/initlist-array3.C
new file mode 100644
index 00000000000..1a94f4ed55b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist-array3.C
@@ -0,0 +1,10 @@
+// PR c++/52743
+// { dg-do compile { target c++11 } }
+
+void composite (int const (&) [2]);
+void composite (int const (&) [3]);
+
+int main ()
+{
+ composite({0,1}); // { dg-error "ambiguous" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept01.C b/gcc/testsuite/g++.dg/cpp0x/noexcept01.C
index f314684eae8..b6be1ef7a3f 100644
--- a/gcc/testsuite/g++.dg/cpp0x/noexcept01.C
+++ b/gcc/testsuite/g++.dg/cpp0x/noexcept01.C
@@ -50,7 +50,7 @@ struct E
~E();
};
-SA (!noexcept (E()));
+SA (noexcept (E()));
struct F
{
@@ -74,7 +74,7 @@ void tf()
}
template void tf<int,true>();
-template void tf<E, false>();
+template void tf<E, true>();
// Make sure that noexcept uses the declared exception-specification, not
// any knowledge we might have about whether or not the function really
diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept17.C b/gcc/testsuite/g++.dg/cpp0x/noexcept17.C
new file mode 100644
index 00000000000..82cd844c067
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/noexcept17.C
@@ -0,0 +1,54 @@
+// PR c++/50043
+// { dg-options -std=c++11 }
+
+struct True1 {};
+struct True2 { ~True2(); };
+struct True3 { ~True3(){ throw 0; } };
+struct False { ~False() noexcept(false); };
+
+template <typename Base>
+struct A : Base
+{
+};
+
+template <typename Member>
+struct B
+{
+ Member mem;
+};
+
+template <typename Base, typename Member>
+struct C : Base
+{
+ Member mem;
+};
+
+#define SA(X) static_assert(X, #X)
+
+SA( noexcept(True1()));
+SA( noexcept(True2()));
+SA( noexcept(True3()));
+SA(!noexcept(False()));
+
+SA( noexcept(A<True1>()));
+SA( noexcept(A<True2>()));
+SA( noexcept(A<True3>()));
+SA(!noexcept(A<False>()));
+
+SA( noexcept(B<True1>()));
+SA( noexcept(B<True2>()));
+SA( noexcept(B<True3>()));
+SA(!noexcept(B<False>()));
+
+SA( noexcept(C<True1, True2>()));
+SA( noexcept(C<True1, True3>()));
+SA( noexcept(C<True2, True3>()));
+SA( noexcept(C<True2, True1>()));
+SA( noexcept(C<True3, True1>()));
+SA( noexcept(C<True3, True2>()));
+SA(!noexcept(C<False, True1>()));
+SA(!noexcept(C<False, True2>()));
+SA(!noexcept(C<False, True3>()));
+SA(!noexcept(C<True1, False>()));
+SA(!noexcept(C<True2, False>()));
+SA(!noexcept(C<True3, False>()));
diff --git a/gcc/testsuite/g++.dg/eh/ctor1.C b/gcc/testsuite/g++.dg/eh/ctor1.C
index 43b735f0b00..b959d1c5620 100644
--- a/gcc/testsuite/g++.dg/eh/ctor1.C
+++ b/gcc/testsuite/g++.dg/eh/ctor1.C
@@ -5,6 +5,12 @@
// PR 411
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#define NOEXCEPT_FALSE noexcept (false)
+#else
+#define NOEXCEPT_FALSE
+#endif
+
bool was_f_in_Bar_destroyed=false;
struct Foo
@@ -17,7 +23,7 @@ struct Foo
struct Bar
{
- ~Bar()
+ ~Bar() NOEXCEPT_FALSE
{
throw 1;
}
diff --git a/gcc/testsuite/g++.dg/eh/init-temp1.C b/gcc/testsuite/g++.dg/eh/init-temp1.C
index 529014f497f..4996cea230f 100644
--- a/gcc/testsuite/g++.dg/eh/init-temp1.C
+++ b/gcc/testsuite/g++.dg/eh/init-temp1.C
@@ -1,6 +1,12 @@
// PR c++/15764
// { dg-do run }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#define NOEXCEPT_FALSE noexcept (false)
+#else
+#define NOEXCEPT_FALSE
+#endif
+
extern "C" void abort ();
int thrown;
@@ -8,7 +14,7 @@ int thrown;
int as;
struct a {
a () { ++as; }
- ~a () { --as; if (thrown++ == 0) throw 42; }
+ ~a () NOEXCEPT_FALSE { --as; if (thrown++ == 0) throw 42; }
};
int f (a const&) { return 1; }
diff --git a/gcc/testsuite/g++.dg/ext/weak4.C b/gcc/testsuite/g++.dg/ext/weak4.C
new file mode 100644
index 00000000000..5b3cce05cd9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/weak4.C
@@ -0,0 +1,9 @@
+// PR c++/52759
+// { dg-do compile }
+// { dg-require-weak "" }
+// { dg-options "" }
+#pragma weak foo
+template <typename T>
+struct A { };
+template <typename T>
+void bar (A<T> &);
diff --git a/gcc/testsuite/g++.dg/opt/pr52727.C b/gcc/testsuite/g++.dg/opt/pr52727.C
new file mode 100644
index 00000000000..4dd38530a02
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr52727.C
@@ -0,0 +1,45 @@
+// { dg-do compile }
+// { dg-options "-g -Os" }
+
+int grow (int);
+void fn (int);
+struct A { int a1, a2; };
+template <typename T>
+struct B
+{
+ A *b;
+ ~B () { b3 (b); }
+ void b1 (int);
+ void b2 (int);
+ void b3 (A *);
+};
+struct C { int c1, c2, c3; bool c4; };
+int
+bar (int x)
+{
+ int y = x / 6;
+ if (y > x / 2)
+ return y;
+ return 0;
+}
+void baz (double, double);
+void
+foo (const C *x, int y, int z)
+{
+ B<int> p;
+ double r = y / 2;
+ int w = bar (int (r));
+ double s = y / 2 + 0.5;
+ double t = z / 2 + 0.5;
+ int u = x->c3;
+ int v = (x->c2 + u - 1 - x->c1) / u;
+ p.b2 ((2 * v > p.b->a1 || (2 * v < p.b->a2 && 2 * v < (p.b->a1 >> 1)))
+ ? grow (0) : p.b->a1);
+ for (int i = 0; i <= v; ++i)
+ {
+ double l = x->c4 ? 4.5 - i * 6.2 / v : (3.1 - i * 31 / v) / 6;
+ baz (s + (r - w) * l, t - (r - w) * l);
+ }
+}
+
+
diff --git a/gcc/testsuite/g++.dg/template/inherit8.C b/gcc/testsuite/g++.dg/template/inherit8.C
new file mode 100644
index 00000000000..a9b2bdb5601
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/inherit8.C
@@ -0,0 +1,13 @@
+// PR c++/52685
+
+template <typename T>
+struct A
+{
+ template <typename U>
+ struct B : public A <B<U> >
+ {
+ struct C : public B<U>
+ {
+ };
+ };
+};
diff --git a/gcc/testsuite/g++.dg/torture/pr52772.C b/gcc/testsuite/g++.dg/torture/pr52772.C
new file mode 100644
index 00000000000..810e6579fba
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr52772.C
@@ -0,0 +1,85 @@
+// { dg-do compile }
+
+typedef __SIZE_TYPE__ size_t;
+
+class c1;
+
+class c2 {
+ public: c2() { };
+ void *operator new(size_t size, const c1 & crc1);
+};
+
+class c3 {
+ public: c3() { _Obj = 0; }
+ ~c3() { if (_Obj) delete _Obj; }
+ void set(c2 *pObj);
+ protected: c2 *_Obj;
+};
+
+void c3::set(c2 *pObj) { _Obj = pObj; };
+
+template<class TYPE> class tc1 : public c2 {
+ public: tc1(int n=0){};
+ int get() const;
+ TYPE& operator[] (int id);
+ TYPE * _data;
+ int _size;
+};
+
+template<class TYPE> TYPE & tc1<TYPE>::operator[] (int id) {
+ return _data[id];
+}
+
+template<class TYPE> int tc1<TYPE>::get() const {
+ return _size;
+}
+
+class c4 {
+ public: c4();
+};
+
+class c5 : public c2 {
+ protected: c2 * _own;
+ public: c5(c2 *o) : _own(o) { }
+ c5(const c4 & box);
+ int add(const c4 & ext);
+};
+
+class c6 {
+ public: int get() const {};
+};
+
+class c7 {
+ friend class c8;
+ int find(c6 * loop) const;
+};
+
+class c8 {
+ const c1 & _rc1;
+ int tria(c7 * face, c5 * vtree0 = 0);
+};
+
+int c8::tria(c7 * face, c5 * vtree0) {
+ c6 *sLData[64];
+ tc1<c6*> loops(64);
+ while (loops.get() > 1) {
+ c6 *iloop = 0;
+ for (int j=1; j<loops.get(); j++) {
+ if (loops[j]->get() < 32) {
+ iloop = loops[j];
+ }
+ }
+ face->find(iloop);
+ }
+ c4 box;
+ c3 ctree;
+ c5 *vtree = vtree0;
+ if (!vtree) {
+ vtree = new (_rc1) c5(box);
+ ctree.set(vtree);
+ for (int j=0; j<1; j++) {
+ c4 sVBBox;
+ vtree->add(sVBBox);
+ }
+ }
+}
diff --git a/gcc/testsuite/g++.dg/tree-ssa/ehcleanup-1.C b/gcc/testsuite/g++.dg/tree-ssa/ehcleanup-1.C
index cc492a80975..0a29ce9cb4f 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/ehcleanup-1.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/ehcleanup-1.C
@@ -1,9 +1,16 @@
// { dg-options "-O2 -fdump-tree-ehcleanup1-details" }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#define NOEXCEPT_FALSE noexcept (false)
+#else
+#define NOEXCEPT_FALSE
+#endif
+
extern void can_throw ();
class a
{
public:
- ~a ()
+ ~a () NOEXCEPT_FALSE
{
if (0)
can_throw ();
diff --git a/gcc/testsuite/g++.dg/warn/Wzero-as-null-pointer-constant-5.C b/gcc/testsuite/g++.dg/warn/Wzero-as-null-pointer-constant-5.C
new file mode 100644
index 00000000000..185d2b5c4ee
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wzero-as-null-pointer-constant-5.C
@@ -0,0 +1,20 @@
+// PR c++/52718
+// { dg-options "-Wzero-as-null-pointer-constant" }
+
+struct foo
+{
+ foo(void* a = 0) {}; // { dg-warning "zero as null pointer" }
+};
+
+void* fun(void* a = 0) {}; // { dg-warning "zero as null pointer" }
+
+struct bar: foo
+{
+ bar() {};
+};
+
+struct baz
+{
+ baz(const foo& f1 = foo(),
+ void* f2 = fun()) {};
+};
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/cleanup1.C b/gcc/testsuite/g++.old-deja/g++.eh/cleanup1.C
index 16646438ed2..12f1ec7a081 100644
--- a/gcc/testsuite/g++.old-deja/g++.eh/cleanup1.C
+++ b/gcc/testsuite/g++.old-deja/g++.eh/cleanup1.C
@@ -2,6 +2,12 @@
// Bug: obj gets destroyed twice because the fixups for the return are
// inside its cleanup region.
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#define NOEXCEPT_FALSE noexcept (false)
+#else
+#define NOEXCEPT_FALSE
+#endif
+
extern "C" int printf (const char *, ...);
int d;
@@ -9,7 +15,7 @@ int d;
struct myExc { };
struct myExcRaiser {
- ~myExcRaiser() { throw myExc(); }
+ ~myExcRaiser() NOEXCEPT_FALSE { throw myExc(); }
};
struct stackObj {
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/spec40.C b/gcc/testsuite/g++.old-deja/g++.pt/spec40.C
index 70abb6fc50f..fc37f412b7e 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/spec40.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/spec40.C
@@ -1,14 +1,33 @@
-// { dg-do run }
+// { dg-do compile }
// Copyright (C) 2000 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 12 Feb 2001 <nathan@codesourcery.com>
-// More from bug 1617. We didn't resolve partial ordering properly. The
-// std is rather vague about it anyway, DR 214 talks about this.
+// More from bug 1617. The resolution of DR 214 implies that the below
+// call to Foo is ambiguous.
+//
+// The type transformation (on the function parameter of Foo) allowed
+// in the context of partial ordering of the Foo template overloads is
+// the following ([temp.deduct.partial]/5):
+//
+// Before the partial ordering is done, certain transformations
+// are performed on the types used for partial ordering:
+//
+// - If P is a reference type, P is replaced by the type
+// referred to.
+//
+// - If A is a reference type, A is replaced by the type
+// referred to.
+//
+// It follows that we are not allowed to apply array-to-pointer
+// decay conversion to the type of the function parameter
+// 'char const (&)[I]'. So the two Foo specializations should
+// be considered unrelated. Thus the partial ordering of the two
+// Foo specializations should fail.
template <typename T> int Foo (T const *) {return 1;}
template <unsigned I> int Foo (char const (&)[I]) {return 2;}
int main ()
{
- return Foo ("a") != 2;
+ return Foo ("a") != 2; // { dg-error "call of overloaded \[^\n\r\]* is ambiguous" }
}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr52760.c b/gcc/testsuite/gcc.c-torture/execute/pr52760.c
new file mode 100644
index 00000000000..1413c5f275a
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr52760.c
@@ -0,0 +1,27 @@
+/* PR tree-optimization/52760 */
+
+struct T { unsigned short a, b, c, d; };
+
+__attribute__((noinline, noclone)) void
+foo (int x, struct T *y)
+{
+ int i;
+
+ for (i = 0; i < x; i++)
+ {
+ y[i].a = ((0x00ff & y[i].a >> 8) | (0xff00 & y[i].a << 8));
+ y[i].b = ((0x00ff & y[i].b >> 8) | (0xff00 & y[i].b << 8));
+ y[i].c = ((0x00ff & y[i].c >> 8) | (0xff00 & y[i].c << 8));
+ y[i].d = ((0x00ff & y[i].d >> 8) | (0xff00 & y[i].d << 8));
+ }
+}
+
+int
+main ()
+{
+ struct T t = { 0x0001, 0x0203, 0x0405, 0x0607 };
+ foo (1, &t);
+ if (t.a != 0x0100 || t.b != 0x0302 || t.c != 0x0504 || t.d != 0x0706)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr52803.c b/gcc/testsuite/gcc.dg/pr52803.c
new file mode 100644
index 00000000000..6774b0c6d21
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr52803.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fno-move-loop-invariants" } */
+
+int main () { return 0; }
diff --git a/gcc/testsuite/gcc.dg/pr52808.c b/gcc/testsuite/gcc.dg/pr52808.c
new file mode 100644
index 00000000000..b731cb40133
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr52808.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O -ftracer" } */
+
+int **fn1 () __attribute__ ((__const__));
+int main ()
+{
+ int i;
+ i = 0;
+ for (;; i++)
+ if (*fn1 ()[i] && !'a' <= 0 && i <= 'z' || *fn1 ()[0] && 'a' <= 'z')
+ return;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr52756.c b/gcc/testsuite/gcc.dg/torture/pr52756.c
new file mode 100644
index 00000000000..175b414e17d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr52756.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+
+void Env_FetchObj0AttrOffset (unsigned int NumFields, int *Status)
+{
+ int Found = 0;
+ if (NumFields)
+ while ((*Status == 0) && NumFields-- > 0 && Found == 0)
+ Found = 1;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr52754.c b/gcc/testsuite/gcc.target/i386/pr52754.c
new file mode 100644
index 00000000000..0f2dbff2dd7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr52754.c
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fpredictive-commoning -msse2 -std=c99" } */
+/* { dg-require-effective-target sse2 } */
+
+#include <x86intrin.h>
+
+#include "isa-check.h"
+#include "sse-os-support.h"
+
+int main()
+{
+ const float mem[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+
+ unsigned int indexes[8];
+ for (unsigned int i = 0; i < 8; ++i) indexes[i] = i;
+
+ check_isa ();
+
+ if (!sse_os_support ())
+ exit (0);
+
+ __m128 x = _mm_setr_ps(0, 1, 2, 3);
+ for (unsigned int i = 0; i + 4 < 6; ++i) {
+ const unsigned int *ii = &indexes[i];
+ const __m128 tmp = _mm_setr_ps(mem[ii[0]], mem[ii[1]], mem[ii[2]], mem[ii[3]]);
+ if (0xf != _mm_movemask_ps(_mm_cmpeq_ps(tmp, x))) {
+ __builtin_abort();
+ }
+ x = _mm_add_ps(x, _mm_set1_ps(1));
+ }
+
+ return 0;
+}
diff --git a/gcc/testsuite/gfortran.dg/pr52835.f90 b/gcc/testsuite/gfortran.dg/pr52835.f90
new file mode 100644
index 00000000000..a72951ab6ee
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr52835.f90
@@ -0,0 +1,16 @@
+! PR tree-optimization/52835
+! { dg-do compile }
+! { dg-options "-O3 -fdump-tree-optimized" }
+
+subroutine foo (x, y, z, n)
+ integer :: n, i
+ real :: x(n), y(n), z(n)
+ do i = 1, n
+ z(i) = 0.0
+ y(i) = 0.0
+ call bar (y(i), z(i), x(i))
+ end do
+end subroutine
+
+! { dg-final { scan-tree-dump "bar " "optimized" } }
+! { dg-final { cleanup-tree-dump "optimized" } }
diff --git a/gcc/testsuite/gnat.dg/controlled6.adb b/gcc/testsuite/gnat.dg/controlled6.adb
new file mode 100644
index 00000000000..88640de7bea
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/controlled6.adb
@@ -0,0 +1,24 @@
+-- { dg-do compile }
+-- { dg-options "-O -gnatn" }
+
+with Ada.Text_IO; use Ada.Text_IO;
+with Controlled6_Pkg;
+with Controlled6_Pkg.Iterators;
+
+procedure Controlled6 is
+
+ type String_Access is access String;
+
+ package My_Q is new Controlled6_Pkg (String_Access);
+ package My_Iterators is new My_Q.Iterators (0);
+ use My_Iterators;
+
+ Iterator : Iterator_Type := Find;
+
+begin
+ loop
+ exit when Is_Null (Iterator);
+ Put (Current (Iterator).all & ' ');
+ Find_Next (Iterator);
+ end loop;
+end;
diff --git a/gcc/testsuite/gnat.dg/controlled6_pkg-iterators.adb b/gcc/testsuite/gnat.dg/controlled6_pkg-iterators.adb
new file mode 100644
index 00000000000..201a75c94cc
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/controlled6_pkg-iterators.adb
@@ -0,0 +1,21 @@
+package body Controlled6_Pkg.Iterators is
+
+ function Find return Iterator_Type is
+ Iterator : Iterator_Type;
+ begin
+ return Iterator;
+ end Find;
+
+ function Current (Iterator : in Iterator_Type) return T is begin
+ return Iterator.Current.Item;
+ end Current;
+
+ procedure Find_Next (Iterator : in out Iterator_Type) is begin
+ Iterator.Current := null;
+ end Find_Next;
+
+ function Is_Null (Iterator : in Iterator_Type) return Boolean is begin
+ return Iterator.Current = null;
+ end Is_Null;
+
+end Controlled6_Pkg.Iterators;
diff --git a/gcc/testsuite/gnat.dg/controlled6_pkg-iterators.ads b/gcc/testsuite/gnat.dg/controlled6_pkg-iterators.ads
new file mode 100644
index 00000000000..89330f6a3ba
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/controlled6_pkg-iterators.ads
@@ -0,0 +1,22 @@
+with Ada.Finalization;
+
+generic
+
+ I : Integer;
+
+package Controlled6_Pkg.Iterators is
+
+ type Iterator_Type is new Ada.Finalization.Controlled with record
+ Current : Node_Access_Type;
+ end record;
+
+ function Find return Iterator_Type;
+
+ function Current (Iterator : in Iterator_Type) return T;
+ pragma Inline (Current);
+
+ procedure Find_Next (Iterator : in out Iterator_Type);
+
+ function Is_Null (Iterator : in Iterator_Type) return Boolean;
+
+end Controlled6_Pkg.Iterators;
diff --git a/gcc/testsuite/gnat.dg/controlled6_pkg.ads b/gcc/testsuite/gnat.dg/controlled6_pkg.ads
new file mode 100644
index 00000000000..2f1052be981
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/controlled6_pkg.ads
@@ -0,0 +1,15 @@
+with Ada.Finalization;
+
+generic
+
+ type T is private;
+
+package Controlled6_Pkg is
+
+ type Node_Type is record
+ Item : T;
+ end record;
+
+ type Node_Access_Type is access Node_Type;
+
+end Controlled6_Pkg;
diff --git a/gcc/testsuite/gnat.dg/specs/aggr5.ads b/gcc/testsuite/gnat.dg/specs/aggr5.ads
new file mode 100644
index 00000000000..ba1e695bca2
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/aggr5.ads
@@ -0,0 +1,19 @@
+-- { dg-do compile }
+
+pragma Restrictions (No_Elaboration_Code);
+
+package Aggr5 is
+
+ type R is record
+ C : Character;
+ F : Float;
+ end record;
+
+ for R use record
+ C at 0 range 0 .. 7;
+ F at 1 range 0 .. 31;
+ end record;
+
+ My_R : R := (C => 'A', F => 1.0);
+
+end Aggr5;
diff --git a/gcc/tracer.c b/gcc/tracer.c
index 602e7580d99..8fb9817dbe9 100644
--- a/gcc/tracer.c
+++ b/gcc/tracer.c
@@ -59,7 +59,6 @@ static bool better_p (const_edge, const_edge);
static edge find_best_successor (basic_block);
static edge find_best_predecessor (basic_block);
static int find_trace (basic_block, basic_block *);
-static void tail_duplicate (void);
/* Minimal outgoing edge probability considered for superblock formation. */
static int probability_cutoff;
@@ -224,7 +223,7 @@ find_trace (basic_block bb, basic_block *trace)
/* Look for basic blocks in frequency order, construct traces and tail duplicate
if profitable. */
-static void
+static bool
tail_duplicate (void)
{
fibnode_t *blocks = XCNEWVEC (fibnode_t, last_basic_block);
@@ -236,6 +235,7 @@ tail_duplicate (void)
gcov_type cover_insns;
int max_dup_insns;
basic_block bb;
+ bool changed = false;
/* Create an oversized sbitmap to reduce the chance that we need to
resize it. */
@@ -332,6 +332,7 @@ tail_duplicate (void)
bb2->index, copy->index, copy->frequency);
bb2 = copy;
+ changed = true;
}
mark_bb_seen (bb2);
bb = bb2;
@@ -353,6 +354,8 @@ tail_duplicate (void)
free (trace);
free (counts);
fibheap_delete (heap);
+
+ return changed;
}
/* Main entry point to this file. */
@@ -360,6 +363,8 @@ tail_duplicate (void)
static unsigned int
tracer (void)
{
+ bool changed;
+
gcc_assert (current_ir_type () == IR_GIMPLE);
if (n_basic_blocks <= NUM_FIXED_BLOCKS + 1)
@@ -370,15 +375,14 @@ tracer (void)
dump_flow_info (dump_file, dump_flags);
/* Trace formation is done on the fly inside tail_duplicate */
- tail_duplicate ();
+ changed = tail_duplicate ();
+ if (changed)
+ free_dominance_info (CDI_DOMINATORS);
- /* FIXME: We really only need to do this when we know tail duplication
- has altered the CFG. */
- free_dominance_info (CDI_DOMINATORS);
if (dump_file)
dump_flow_info (dump_file, dump_flags);
- return 0;
+ return changed ? TODO_cleanup_cfg : 0;
}
static bool
diff --git a/gcc/tree-affine.c b/gcc/tree-affine.c
index 69cce2e7e61..7bb1645d425 100644
--- a/gcc/tree-affine.c
+++ b/gcc/tree-affine.c
@@ -812,7 +812,7 @@ aff_combination_constant_multiple_p (aff_tree *val, aff_tree *div,
/* Prints the affine VAL to the FILE. */
-void
+static void
print_aff (FILE *file, aff_tree *val)
{
unsigned i;
diff --git a/gcc/tree-affine.h b/gcc/tree-affine.h
index 8cfbd691d9e..4d3a49df032 100644
--- a/gcc/tree-affine.h
+++ b/gcc/tree-affine.h
@@ -79,5 +79,4 @@ void free_affine_expand_cache (struct pointer_map_t **);
bool aff_comb_cannot_overlap_p (aff_tree *, double_int, double_int);
/* Debugging functions. */
-void print_aff (FILE *, aff_tree *);
void debug_aff (aff_tree *);
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index eb7b62a72c5..1f59c03cfcd 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -2273,6 +2273,43 @@ gimple_cfg2vcg (FILE *file)
Miscellaneous helpers
---------------------------------------------------------------------------*/
+/* Return true if T, a GIMPLE_CALL, can make an abnormal transfer of control
+ flow. Transfers of control flow associated with EH are excluded. */
+
+static bool
+call_can_make_abnormal_goto (gimple t)
+{
+ /* If the function has no non-local labels, then a call cannot make an
+ abnormal transfer of control. */
+ if (!cfun->has_nonlocal_label)
+ return false;
+
+ /* Likewise if the call has no side effects. */
+ if (!gimple_has_side_effects (t))
+ return false;
+
+ /* Likewise if the called function is leaf. */
+ if (gimple_call_flags (t) & ECF_LEAF)
+ return false;
+
+ return true;
+}
+
+
+/* Return true if T can make an abnormal transfer of control flow.
+ Transfers of control flow associated with EH are excluded. */
+
+bool
+stmt_can_make_abnormal_goto (gimple t)
+{
+ if (computed_goto_p (t))
+ return true;
+ if (is_gimple_call (t))
+ return call_can_make_abnormal_goto (t);
+ return false;
+}
+
+
/* Return true if T represents a stmt that always transfers control. */
bool
@@ -2306,10 +2343,8 @@ is_ctrl_altering_stmt (gimple t)
{
int flags = gimple_call_flags (t);
- /* A non-pure/const call alters flow control if the current
- function has nonlocal labels. */
- if (!(flags & (ECF_CONST | ECF_PURE | ECF_LEAF))
- && cfun->has_nonlocal_label)
+ /* A call alters control flow if it can make an abnormal goto. */
+ if (call_can_make_abnormal_goto (t))
return true;
/* A call also alters control flow if it does not return. */
@@ -2367,21 +2402,6 @@ simple_goto_p (gimple t)
}
-/* Return true if T can make an abnormal transfer of control flow.
- Transfers of control flow associated with EH are excluded. */
-
-bool
-stmt_can_make_abnormal_goto (gimple t)
-{
- if (computed_goto_p (t))
- return true;
- if (is_gimple_call (t))
- return (gimple_has_side_effects (t) && cfun->has_nonlocal_label
- && !(gimple_call_flags (t) & ECF_LEAF));
- return false;
-}
-
-
/* Return true if STMT should start a new basic block. PREV_STMT is
the statement preceding STMT. It is used when STMT is a label or a
case label. Labels should only start a new basic block if their
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index 9b3a10df3c7..6fb0d23f74e 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -140,7 +140,7 @@ int_divides_p (int a, int b)
/* Dump into FILE all the data references from DATAREFS. */
-void
+static void
dump_data_references (FILE *file, VEC (data_reference_p, heap) *datarefs)
{
unsigned int i;
@@ -158,27 +158,6 @@ debug_data_references (VEC (data_reference_p, heap) *datarefs)
dump_data_references (stderr, datarefs);
}
-/* Dump to STDERR all the dependence relations from DDRS. */
-
-DEBUG_FUNCTION void
-debug_data_dependence_relations (VEC (ddr_p, heap) *ddrs)
-{
- dump_data_dependence_relations (stderr, ddrs);
-}
-
-/* Dump into FILE all the dependence relations from DDRS. */
-
-void
-dump_data_dependence_relations (FILE *file,
- VEC (ddr_p, heap) *ddrs)
-{
- unsigned int i;
- struct data_dependence_relation *ddr;
-
- FOR_EACH_VEC_ELT (ddr_p, ddrs, i, ddr)
- dump_data_dependence_relation (file, ddr);
-}
-
/* Print to STDERR the data_reference DR. */
DEBUG_FUNCTION void
@@ -253,7 +232,7 @@ dump_conflict_function (FILE *outf, conflict_function *cf)
/* Dump function for a SUBSCRIPT structure. */
-void
+static void
dump_subscript (FILE *outf, struct subscript *subscript)
{
conflict_function *cf = SUB_CONFLICTS_IN_A (subscript);
@@ -286,7 +265,7 @@ dump_subscript (FILE *outf, struct subscript *subscript)
/* Print the classic direction vector DIRV to OUTF. */
-void
+static void
print_direction_vector (FILE *outf,
lambda_vector dirv,
int length)
@@ -331,7 +310,7 @@ print_direction_vector (FILE *outf,
/* Print a vector of direction vectors. */
-void
+static void
print_dir_vectors (FILE *outf, VEC (lambda_vector, heap) *dir_vects,
int length)
{
@@ -356,9 +335,9 @@ print_lambda_vector (FILE * outfile, lambda_vector vector, int n)
/* Print a vector of distance vectors. */
-void
-print_dist_vectors (FILE *outf, VEC (lambda_vector, heap) *dist_vects,
- int length)
+static void
+print_dist_vectors (FILE *outf, VEC (lambda_vector, heap) *dist_vects,
+ int length)
{
unsigned j;
lambda_vector v;
@@ -367,17 +346,9 @@ print_dist_vectors (FILE *outf, VEC (lambda_vector, heap) *dist_vects,
print_lambda_vector (outf, v, length);
}
-/* Debug version. */
-
-DEBUG_FUNCTION void
-debug_data_dependence_relation (struct data_dependence_relation *ddr)
-{
- dump_data_dependence_relation (stderr, ddr);
-}
-
/* Dump function for a DATA_DEPENDENCE_RELATION structure. */
-void
+static void
dump_data_dependence_relation (FILE *outf,
struct data_dependence_relation *ddr)
{
@@ -450,45 +421,33 @@ dump_data_dependence_relation (FILE *outf,
fprintf (outf, ")\n");
}
-/* Dump function for a DATA_DEPENDENCE_DIRECTION structure. */
+/* Debug version. */
-void
-dump_data_dependence_direction (FILE *file,
- enum data_dependence_direction dir)
+DEBUG_FUNCTION void
+debug_data_dependence_relation (struct data_dependence_relation *ddr)
{
- switch (dir)
- {
- case dir_positive:
- fprintf (file, "+");
- break;
-
- case dir_negative:
- fprintf (file, "-");
- break;
-
- case dir_equal:
- fprintf (file, "=");
- break;
+ dump_data_dependence_relation (stderr, ddr);
+}
- case dir_positive_or_negative:
- fprintf (file, "+-");
- break;
+/* Dump into FILE all the dependence relations from DDRS. */
- case dir_positive_or_equal:
- fprintf (file, "+=");
- break;
+void
+dump_data_dependence_relations (FILE *file,
+ VEC (ddr_p, heap) *ddrs)
+{
+ unsigned int i;
+ struct data_dependence_relation *ddr;
- case dir_negative_or_equal:
- fprintf (file, "-=");
- break;
+ FOR_EACH_VEC_ELT (ddr_p, ddrs, i, ddr)
+ dump_data_dependence_relation (file, ddr);
+}
- case dir_star:
- fprintf (file, "*");
- break;
+/* Dump to STDERR all the dependence relations from DDRS. */
- default:
- break;
- }
+DEBUG_FUNCTION void
+debug_data_dependence_relations (VEC (ddr_p, heap) *ddrs)
+{
+ dump_data_dependence_relations (stderr, ddrs);
}
/* Dumps the distance and direction vectors in FILE. DDRS contains
@@ -496,7 +455,7 @@ dump_data_dependence_direction (FILE *file,
dependence vectors, or in other words the number of loops in the
considered nest. */
-void
+static void
dump_dist_dir_vectors (FILE *file, VEC (ddr_p, heap) *ddrs)
{
unsigned int i, j;
@@ -526,7 +485,7 @@ dump_dist_dir_vectors (FILE *file, VEC (ddr_p, heap) *ddrs)
/* Dumps the data dependence relations DDRS in FILE. */
-void
+static void
dump_ddrs (FILE *file, VEC (ddr_p, heap) *ddrs)
{
unsigned int i;
@@ -538,6 +497,12 @@ dump_ddrs (FILE *file, VEC (ddr_p, heap) *ddrs)
fprintf (file, "\n\n");
}
+DEBUG_FUNCTION void
+debug_ddrs (VEC (ddr_p, heap) *ddrs)
+{
+ dump_ddrs (stderr, ddrs);
+}
+
/* Helper function for split_constant_offset. Expresses OP0 CODE OP1
(the type of the result is TYPE) as VAR + OFF, where OFF is a nonzero
constant of type ssizetype, and returns true. If we cannot do this
@@ -4236,10 +4201,24 @@ compute_all_dependences (VEC (data_reference_p, heap) *datarefs,
return true;
}
+/* Describes a location of a memory reference. */
+
+typedef struct data_ref_loc_d
+{
+ /* Position of the memory reference. */
+ tree *pos;
+
+ /* True if the memory reference is read. */
+ bool is_read;
+} data_ref_loc;
+
+DEF_VEC_O (data_ref_loc);
+DEF_VEC_ALLOC_O (data_ref_loc, heap);
+
/* Stores the locations of memory references in STMT to REFERENCES. Returns
true if STMT clobbers memory, false otherwise. */
-bool
+static bool
get_references_in_stmt (gimple stmt, VEC (data_ref_loc, heap) **references)
{
bool clobbers_memory = false;
@@ -4708,7 +4687,7 @@ free_data_refs (VEC (data_reference_p, heap) *datarefs)
/* Dump vertex I in RDG to FILE. */
-void
+static void
dump_rdg_vertex (FILE *file, struct graph *rdg, int i)
{
struct vertex *v = &(rdg->vertices[i]);
@@ -4744,7 +4723,8 @@ debug_rdg_vertex (struct graph *rdg, int i)
/* Dump component C of RDG to FILE. If DUMPED is non-null, set the
dumped vertices to that bitmap. */
-void dump_rdg_component (FILE *file, struct graph *rdg, int c, bitmap dumped)
+static void
+dump_rdg_component (FILE *file, struct graph *rdg, int c, bitmap dumped)
{
int i;
@@ -5129,20 +5109,19 @@ build_rdg (struct loop *loop,
VEC (data_reference_p, heap) **datarefs)
{
struct graph *rdg = NULL;
- VEC (gimple, heap) *stmts = VEC_alloc (gimple, heap, 10);
-
- compute_data_dependences_for_loop (loop, false, loop_nest, datarefs,
- dependence_relations);
- if (known_dependences_p (*dependence_relations))
+ if (compute_data_dependences_for_loop (loop, false, loop_nest, datarefs,
+ dependence_relations)
+ && known_dependences_p (*dependence_relations))
{
+ VEC (gimple, heap) *stmts = VEC_alloc (gimple, heap, 10);
stmts_from_loop (loop, &stmts);
rdg = build_empty_rdg (VEC_length (gimple, stmts));
create_rdg_vertices (rdg, stmts);
create_rdg_edges (rdg, *dependence_relations);
+ VEC_free (gimple, heap, stmts);
}
- VEC_free (gimple, heap, stmts);
return rdg;
}
@@ -5401,20 +5380,3 @@ remove_similar_memory_refs (VEC (gimple, heap) **stmts)
htab_delete (seen);
}
-/* Returns the index of PARAMETER in the parameters vector of the
- ACCESS_MATRIX. If PARAMETER does not exist return -1. */
-
-int
-access_matrix_get_index_for_parameter (tree parameter,
- struct access_matrix *access_matrix)
-{
- int i;
- VEC (tree,heap) *lambda_parameters = AM_PARAMETERS (access_matrix);
- tree lambda_parameter;
-
- FOR_EACH_VEC_ELT (tree, lambda_parameters, i, lambda_parameter)
- if (lambda_parameter == parameter)
- return i + AM_NB_INDUCTION_VARS (access_matrix);
-
- return -1;
-}
diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h
index d983c8cda45..41a20d74206 100644
--- a/gcc/tree-data-ref.h
+++ b/gcc/tree-data-ref.h
@@ -169,8 +169,6 @@ am_vector_index_for_loop (struct access_matrix *access_matrix, int loop_num)
gcc_unreachable();
}
-int access_matrix_get_index_for_parameter (tree, struct access_matrix *);
-
struct data_reference
{
/* A pointer to the statement that contains this DR. */
@@ -371,22 +369,6 @@ DEF_VEC_ALLOC_P(ddr_p,heap);
#define DDR_REVERSED_P(DDR) DDR->reversed_p
-
-/* Describes a location of a memory reference. */
-
-typedef struct data_ref_loc_d
-{
- /* Position of the memory reference. */
- tree *pos;
-
- /* True if the memory reference is read. */
- bool is_read;
-} data_ref_loc;
-
-DEF_VEC_O (data_ref_loc);
-DEF_VEC_ALLOC_O (data_ref_loc, heap);
-
-bool get_references_in_stmt (gimple, VEC (data_ref_loc, heap) **);
bool dr_analyze_innermost (struct data_reference *, struct loop *);
extern bool compute_data_dependences_for_loop (struct loop *, bool,
VEC (loop_p, heap) **,
@@ -395,23 +377,13 @@ extern bool compute_data_dependences_for_loop (struct loop *, bool,
extern bool compute_data_dependences_for_bb (basic_block, bool,
VEC (data_reference_p, heap) **,
VEC (ddr_p, heap) **);
-extern void print_direction_vector (FILE *, lambda_vector, int);
-extern void print_dir_vectors (FILE *, VEC (lambda_vector, heap) *, int);
-extern void print_dist_vectors (FILE *, VEC (lambda_vector, heap) *, int);
-extern void dump_subscript (FILE *, struct subscript *);
-extern void dump_ddrs (FILE *, VEC (ddr_p, heap) *);
-extern void dump_dist_dir_vectors (FILE *, VEC (ddr_p, heap) *);
+extern void debug_ddrs (VEC (ddr_p, heap) *);
extern void dump_data_reference (FILE *, struct data_reference *);
extern void debug_data_reference (struct data_reference *);
-extern void dump_data_references (FILE *, VEC (data_reference_p, heap) *);
extern void debug_data_references (VEC (data_reference_p, heap) *);
extern void debug_data_dependence_relation (struct data_dependence_relation *);
-extern void dump_data_dependence_relation (FILE *,
- struct data_dependence_relation *);
extern void dump_data_dependence_relations (FILE *, VEC (ddr_p, heap) *);
extern void debug_data_dependence_relations (VEC (ddr_p, heap) *);
-extern void dump_data_dependence_direction (FILE *,
- enum data_dependence_direction);
extern void free_dependence_relation (struct data_dependence_relation *);
extern void free_dependence_relations (VEC (ddr_p, heap) *);
extern void free_data_ref (data_reference_p);
@@ -567,9 +539,7 @@ typedef struct rdg_vertex
#define RDG_MEM_WRITE_STMT(RDG, I) RDGV_HAS_MEM_WRITE (&(RDG->vertices[I]))
#define RDG_MEM_READS_STMT(RDG, I) RDGV_HAS_MEM_READS (&(RDG->vertices[I]))
-void dump_rdg_vertex (FILE *, struct graph *, int);
void debug_rdg_vertex (struct graph *, int);
-void dump_rdg_component (FILE *, struct graph *, int, bitmap);
void debug_rdg_component (struct graph *, int);
void dump_rdg (FILE *, struct graph *);
void debug_rdg (struct graph *);
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index c28006a9132..4e86b8db0c3 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -1764,23 +1764,25 @@ gsi_prev_dom_bb_nondebug (gimple_stmt_iterator *i)
}
/* Find a BUILT_IN_STACK_SAVE dominating gsi_stmt (I), and insert
- a clobber of VAR before each matching BUILT_IN_STACK_RESTORE. */
+ a clobber of VAR before each matching BUILT_IN_STACK_RESTORE.
+
+ It is possible that BUILT_IN_STACK_SAVE cannot be find in a dominator when a
+ previous pass (such as DOM) duplicated it along multiple paths to a BB. In
+ that case the function gives up without inserting the clobbers. */
static void
insert_clobbers_for_var (gimple_stmt_iterator i, tree var)
{
- bool save_found;
gimple stmt;
tree saved_val;
htab_t visited = NULL;
- for (save_found = false; !gsi_end_p (i); gsi_prev_dom_bb_nondebug (&i))
+ for (; !gsi_end_p (i); gsi_prev_dom_bb_nondebug (&i))
{
stmt = gsi_stmt (i);
if (!gimple_call_builtin_p (stmt, BUILT_IN_STACK_SAVE))
continue;
- save_found = true;
saved_val = gimple_call_lhs (stmt);
if (saved_val == NULL_TREE)
@@ -1792,7 +1794,6 @@ insert_clobbers_for_var (gimple_stmt_iterator i, tree var)
if (visited != NULL)
htab_delete (visited);
- gcc_assert (save_found);
}
/* Detects a __builtin_alloca_with_align with constant size argument. Declares
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 919779526d9..2b16222bbd5 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -905,6 +905,7 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
that of the pointed-to type of the address we can put the
dereferenced address on the LHS preserving the original alias-type. */
else if (gimple_assign_lhs (use_stmt) == lhs
+ && integer_zerop (TREE_OPERAND (lhs, 1))
&& useless_type_conversion_p
(TREE_TYPE (TREE_OPERAND (def_rhs, 0)),
TREE_TYPE (gimple_assign_rhs1 (use_stmt))))
@@ -917,9 +918,8 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
if (TREE_CODE (*def_rhs_basep) == MEM_REF)
{
new_base = TREE_OPERAND (*def_rhs_basep, 0);
- new_offset
- = int_const_binop (PLUS_EXPR, TREE_OPERAND (lhs, 1),
- TREE_OPERAND (*def_rhs_basep, 1));
+ new_offset = fold_convert (TREE_TYPE (TREE_OPERAND (lhs, 1)),
+ TREE_OPERAND (*def_rhs_basep, 1));
}
else
{
@@ -989,6 +989,7 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
that of the pointed-to type of the address we can put the
dereferenced address on the RHS preserving the original alias-type. */
else if (gimple_assign_rhs1 (use_stmt) == rhs
+ && integer_zerop (TREE_OPERAND (rhs, 1))
&& useless_type_conversion_p
(TREE_TYPE (gimple_assign_lhs (use_stmt)),
TREE_TYPE (TREE_OPERAND (def_rhs, 0))))
@@ -1001,9 +1002,8 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
if (TREE_CODE (*def_rhs_basep) == MEM_REF)
{
new_base = TREE_OPERAND (*def_rhs_basep, 0);
- new_offset
- = int_const_binop (PLUS_EXPR, TREE_OPERAND (rhs, 1),
- TREE_OPERAND (*def_rhs_basep, 1));
+ new_offset = fold_convert (TREE_TYPE (TREE_OPERAND (rhs, 1)),
+ TREE_OPERAND (*def_rhs_basep, 1));
}
else
{
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index 4532886ca96..687eee0485a 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -826,6 +826,17 @@ determine_bb_domination_status (struct loop *loop, basic_block bb)
return (bb_reachable ? DOMST_DOMINATING : DOMST_LOOP_BROKEN);
}
+/* Return true if BB is part of the new pre-header that is created
+ when threading the latch to DATA. */
+
+static bool
+def_split_header_continue_p (const_basic_block bb, const void *data)
+{
+ const_basic_block new_header = (const_basic_block) data;
+ return (bb->loop_father == new_header->loop_father
+ && bb != new_header);
+}
+
/* Thread jumps through the header of LOOP. Returns true if cfg changes.
If MAY_PEEL_LOOP_HEADERS is false, we avoid threading from entry edges
to the inside of the loop. */
@@ -990,11 +1001,50 @@ thread_through_loop_header (struct loop *loop, bool may_peel_loop_headers)
if (latch->aux)
{
- /* First handle the case latch edge is redirected. */
+ basic_block *bblocks;
+ unsigned nblocks, i;
+
+ /* First handle the case latch edge is redirected. We are copying
+ the loop header but not creating a multiple entry loop. Make the
+ cfg manipulation code aware of that fact. */
+ set_loop_copy (loop, loop);
loop->latch = thread_single_edge (latch);
+ set_loop_copy (loop, NULL);
gcc_assert (single_succ (loop->latch) == tgt_bb);
loop->header = tgt_bb;
+ /* Remove the new pre-header blocks from our loop. */
+ bblocks = XCNEWVEC (basic_block, loop->num_nodes);
+ nblocks = dfs_enumerate_from (header, 0, def_split_header_continue_p,
+ bblocks, loop->num_nodes, tgt_bb);
+ for (i = 0; i < nblocks; i++)
+ {
+ remove_bb_from_loops (bblocks[i]);
+ add_bb_to_loop (bblocks[i], loop_outer (loop));
+ }
+ free (bblocks);
+
+ /* Cancel remaining threading requests that would make the
+ loop a multiple entry loop. */
+ FOR_EACH_EDGE (e, ei, header->preds)
+ {
+ edge e2;
+ if (e->aux == NULL)
+ continue;
+
+ if (THREAD_TARGET2 (e))
+ e2 = THREAD_TARGET2 (e);
+ else
+ e2 = THREAD_TARGET (e);
+
+ if (e->src->loop_father != e2->dest->loop_father
+ && e2->dest != loop->header)
+ {
+ free (e->aux);
+ e->aux = NULL;
+ }
+ }
+
/* Thread the remaining edges through the former header. */
thread_block (header, false);
}
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index c142bbb0201..0ab6be0671a 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -2337,8 +2337,23 @@ vect_get_constant_vectors (tree op, slp_tree slp_node,
op = gimple_call_arg (stmt, op_num);
break;
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ case LROTATE_EXPR:
+ case RROTATE_EXPR:
+ op = gimple_op (stmt, op_num + 1);
+ /* Unlike the other binary operators, shifts/rotates have
+ the shift count being int, instead of the same type as
+ the lhs, so make sure the scalar is the right type if
+ we are dealing with vectors of
+ long long/long/short/char. */
+ if (op_num == 1 && constant_p)
+ op = fold_convert (TREE_TYPE (vector_type), op);
+ break;
+
default:
op = gimple_op (stmt, op_num + 1);
+ break;
}
}
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 0c04de47974..34ed948cade 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -4420,6 +4420,7 @@ initializer_constant_valid_for_bitfield_p (tree value)
}
case INTEGER_CST:
+ case REAL_CST:
return true;
case VIEW_CONVERT_EXPR:
@@ -5075,10 +5076,7 @@ output_constructor (tree exp, unsigned HOST_WIDE_INT size,
/* The element in a union constructor specifies the proper field
or index. */
- if ((TREE_CODE (local.type) == RECORD_TYPE
- || TREE_CODE (local.type) == UNION_TYPE
- || TREE_CODE (local.type) == QUAL_UNION_TYPE)
- && ce->index != NULL_TREE)
+ if (RECORD_OR_UNION_TYPE_P (local.type) && ce->index != NULL_TREE)
local.field = ce->index;
else if (TREE_CODE (local.type) == ARRAY_TYPE)
@@ -5110,9 +5108,18 @@ output_constructor (tree exp, unsigned HOST_WIDE_INT size,
|| !CONSTRUCTOR_BITFIELD_P (local.field)))
output_constructor_regular_field (&local);
- /* For a true bitfield or part of an outer one. */
+ /* For a true bitfield or part of an outer one. Only INTEGER_CSTs are
+ supported for scalar fields, so we may need to convert first. */
else
- output_constructor_bitfield (&local, outer);
+ {
+ if (TREE_CODE (local.val) == REAL_CST)
+ local.val
+ = fold_unary (VIEW_CONVERT_EXPR,
+ build_nonstandard_integer_type
+ (TYPE_PRECISION (TREE_TYPE (local.val)), 0),
+ local.val);
+ output_constructor_bitfield (&local, outer);
+ }
}
/* If we are not at toplevel, save the pending data for our caller.
diff --git a/libffi/ChangeLog b/libffi/ChangeLog
index 6df2662df80..4f514f9f999 100644
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -1,3 +1,11 @@
+2012-04-02 Peter Bergner <bergner@vnet.ibm.com>
+
+ * src/powerpc/ffi.c (ffi_prep_args_SYSV): Declare double_tmp.
+ Silence casting pointer to integer of different size warning.
+ Delete goto to previously deleted label.
+ (ffi_call): Silence possibly undefined warning.
+ (ffi_closure_helper_SYSV): Declare variable type.
+
2012-03-13 Kaz Kojima <kkojima@gcc.gnu.org>
* src/sh/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test,
diff --git a/libffi/src/powerpc/ffi.c b/libffi/src/powerpc/ffi.c
index 1920c91104d..baca69448fe 100644
--- a/libffi/src/powerpc/ffi.c
+++ b/libffi/src/powerpc/ffi.c
@@ -146,6 +146,7 @@ ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack)
gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
intarg_count = 0;
#ifndef __NO_FPRS__
+ double double_tmp;
fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS;
fparg_count = 0;
copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c);
@@ -155,9 +156,9 @@ ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack)
next_arg.u = stack + 2;
/* Check that everything starts aligned properly. */
- FFI_ASSERT (((unsigned) (char *) stack & 0xF) == 0);
- FFI_ASSERT (((unsigned) copy_space.c & 0xF) == 0);
- FFI_ASSERT (((unsigned) stacktop.c & 0xF) == 0);
+ FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
+ FFI_ASSERT (((unsigned long) copy_space.c & 0xF) == 0);
+ FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
FFI_ASSERT ((bytes & 0xF) == 0);
FFI_ASSERT (copy_space.c >= next_arg.c);
@@ -211,8 +212,6 @@ ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack)
case FFI_TYPE_DOUBLE:
/* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64. */
- if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
- goto soft_double_prep;
double_tmp = **p_argv.d;
if (fparg_count >= NUM_FPR_ARG_REGISTERS)
@@ -925,7 +924,7 @@ ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
*/
unsigned int smst_buffer[2];
extended_cif ecif;
- unsigned int rsize;
+ unsigned int rsize = 0;
ecif.cif = cif;
ecif.avalue = avalue;
@@ -1132,7 +1131,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue,
if (nf < 8)
{
- temp = pfr->d;
+ double temp = pfr->d;
pfr->f = (float) temp;
avalue[i] = pfr;
nf++;
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index f44f52ea1ba..354b3ceedf8 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,13 @@
+2012-04-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/linux-unwind.h (RT_SIGRETURN_SYSCALL): Update x32
+ system call number.
+
+2012-03-31 Eric Botcazou <ebotcazou@adacore.com>
+
+ * config/ia64/unwind-ia64.c (uw_install_context): Manually save LC
+ if it hasn't been previously saved.
+
2012-03-29 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/linux-unwind.h (x86_64_fallback_frame_state): Define
diff --git a/libgcc/config/i386/linux-unwind.h b/libgcc/config/i386/linux-unwind.h
index aef2692b141..ad0ccfa0be7 100644
--- a/libgcc/config/i386/linux-unwind.h
+++ b/libgcc/config/i386/linux-unwind.h
@@ -54,7 +54,7 @@ x86_64_fallback_frame_state (struct _Unwind_Context *context,
#ifdef __LP64__
#define RT_SIGRETURN_SYSCALL 0x050f0000000fc0c7ULL
#else
-#define RT_SIGRETURN_SYSCALL 0x050f40002006c0c7ULL
+#define RT_SIGRETURN_SYSCALL 0x050f40000201c0c7ULL
#endif
if (*(unsigned char *)(pc+0) == 0x48
&& *(unsigned long long *)(pc+1) == RT_SIGRETURN_SYSCALL)
diff --git a/libgcc/config/ia64/unwind-ia64.c b/libgcc/config/ia64/unwind-ia64.c
index 10cf1363b1b..2bb9100a499 100644
--- a/libgcc/config/ia64/unwind-ia64.c
+++ b/libgcc/config/ia64/unwind-ia64.c
@@ -2169,8 +2169,20 @@ uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
struct _Unwind_Context *target)
{
unw_word ireg_buf[4], ireg_nat = 0, ireg_pr = 0;
+ unw_word saved_lc;
int i;
+ /* ??? LC is a fixed register so the call to __builtin_unwind_init in
+ uw_init_context doesn't cause it to be saved. In case it isn't in
+ the user frames either, we need to manually do so here, lest it be
+ clobbered by the loop just below. */
+ if (target->lc_loc == NULL)
+ {
+ register unw_word lc asm ("ar.lc");
+ saved_lc = lc;
+ target->lc_loc = &saved_lc;
+ }
+
/* Copy integer register data from the target context to a
temporary buffer. Do this so that we can frob AR.UNAT
to get the NaT bits for these registers set properly. */
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 7890287c3e5..0afe589e6b3 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,15 @@
+2012-04-02 Tristan Gingold <gingold@adacore.com>
+
+ * configure.ac: Use new version of GCC_CHECK_MATH_FUNC.
+ * configure: Regenerate
+ * config.h.in: Regenerate.
+
+2012-03-30 Uros Bizjak <ubizjak@gmail.com>
+
+ PR libgfortran/52758
+ * intrinsics/chmod.c (chmod_func): Remove out-of-bounds
+ initialization of rwxXstugo.
+
2012-03-27 Tristan Gingold <gingold@adacore.com>
* configure.ac: Add description to AC_DEFINE in
diff --git a/libgfortran/config.h.in b/libgfortran/config.h.in
index 2ec68833e38..30a7e121325 100644
--- a/libgfortran/config.h.in
+++ b/libgfortran/config.h.in
@@ -6,70 +6,70 @@
/* Define to 1 if you have the `access' function. */
#undef HAVE_ACCESS
-/* acos is available */
+/* Define to 1 if you have the `acos' function. */
#undef HAVE_ACOS
-/* acosf is available */
+/* Define to 1 if you have the `acosf' function. */
#undef HAVE_ACOSF
-/* acosh is available */
+/* Define to 1 if you have the `acosh' function. */
#undef HAVE_ACOSH
-/* acoshf is available */
+/* Define to 1 if you have the `acoshf' function. */
#undef HAVE_ACOSHF
-/* acoshl is available */
+/* Define to 1 if you have the `acoshl' function. */
#undef HAVE_ACOSHL
-/* acosl is available */
+/* Define to 1 if you have the `acosl' function. */
#undef HAVE_ACOSL
/* Define to 1 if you have the `alarm' function. */
#undef HAVE_ALARM
-/* asin is available */
+/* Define to 1 if you have the `asin' function. */
#undef HAVE_ASIN
-/* asinf is available */
+/* Define to 1 if you have the `asinf' function. */
#undef HAVE_ASINF
-/* asinh is available */
+/* Define to 1 if you have the `asinh' function. */
#undef HAVE_ASINH
-/* asinhf is available */
+/* Define to 1 if you have the `asinhf' function. */
#undef HAVE_ASINHF
-/* asinhl is available */
+/* Define to 1 if you have the `asinhl' function. */
#undef HAVE_ASINHL
-/* asinl is available */
+/* Define to 1 if you have the `asinl' function. */
#undef HAVE_ASINL
-/* atan is available */
+/* Define to 1 if you have the `atan' function. */
#undef HAVE_ATAN
-/* atan2 is available */
+/* Define to 1 if you have the `atan2' function. */
#undef HAVE_ATAN2
-/* atan2f is available */
+/* Define to 1 if you have the `atan2f' function. */
#undef HAVE_ATAN2F
-/* atan2l is available */
+/* Define to 1 if you have the `atan2l' function. */
#undef HAVE_ATAN2L
-/* atanf is available */
+/* Define to 1 if you have the `atanf' function. */
#undef HAVE_ATANF
-/* atanh is available */
+/* Define to 1 if you have the `atanh' function. */
#undef HAVE_ATANH
-/* atanhf is available */
+/* Define to 1 if you have the `atanhf' function. */
#undef HAVE_ATANHF
-/* atanhl is available */
+/* Define to 1 if you have the `atanhl' function. */
#undef HAVE_ATANHL
-/* atanl is available */
+/* Define to 1 if you have the `atanl' function. */
#undef HAVE_ATANL
/* Define to 1 if the target supports __attribute__((alias(...))). */
@@ -84,112 +84,112 @@
/* Define if powf is broken. */
#undef HAVE_BROKEN_POWF
-/* cabs is available */
+/* Define to 1 if you have the `cabs' function. */
#undef HAVE_CABS
-/* cabsf is available */
+/* Define to 1 if you have the `cabsf' function. */
#undef HAVE_CABSF
-/* cabsl is available */
+/* Define to 1 if you have the `cabsl' function. */
#undef HAVE_CABSL
-/* cacos is available */
+/* Define to 1 if you have the `cacos' function. */
#undef HAVE_CACOS
-/* cacosf is available */
+/* Define to 1 if you have the `cacosf' function. */
#undef HAVE_CACOSF
-/* cacosh is available */
+/* Define to 1 if you have the `cacosh' function. */
#undef HAVE_CACOSH
-/* cacoshf is available */
+/* Define to 1 if you have the `cacoshf' function. */
#undef HAVE_CACOSHF
-/* cacoshl is available */
+/* Define to 1 if you have the `cacoshl' function. */
#undef HAVE_CACOSHL
-/* cacosl is available */
+/* Define to 1 if you have the `cacosl' function. */
#undef HAVE_CACOSL
-/* carg is available */
+/* Define to 1 if you have the `carg' function. */
#undef HAVE_CARG
-/* cargf is available */
+/* Define to 1 if you have the `cargf' function. */
#undef HAVE_CARGF
-/* cargl is available */
+/* Define to 1 if you have the `cargl' function. */
#undef HAVE_CARGL
-/* casin is available */
+/* Define to 1 if you have the `casin' function. */
#undef HAVE_CASIN
-/* casinf is available */
+/* Define to 1 if you have the `casinf' function. */
#undef HAVE_CASINF
-/* casinh is available */
+/* Define to 1 if you have the `casinh' function. */
#undef HAVE_CASINH
-/* casinhf is available */
+/* Define to 1 if you have the `casinhf' function. */
#undef HAVE_CASINHF
-/* casinhl is available */
+/* Define to 1 if you have the `casinhl' function. */
#undef HAVE_CASINHL
-/* casinl is available */
+/* Define to 1 if you have the `casinl' function. */
#undef HAVE_CASINL
-/* catan is available */
+/* Define to 1 if you have the `catan' function. */
#undef HAVE_CATAN
-/* catanf is available */
+/* Define to 1 if you have the `catanf' function. */
#undef HAVE_CATANF
-/* catanh is available */
+/* Define to 1 if you have the `catanh' function. */
#undef HAVE_CATANH
-/* catanhf is available */
+/* Define to 1 if you have the `catanhf' function. */
#undef HAVE_CATANHF
-/* catanhl is available */
+/* Define to 1 if you have the `catanhl' function. */
#undef HAVE_CATANHL
-/* catanl is available */
+/* Define to 1 if you have the `catanl' function. */
#undef HAVE_CATANL
-/* ccos is available */
+/* Define to 1 if you have the `ccos' function. */
#undef HAVE_CCOS
-/* ccosf is available */
+/* Define to 1 if you have the `ccosf' function. */
#undef HAVE_CCOSF
-/* ccosh is available */
+/* Define to 1 if you have the `ccosh' function. */
#undef HAVE_CCOSH
-/* ccoshf is available */
+/* Define to 1 if you have the `ccoshf' function. */
#undef HAVE_CCOSHF
-/* ccoshl is available */
+/* Define to 1 if you have the `ccoshl' function. */
#undef HAVE_CCOSHL
-/* ccosl is available */
+/* Define to 1 if you have the `ccosl' function. */
#undef HAVE_CCOSL
-/* ceil is available */
+/* Define to 1 if you have the `ceil' function. */
#undef HAVE_CEIL
-/* ceilf is available */
+/* Define to 1 if you have the `ceilf' function. */
#undef HAVE_CEILF
-/* ceill is available */
+/* Define to 1 if you have the `ceill' function. */
#undef HAVE_CEILL
-/* cexp is available */
+/* Define to 1 if you have the `cexp' function. */
#undef HAVE_CEXP
-/* cexpf is available */
+/* Define to 1 if you have the `cexpf' function. */
#undef HAVE_CEXPF
-/* cexpl is available */
+/* Define to 1 if you have the `cexpl' function. */
#undef HAVE_CEXPL
/* Define to 1 if you have the `chdir' function. */
@@ -207,19 +207,19 @@
/* libm includes clog */
#undef HAVE_CLOG
-/* clog10 is available */
+/* Define to 1 if you have the `clog10' function. */
#undef HAVE_CLOG10
-/* clog10f is available */
+/* Define to 1 if you have the `clog10f' function. */
#undef HAVE_CLOG10F
-/* clog10l is available */
+/* Define to 1 if you have the `clog10l' function. */
#undef HAVE_CLOG10L
-/* clogf is available */
+/* Define to 1 if you have the `clogf' function. */
#undef HAVE_CLOGF
-/* clogl is available */
+/* Define to 1 if you have the `clogl' function. */
#undef HAVE_CLOGL
/* Define to 1 if you have the `close' function. */
@@ -228,88 +228,88 @@
/* Define to 1 if you have the <complex.h> header file. */
#undef HAVE_COMPLEX_H
-/* copysign is available */
+/* Define to 1 if you have the `copysign' function. */
#undef HAVE_COPYSIGN
-/* copysignf is available */
+/* Define to 1 if you have the `copysignf' function. */
#undef HAVE_COPYSIGNF
-/* copysignl is available */
+/* Define to 1 if you have the `copysignl' function. */
#undef HAVE_COPYSIGNL
-/* cos is available */
+/* Define to 1 if you have the `cos' function. */
#undef HAVE_COS
-/* cosf is available */
+/* Define to 1 if you have the `cosf' function. */
#undef HAVE_COSF
-/* cosh is available */
+/* Define to 1 if you have the `cosh' function. */
#undef HAVE_COSH
-/* coshf is available */
+/* Define to 1 if you have the `coshf' function. */
#undef HAVE_COSHF
-/* coshl is available */
+/* Define to 1 if you have the `coshl' function. */
#undef HAVE_COSHL
-/* cosl is available */
+/* Define to 1 if you have the `cosl' function. */
#undef HAVE_COSL
-/* cpow is available */
+/* Define to 1 if you have the `cpow' function. */
#undef HAVE_CPOW
-/* cpowf is available */
+/* Define to 1 if you have the `cpowf' function. */
#undef HAVE_CPOWF
-/* cpowl is available */
+/* Define to 1 if you have the `cpowl' function. */
#undef HAVE_CPOWL
/* Define if CRLF is line terminator. */
#undef HAVE_CRLF
-/* csin is available */
+/* Define to 1 if you have the `csin' function. */
#undef HAVE_CSIN
-/* csinf is available */
+/* Define to 1 if you have the `csinf' function. */
#undef HAVE_CSINF
-/* csinh is available */
+/* Define to 1 if you have the `csinh' function. */
#undef HAVE_CSINH
-/* csinhf is available */
+/* Define to 1 if you have the `csinhf' function. */
#undef HAVE_CSINHF
-/* csinhl is available */
+/* Define to 1 if you have the `csinhl' function. */
#undef HAVE_CSINHL
-/* csinl is available */
+/* Define to 1 if you have the `csinl' function. */
#undef HAVE_CSINL
-/* csqrt is available */
+/* Define to 1 if you have the `csqrt' function. */
#undef HAVE_CSQRT
-/* csqrtf is available */
+/* Define to 1 if you have the `csqrtf' function. */
#undef HAVE_CSQRTF
-/* csqrtl is available */
+/* Define to 1 if you have the `csqrtl' function. */
#undef HAVE_CSQRTL
-/* ctan is available */
+/* Define to 1 if you have the `ctan' function. */
#undef HAVE_CTAN
-/* ctanf is available */
+/* Define to 1 if you have the `ctanf' function. */
#undef HAVE_CTANF
-/* ctanh is available */
+/* Define to 1 if you have the `ctanh' function. */
#undef HAVE_CTANH
-/* ctanhf is available */
+/* Define to 1 if you have the `ctanhf' function. */
#undef HAVE_CTANHF
-/* ctanhl is available */
+/* Define to 1 if you have the `ctanhl' function. */
#undef HAVE_CTANHL
-/* ctanl is available */
+/* Define to 1 if you have the `ctanl' function. */
#undef HAVE_CTANL
/* Define to 1 if you have the <dlfcn.h> header file. */
@@ -321,22 +321,22 @@
/* Define to 1 if you have the `dup2' function. */
#undef HAVE_DUP2
-/* erf is available */
+/* Define to 1 if you have the `erf' function. */
#undef HAVE_ERF
-/* erfc is available */
+/* Define to 1 if you have the `erfc' function. */
#undef HAVE_ERFC
-/* erfcf is available */
+/* Define to 1 if you have the `erfcf' function. */
#undef HAVE_ERFCF
-/* erfcl is available */
+/* Define to 1 if you have the `erfcl' function. */
#undef HAVE_ERFCL
-/* erff is available */
+/* Define to 1 if you have the `erff' function. */
#undef HAVE_ERFF
-/* erfl is available */
+/* Define to 1 if you have the `erfl' function. */
#undef HAVE_ERFL
/* Define to 1 if you have the `execl' function. */
@@ -345,22 +345,22 @@
/* Define to 1 if you have the `execve' function. */
#undef HAVE_EXECVE
-/* exp is available */
+/* Define to 1 if you have the `exp' function. */
#undef HAVE_EXP
-/* expf is available */
+/* Define to 1 if you have the `expf' function. */
#undef HAVE_EXPF
-/* expl is available */
+/* Define to 1 if you have the `expl' function. */
#undef HAVE_EXPL
-/* fabs is available */
+/* Define to 1 if you have the `fabs' function. */
#undef HAVE_FABS
-/* fabsf is available */
+/* Define to 1 if you have the `fabsf' function. */
#undef HAVE_FABSF
-/* fabsl is available */
+/* Define to 1 if you have the `fabsl' function. */
#undef HAVE_FABSL
/* libm includes feenableexcept */
@@ -375,22 +375,22 @@
/* Define to 1 if you have the <floatingpoint.h> header file. */
#undef HAVE_FLOATINGPOINT_H
-/* floor is available */
+/* Define to 1 if you have the `floor' function. */
#undef HAVE_FLOOR
-/* floorf is available */
+/* Define to 1 if you have the `floorf' function. */
#undef HAVE_FLOORF
-/* floorl is available */
+/* Define to 1 if you have the `floorl' function. */
#undef HAVE_FLOORL
-/* fmod is available */
+/* Define to 1 if you have the `fmod' function. */
#undef HAVE_FMOD
-/* fmodf is available */
+/* Define to 1 if you have the `fmodf' function. */
#undef HAVE_FMODF
-/* fmodl is available */
+/* Define to 1 if you have the `fmodl' function. */
#undef HAVE_FMODL
/* Define to 1 if you have the `fork' function. */
@@ -408,13 +408,13 @@
/* fp_trap is present */
#undef HAVE_FP_TRAP
-/* frexp is available */
+/* Define to 1 if you have the `frexp' function. */
#undef HAVE_FREXP
-/* frexpf is available */
+/* Define to 1 if you have the `frexpf' function. */
#undef HAVE_FREXPF
-/* frexpl is available */
+/* Define to 1 if you have the `frexpl' function. */
#undef HAVE_FREXPL
/* Define to 1 if you have the `fstat' function. */
@@ -468,13 +468,13 @@
/* Define to 1 if you have the `gmtime_r' function. */
#undef HAVE_GMTIME_R
-/* hypot is available */
+/* Define to 1 if you have the `hypot' function. */
#undef HAVE_HYPOT
-/* hypotf is available */
+/* Define to 1 if you have the `hypotf' function. */
#undef HAVE_HYPOTF
-/* hypotl is available */
+/* Define to 1 if you have the `hypotl' function. */
#undef HAVE_HYPOTL
/* Define to 1 if you have the <ieeefp.h> header file. */
@@ -486,52 +486,52 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
-/* j0 is available */
+/* Define to 1 if you have the `j0' function. */
#undef HAVE_J0
-/* j0f is available */
+/* Define to 1 if you have the `j0f' function. */
#undef HAVE_J0F
-/* j0l is available */
+/* Define to 1 if you have the `j0l' function. */
#undef HAVE_J0L
-/* j1 is available */
+/* Define to 1 if you have the `j1' function. */
#undef HAVE_J1
-/* j1f is available */
+/* Define to 1 if you have the `j1f' function. */
#undef HAVE_J1F
-/* j1l is available */
+/* Define to 1 if you have the `j1l' function. */
#undef HAVE_J1L
-/* jn is available */
+/* Define to 1 if you have the `jn' function. */
#undef HAVE_JN
-/* jnf is available */
+/* Define to 1 if you have the `jnf' function. */
#undef HAVE_JNF
-/* jnl is available */
+/* Define to 1 if you have the `jnl' function. */
#undef HAVE_JNL
/* Define to 1 if you have the `kill' function. */
#undef HAVE_KILL
-/* ldexp is available */
+/* Define to 1 if you have the `ldexp' function. */
#undef HAVE_LDEXP
-/* ldexpf is available */
+/* Define to 1 if you have the `ldexpf' function. */
#undef HAVE_LDEXPF
-/* ldexpl is available */
+/* Define to 1 if you have the `ldexpl' function. */
#undef HAVE_LDEXPL
-/* lgamma is available */
+/* Define to 1 if you have the `lgamma' function. */
#undef HAVE_LGAMMA
-/* lgammaf is available */
+/* Define to 1 if you have the `lgammaf' function. */
#undef HAVE_LGAMMAF
-/* lgammal is available */
+/* Define to 1 if you have the `lgammal' function. */
#undef HAVE_LGAMMAL
/* Define to 1 if you have the `m' library (-lm). */
@@ -540,43 +540,43 @@
/* Define to 1 if you have the `link' function. */
#undef HAVE_LINK
-/* llround is available */
+/* Define to 1 if you have the `llround' function. */
#undef HAVE_LLROUND
-/* llroundf is available */
+/* Define to 1 if you have the `llroundf' function. */
#undef HAVE_LLROUNDF
-/* llroundl is available */
+/* Define to 1 if you have the `llroundl' function. */
#undef HAVE_LLROUNDL
/* Define to 1 if you have the `localtime_r' function. */
#undef HAVE_LOCALTIME_R
-/* log is available */
+/* Define to 1 if you have the `log' function. */
#undef HAVE_LOG
-/* log10 is available */
+/* Define to 1 if you have the `log10' function. */
#undef HAVE_LOG10
-/* log10f is available */
+/* Define to 1 if you have the `log10f' function. */
#undef HAVE_LOG10F
-/* log10l is available */
+/* Define to 1 if you have the `log10l' function. */
#undef HAVE_LOG10L
-/* logf is available */
+/* Define to 1 if you have the `logf' function. */
#undef HAVE_LOGF
-/* logl is available */
+/* Define to 1 if you have the `logl' function. */
#undef HAVE_LOGL
-/* lround is available */
+/* Define to 1 if you have the `lround' function. */
#undef HAVE_LROUND
-/* lroundf is available */
+/* Define to 1 if you have the `lroundf' function. */
#undef HAVE_LROUNDF
-/* lroundl is available */
+/* Define to 1 if you have the `lroundl' function. */
#undef HAVE_LROUNDL
/* Define to 1 if you have the `lstat' function. */
@@ -594,13 +594,13 @@
/* Define to 1 if you have the `mkstemp' function. */
#undef HAVE_MKSTEMP
-/* nextafter is available */
+/* Define to 1 if you have the `nextafter' function. */
#undef HAVE_NEXTAFTER
-/* nextafterf is available */
+/* Define to 1 if you have the `nextafterf' function. */
#undef HAVE_NEXTAFTERF
-/* nextafterl is available */
+/* Define to 1 if you have the `nextafterl' function. */
#undef HAVE_NEXTAFTERL
/* Define to 1 if you have the `pipe' function. */
@@ -609,13 +609,13 @@
/* Define to 1 if we have POSIX getpwuid_r which takes 5 arguments. */
#undef HAVE_POSIX_GETPWUID_R
-/* pow is available */
+/* Define to 1 if you have the `pow' function. */
#undef HAVE_POW
-/* powf is available */
+/* Define to 1 if you have the `powf' function. */
#undef HAVE_POWF
-/* powl is available */
+/* Define to 1 if you have the `powl' function. */
#undef HAVE_POWL
/* Define to 1 if the system has the type `ptrdiff_t'. */
@@ -627,43 +627,43 @@
/* Define to 1 if you have the `readlink' function. */
#undef HAVE_READLINK
-/* round is available */
+/* Define to 1 if you have the `round' function. */
#undef HAVE_ROUND
-/* roundf is available */
+/* Define to 1 if you have the `roundf' function. */
#undef HAVE_ROUNDF
-/* roundl is available */
+/* Define to 1 if you have the `roundl' function. */
#undef HAVE_ROUNDL
-/* scalbn is available */
+/* Define to 1 if you have the `scalbn' function. */
#undef HAVE_SCALBN
-/* scalbnf is available */
+/* Define to 1 if you have the `scalbnf' function. */
#undef HAVE_SCALBNF
-/* scalbnl is available */
+/* Define to 1 if you have the `scalbnl' function. */
#undef HAVE_SCALBNL
/* Define to 1 if you have the `setmode' function. */
#undef HAVE_SETMODE
-/* sin is available */
+/* Define to 1 if you have the `sin' function. */
#undef HAVE_SIN
-/* sinf is available */
+/* Define to 1 if you have the `sinf' function. */
#undef HAVE_SINF
-/* sinh is available */
+/* Define to 1 if you have the `sinh' function. */
#undef HAVE_SINH
-/* sinhf is available */
+/* Define to 1 if you have the `sinhf' function. */
#undef HAVE_SINHF
-/* sinhl is available */
+/* Define to 1 if you have the `sinhl' function. */
#undef HAVE_SINHL
-/* sinl is available */
+/* Define to 1 if you have the `sinl' function. */
#undef HAVE_SINL
/* Define to 1 if you have the `sleep' function. */
@@ -672,13 +672,13 @@
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
-/* sqrt is available */
+/* Define to 1 if you have the `sqrt' function. */
#undef HAVE_SQRT
-/* sqrtf is available */
+/* Define to 1 if you have the `sqrtf' function. */
#undef HAVE_SQRTF
-/* sqrtl is available */
+/* Define to 1 if you have the `sqrtl' function. */
#undef HAVE_SQRTL
/* Define to 1 if you have the `stat' function. */
@@ -741,43 +741,43 @@
/* Define to 1 if you have the <sys/wait.h> header file. */
#undef HAVE_SYS_WAIT_H
-/* tan is available */
+/* Define to 1 if you have the `tan' function. */
#undef HAVE_TAN
-/* tanf is available */
+/* Define to 1 if you have the `tanf' function. */
#undef HAVE_TANF
-/* tanh is available */
+/* Define to 1 if you have the `tanh' function. */
#undef HAVE_TANH
-/* tanhf is available */
+/* Define to 1 if you have the `tanhf' function. */
#undef HAVE_TANHF
-/* tanhl is available */
+/* Define to 1 if you have the `tanhl' function. */
#undef HAVE_TANHL
-/* tanl is available */
+/* Define to 1 if you have the `tanl' function. */
#undef HAVE_TANL
-/* tgamma is available */
+/* Define to 1 if you have the `tgamma' function. */
#undef HAVE_TGAMMA
-/* tgammaf is available */
+/* Define to 1 if you have the `tgammaf' function. */
#undef HAVE_TGAMMAF
-/* tgammal is available */
+/* Define to 1 if you have the `tgammal' function. */
#undef HAVE_TGAMMAL
/* Define to 1 if you have the `times' function. */
#undef HAVE_TIMES
-/* trunc is available */
+/* Define to 1 if you have the `trunc' function. */
#undef HAVE_TRUNC
-/* truncf is available */
+/* Define to 1 if you have the `truncf' function. */
#undef HAVE_TRUNCF
-/* truncl is available */
+/* Define to 1 if you have the `truncl' function. */
#undef HAVE_TRUNCL
/* Define to 1 if you have the `ttyname' function. */
@@ -807,31 +807,31 @@
/* Define if target has a reliable stat. */
#undef HAVE_WORKING_STAT
-/* y0 is available */
+/* Define to 1 if you have the `y0' function. */
#undef HAVE_Y0
-/* y0f is available */
+/* Define to 1 if you have the `y0f' function. */
#undef HAVE_Y0F
-/* y0l is available */
+/* Define to 1 if you have the `y0l' function. */
#undef HAVE_Y0L
-/* y1 is available */
+/* Define to 1 if you have the `y1' function. */
#undef HAVE_Y1
-/* y1f is available */
+/* Define to 1 if you have the `y1f' function. */
#undef HAVE_Y1F
-/* y1l is available */
+/* Define to 1 if you have the `y1l' function. */
#undef HAVE_Y1L
-/* yn is available */
+/* Define to 1 if you have the `yn' function. */
#undef HAVE_YN
-/* ynf is available */
+/* Define to 1 if you have the `ynf' function. */
#undef HAVE_YNF
-/* ynl is available */
+/* Define to 1 if you have the `ynl' function. */
#undef HAVE_YNL
/* Define to the sub-directory in which libtool stores uninstalled libraries.
diff --git a/libgfortran/configure b/libgfortran/configure
index 1be1cdedadc..b80f5453d00 100755
--- a/libgfortran/configure
+++ b/libgfortran/configure
@@ -16630,7 +16630,9 @@ fi
$as_echo "$gcc_cv_math_func_acosf" >&6; }
if test $gcc_cv_math_func_acosf = yes; then
-$as_echo "#define HAVE_ACOSF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ACOSF 1
+_ACEOF
fi
@@ -16676,7 +16678,9 @@ fi
$as_echo "$gcc_cv_math_func_acos" >&6; }
if test $gcc_cv_math_func_acos = yes; then
-$as_echo "#define HAVE_ACOS 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ACOS 1
+_ACEOF
fi
@@ -16722,7 +16726,9 @@ fi
$as_echo "$gcc_cv_math_func_acosl" >&6; }
if test $gcc_cv_math_func_acosl = yes; then
-$as_echo "#define HAVE_ACOSL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ACOSL 1
+_ACEOF
fi
@@ -16768,7 +16774,9 @@ fi
$as_echo "$gcc_cv_math_func_acoshf" >&6; }
if test $gcc_cv_math_func_acoshf = yes; then
-$as_echo "#define HAVE_ACOSHF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ACOSHF 1
+_ACEOF
fi
@@ -16814,7 +16822,9 @@ fi
$as_echo "$gcc_cv_math_func_acosh" >&6; }
if test $gcc_cv_math_func_acosh = yes; then
-$as_echo "#define HAVE_ACOSH 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ACOSH 1
+_ACEOF
fi
@@ -16860,7 +16870,9 @@ fi
$as_echo "$gcc_cv_math_func_acoshl" >&6; }
if test $gcc_cv_math_func_acoshl = yes; then
-$as_echo "#define HAVE_ACOSHL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ACOSHL 1
+_ACEOF
fi
@@ -16906,7 +16918,9 @@ fi
$as_echo "$gcc_cv_math_func_asinf" >&6; }
if test $gcc_cv_math_func_asinf = yes; then
-$as_echo "#define HAVE_ASINF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ASINF 1
+_ACEOF
fi
@@ -16952,7 +16966,9 @@ fi
$as_echo "$gcc_cv_math_func_asin" >&6; }
if test $gcc_cv_math_func_asin = yes; then
-$as_echo "#define HAVE_ASIN 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ASIN 1
+_ACEOF
fi
@@ -16998,7 +17014,9 @@ fi
$as_echo "$gcc_cv_math_func_asinl" >&6; }
if test $gcc_cv_math_func_asinl = yes; then
-$as_echo "#define HAVE_ASINL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ASINL 1
+_ACEOF
fi
@@ -17044,7 +17062,9 @@ fi
$as_echo "$gcc_cv_math_func_asinhf" >&6; }
if test $gcc_cv_math_func_asinhf = yes; then
-$as_echo "#define HAVE_ASINHF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ASINHF 1
+_ACEOF
fi
@@ -17090,7 +17110,9 @@ fi
$as_echo "$gcc_cv_math_func_asinh" >&6; }
if test $gcc_cv_math_func_asinh = yes; then
-$as_echo "#define HAVE_ASINH 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ASINH 1
+_ACEOF
fi
@@ -17136,7 +17158,9 @@ fi
$as_echo "$gcc_cv_math_func_asinhl" >&6; }
if test $gcc_cv_math_func_asinhl = yes; then
-$as_echo "#define HAVE_ASINHL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ASINHL 1
+_ACEOF
fi
@@ -17182,7 +17206,9 @@ fi
$as_echo "$gcc_cv_math_func_atan2f" >&6; }
if test $gcc_cv_math_func_atan2f = yes; then
-$as_echo "#define HAVE_ATAN2F 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ATAN2F 1
+_ACEOF
fi
@@ -17228,7 +17254,9 @@ fi
$as_echo "$gcc_cv_math_func_atan2" >&6; }
if test $gcc_cv_math_func_atan2 = yes; then
-$as_echo "#define HAVE_ATAN2 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ATAN2 1
+_ACEOF
fi
@@ -17274,7 +17302,9 @@ fi
$as_echo "$gcc_cv_math_func_atan2l" >&6; }
if test $gcc_cv_math_func_atan2l = yes; then
-$as_echo "#define HAVE_ATAN2L 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ATAN2L 1
+_ACEOF
fi
@@ -17320,7 +17350,9 @@ fi
$as_echo "$gcc_cv_math_func_atanf" >&6; }
if test $gcc_cv_math_func_atanf = yes; then
-$as_echo "#define HAVE_ATANF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ATANF 1
+_ACEOF
fi
@@ -17366,7 +17398,9 @@ fi
$as_echo "$gcc_cv_math_func_atan" >&6; }
if test $gcc_cv_math_func_atan = yes; then
-$as_echo "#define HAVE_ATAN 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ATAN 1
+_ACEOF
fi
@@ -17412,7 +17446,9 @@ fi
$as_echo "$gcc_cv_math_func_atanl" >&6; }
if test $gcc_cv_math_func_atanl = yes; then
-$as_echo "#define HAVE_ATANL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ATANL 1
+_ACEOF
fi
@@ -17458,7 +17494,9 @@ fi
$as_echo "$gcc_cv_math_func_atanhf" >&6; }
if test $gcc_cv_math_func_atanhf = yes; then
-$as_echo "#define HAVE_ATANHF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ATANHF 1
+_ACEOF
fi
@@ -17504,7 +17542,9 @@ fi
$as_echo "$gcc_cv_math_func_atanh" >&6; }
if test $gcc_cv_math_func_atanh = yes; then
-$as_echo "#define HAVE_ATANH 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ATANH 1
+_ACEOF
fi
@@ -17550,7 +17590,9 @@ fi
$as_echo "$gcc_cv_math_func_atanhl" >&6; }
if test $gcc_cv_math_func_atanhl = yes; then
-$as_echo "#define HAVE_ATANHL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ATANHL 1
+_ACEOF
fi
@@ -17596,7 +17638,9 @@ fi
$as_echo "$gcc_cv_math_func_cargf" >&6; }
if test $gcc_cv_math_func_cargf = yes; then
-$as_echo "#define HAVE_CARGF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CARGF 1
+_ACEOF
fi
@@ -17642,7 +17686,9 @@ fi
$as_echo "$gcc_cv_math_func_carg" >&6; }
if test $gcc_cv_math_func_carg = yes; then
-$as_echo "#define HAVE_CARG 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CARG 1
+_ACEOF
fi
@@ -17688,7 +17734,9 @@ fi
$as_echo "$gcc_cv_math_func_cargl" >&6; }
if test $gcc_cv_math_func_cargl = yes; then
-$as_echo "#define HAVE_CARGL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CARGL 1
+_ACEOF
fi
@@ -17734,7 +17782,9 @@ fi
$as_echo "$gcc_cv_math_func_ceilf" >&6; }
if test $gcc_cv_math_func_ceilf = yes; then
-$as_echo "#define HAVE_CEILF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CEILF 1
+_ACEOF
fi
@@ -17780,7 +17830,9 @@ fi
$as_echo "$gcc_cv_math_func_ceil" >&6; }
if test $gcc_cv_math_func_ceil = yes; then
-$as_echo "#define HAVE_CEIL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CEIL 1
+_ACEOF
fi
@@ -17826,7 +17878,9 @@ fi
$as_echo "$gcc_cv_math_func_ceill" >&6; }
if test $gcc_cv_math_func_ceill = yes; then
-$as_echo "#define HAVE_CEILL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CEILL 1
+_ACEOF
fi
@@ -17872,7 +17926,9 @@ fi
$as_echo "$gcc_cv_math_func_copysignf" >&6; }
if test $gcc_cv_math_func_copysignf = yes; then
-$as_echo "#define HAVE_COPYSIGNF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_COPYSIGNF 1
+_ACEOF
fi
@@ -17918,7 +17974,9 @@ fi
$as_echo "$gcc_cv_math_func_copysign" >&6; }
if test $gcc_cv_math_func_copysign = yes; then
-$as_echo "#define HAVE_COPYSIGN 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_COPYSIGN 1
+_ACEOF
fi
@@ -17964,7 +18022,9 @@ fi
$as_echo "$gcc_cv_math_func_copysignl" >&6; }
if test $gcc_cv_math_func_copysignl = yes; then
-$as_echo "#define HAVE_COPYSIGNL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_COPYSIGNL 1
+_ACEOF
fi
@@ -18010,7 +18070,9 @@ fi
$as_echo "$gcc_cv_math_func_cosf" >&6; }
if test $gcc_cv_math_func_cosf = yes; then
-$as_echo "#define HAVE_COSF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_COSF 1
+_ACEOF
fi
@@ -18056,7 +18118,9 @@ fi
$as_echo "$gcc_cv_math_func_cos" >&6; }
if test $gcc_cv_math_func_cos = yes; then
-$as_echo "#define HAVE_COS 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_COS 1
+_ACEOF
fi
@@ -18102,7 +18166,9 @@ fi
$as_echo "$gcc_cv_math_func_cosl" >&6; }
if test $gcc_cv_math_func_cosl = yes; then
-$as_echo "#define HAVE_COSL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_COSL 1
+_ACEOF
fi
@@ -18148,7 +18214,9 @@ fi
$as_echo "$gcc_cv_math_func_ccosf" >&6; }
if test $gcc_cv_math_func_ccosf = yes; then
-$as_echo "#define HAVE_CCOSF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CCOSF 1
+_ACEOF
fi
@@ -18194,7 +18262,9 @@ fi
$as_echo "$gcc_cv_math_func_ccos" >&6; }
if test $gcc_cv_math_func_ccos = yes; then
-$as_echo "#define HAVE_CCOS 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CCOS 1
+_ACEOF
fi
@@ -18240,7 +18310,9 @@ fi
$as_echo "$gcc_cv_math_func_ccosl" >&6; }
if test $gcc_cv_math_func_ccosl = yes; then
-$as_echo "#define HAVE_CCOSL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CCOSL 1
+_ACEOF
fi
@@ -18286,7 +18358,9 @@ fi
$as_echo "$gcc_cv_math_func_coshf" >&6; }
if test $gcc_cv_math_func_coshf = yes; then
-$as_echo "#define HAVE_COSHF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_COSHF 1
+_ACEOF
fi
@@ -18332,7 +18406,9 @@ fi
$as_echo "$gcc_cv_math_func_cosh" >&6; }
if test $gcc_cv_math_func_cosh = yes; then
-$as_echo "#define HAVE_COSH 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_COSH 1
+_ACEOF
fi
@@ -18378,7 +18454,9 @@ fi
$as_echo "$gcc_cv_math_func_coshl" >&6; }
if test $gcc_cv_math_func_coshl = yes; then
-$as_echo "#define HAVE_COSHL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_COSHL 1
+_ACEOF
fi
@@ -18424,7 +18502,9 @@ fi
$as_echo "$gcc_cv_math_func_ccoshf" >&6; }
if test $gcc_cv_math_func_ccoshf = yes; then
-$as_echo "#define HAVE_CCOSHF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CCOSHF 1
+_ACEOF
fi
@@ -18470,7 +18550,9 @@ fi
$as_echo "$gcc_cv_math_func_ccosh" >&6; }
if test $gcc_cv_math_func_ccosh = yes; then
-$as_echo "#define HAVE_CCOSH 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CCOSH 1
+_ACEOF
fi
@@ -18516,7 +18598,9 @@ fi
$as_echo "$gcc_cv_math_func_ccoshl" >&6; }
if test $gcc_cv_math_func_ccoshl = yes; then
-$as_echo "#define HAVE_CCOSHL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CCOSHL 1
+_ACEOF
fi
@@ -18562,7 +18646,9 @@ fi
$as_echo "$gcc_cv_math_func_expf" >&6; }
if test $gcc_cv_math_func_expf = yes; then
-$as_echo "#define HAVE_EXPF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_EXPF 1
+_ACEOF
fi
@@ -18608,7 +18694,9 @@ fi
$as_echo "$gcc_cv_math_func_exp" >&6; }
if test $gcc_cv_math_func_exp = yes; then
-$as_echo "#define HAVE_EXP 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_EXP 1
+_ACEOF
fi
@@ -18654,7 +18742,9 @@ fi
$as_echo "$gcc_cv_math_func_expl" >&6; }
if test $gcc_cv_math_func_expl = yes; then
-$as_echo "#define HAVE_EXPL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_EXPL 1
+_ACEOF
fi
@@ -18700,7 +18790,9 @@ fi
$as_echo "$gcc_cv_math_func_cexpf" >&6; }
if test $gcc_cv_math_func_cexpf = yes; then
-$as_echo "#define HAVE_CEXPF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CEXPF 1
+_ACEOF
fi
@@ -18746,7 +18838,9 @@ fi
$as_echo "$gcc_cv_math_func_cexp" >&6; }
if test $gcc_cv_math_func_cexp = yes; then
-$as_echo "#define HAVE_CEXP 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CEXP 1
+_ACEOF
fi
@@ -18792,7 +18886,9 @@ fi
$as_echo "$gcc_cv_math_func_cexpl" >&6; }
if test $gcc_cv_math_func_cexpl = yes; then
-$as_echo "#define HAVE_CEXPL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CEXPL 1
+_ACEOF
fi
@@ -18838,7 +18934,9 @@ fi
$as_echo "$gcc_cv_math_func_fabsf" >&6; }
if test $gcc_cv_math_func_fabsf = yes; then
-$as_echo "#define HAVE_FABSF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FABSF 1
+_ACEOF
fi
@@ -18884,7 +18982,9 @@ fi
$as_echo "$gcc_cv_math_func_fabs" >&6; }
if test $gcc_cv_math_func_fabs = yes; then
-$as_echo "#define HAVE_FABS 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FABS 1
+_ACEOF
fi
@@ -18930,7 +19030,9 @@ fi
$as_echo "$gcc_cv_math_func_fabsl" >&6; }
if test $gcc_cv_math_func_fabsl = yes; then
-$as_echo "#define HAVE_FABSL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FABSL 1
+_ACEOF
fi
@@ -18976,7 +19078,9 @@ fi
$as_echo "$gcc_cv_math_func_cabsf" >&6; }
if test $gcc_cv_math_func_cabsf = yes; then
-$as_echo "#define HAVE_CABSF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CABSF 1
+_ACEOF
fi
@@ -19022,7 +19126,9 @@ fi
$as_echo "$gcc_cv_math_func_cabs" >&6; }
if test $gcc_cv_math_func_cabs = yes; then
-$as_echo "#define HAVE_CABS 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CABS 1
+_ACEOF
fi
@@ -19068,7 +19174,9 @@ fi
$as_echo "$gcc_cv_math_func_cabsl" >&6; }
if test $gcc_cv_math_func_cabsl = yes; then
-$as_echo "#define HAVE_CABSL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CABSL 1
+_ACEOF
fi
@@ -19114,7 +19222,9 @@ fi
$as_echo "$gcc_cv_math_func_floorf" >&6; }
if test $gcc_cv_math_func_floorf = yes; then
-$as_echo "#define HAVE_FLOORF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FLOORF 1
+_ACEOF
fi
@@ -19160,7 +19270,9 @@ fi
$as_echo "$gcc_cv_math_func_floor" >&6; }
if test $gcc_cv_math_func_floor = yes; then
-$as_echo "#define HAVE_FLOOR 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FLOOR 1
+_ACEOF
fi
@@ -19206,7 +19318,9 @@ fi
$as_echo "$gcc_cv_math_func_floorl" >&6; }
if test $gcc_cv_math_func_floorl = yes; then
-$as_echo "#define HAVE_FLOORL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FLOORL 1
+_ACEOF
fi
@@ -19252,7 +19366,9 @@ fi
$as_echo "$gcc_cv_math_func_fmodf" >&6; }
if test $gcc_cv_math_func_fmodf = yes; then
-$as_echo "#define HAVE_FMODF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FMODF 1
+_ACEOF
fi
@@ -19298,7 +19414,9 @@ fi
$as_echo "$gcc_cv_math_func_fmod" >&6; }
if test $gcc_cv_math_func_fmod = yes; then
-$as_echo "#define HAVE_FMOD 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FMOD 1
+_ACEOF
fi
@@ -19344,7 +19462,9 @@ fi
$as_echo "$gcc_cv_math_func_fmodl" >&6; }
if test $gcc_cv_math_func_fmodl = yes; then
-$as_echo "#define HAVE_FMODL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FMODL 1
+_ACEOF
fi
@@ -19390,7 +19510,9 @@ fi
$as_echo "$gcc_cv_math_func_frexpf" >&6; }
if test $gcc_cv_math_func_frexpf = yes; then
-$as_echo "#define HAVE_FREXPF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FREXPF 1
+_ACEOF
fi
@@ -19436,7 +19558,9 @@ fi
$as_echo "$gcc_cv_math_func_frexp" >&6; }
if test $gcc_cv_math_func_frexp = yes; then
-$as_echo "#define HAVE_FREXP 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FREXP 1
+_ACEOF
fi
@@ -19482,7 +19606,9 @@ fi
$as_echo "$gcc_cv_math_func_frexpl" >&6; }
if test $gcc_cv_math_func_frexpl = yes; then
-$as_echo "#define HAVE_FREXPL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FREXPL 1
+_ACEOF
fi
@@ -19528,7 +19654,9 @@ fi
$as_echo "$gcc_cv_math_func_hypotf" >&6; }
if test $gcc_cv_math_func_hypotf = yes; then
-$as_echo "#define HAVE_HYPOTF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_HYPOTF 1
+_ACEOF
fi
@@ -19574,7 +19702,9 @@ fi
$as_echo "$gcc_cv_math_func_hypot" >&6; }
if test $gcc_cv_math_func_hypot = yes; then
-$as_echo "#define HAVE_HYPOT 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_HYPOT 1
+_ACEOF
fi
@@ -19620,7 +19750,9 @@ fi
$as_echo "$gcc_cv_math_func_hypotl" >&6; }
if test $gcc_cv_math_func_hypotl = yes; then
-$as_echo "#define HAVE_HYPOTL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_HYPOTL 1
+_ACEOF
fi
@@ -19666,7 +19798,9 @@ fi
$as_echo "$gcc_cv_math_func_ldexpf" >&6; }
if test $gcc_cv_math_func_ldexpf = yes; then
-$as_echo "#define HAVE_LDEXPF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LDEXPF 1
+_ACEOF
fi
@@ -19712,7 +19846,9 @@ fi
$as_echo "$gcc_cv_math_func_ldexp" >&6; }
if test $gcc_cv_math_func_ldexp = yes; then
-$as_echo "#define HAVE_LDEXP 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LDEXP 1
+_ACEOF
fi
@@ -19758,7 +19894,9 @@ fi
$as_echo "$gcc_cv_math_func_ldexpl" >&6; }
if test $gcc_cv_math_func_ldexpl = yes; then
-$as_echo "#define HAVE_LDEXPL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LDEXPL 1
+_ACEOF
fi
@@ -19804,7 +19942,9 @@ fi
$as_echo "$gcc_cv_math_func_logf" >&6; }
if test $gcc_cv_math_func_logf = yes; then
-$as_echo "#define HAVE_LOGF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LOGF 1
+_ACEOF
fi
@@ -19850,7 +19990,9 @@ fi
$as_echo "$gcc_cv_math_func_log" >&6; }
if test $gcc_cv_math_func_log = yes; then
-$as_echo "#define HAVE_LOG 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LOG 1
+_ACEOF
fi
@@ -19896,7 +20038,9 @@ fi
$as_echo "$gcc_cv_math_func_logl" >&6; }
if test $gcc_cv_math_func_logl = yes; then
-$as_echo "#define HAVE_LOGL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LOGL 1
+_ACEOF
fi
@@ -19942,7 +20086,9 @@ fi
$as_echo "$gcc_cv_math_func_clogf" >&6; }
if test $gcc_cv_math_func_clogf = yes; then
-$as_echo "#define HAVE_CLOGF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CLOGF 1
+_ACEOF
fi
@@ -19988,7 +20134,9 @@ fi
$as_echo "$gcc_cv_math_func_clog" >&6; }
if test $gcc_cv_math_func_clog = yes; then
-$as_echo "#define HAVE_CLOG 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CLOG 1
+_ACEOF
fi
@@ -20034,7 +20182,9 @@ fi
$as_echo "$gcc_cv_math_func_clogl" >&6; }
if test $gcc_cv_math_func_clogl = yes; then
-$as_echo "#define HAVE_CLOGL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CLOGL 1
+_ACEOF
fi
@@ -20080,7 +20230,9 @@ fi
$as_echo "$gcc_cv_math_func_log10f" >&6; }
if test $gcc_cv_math_func_log10f = yes; then
-$as_echo "#define HAVE_LOG10F 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LOG10F 1
+_ACEOF
fi
@@ -20126,7 +20278,9 @@ fi
$as_echo "$gcc_cv_math_func_log10" >&6; }
if test $gcc_cv_math_func_log10 = yes; then
-$as_echo "#define HAVE_LOG10 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LOG10 1
+_ACEOF
fi
@@ -20172,7 +20326,9 @@ fi
$as_echo "$gcc_cv_math_func_log10l" >&6; }
if test $gcc_cv_math_func_log10l = yes; then
-$as_echo "#define HAVE_LOG10L 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LOG10L 1
+_ACEOF
fi
@@ -20218,7 +20374,9 @@ fi
$as_echo "$gcc_cv_math_func_clog10f" >&6; }
if test $gcc_cv_math_func_clog10f = yes; then
-$as_echo "#define HAVE_CLOG10F 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CLOG10F 1
+_ACEOF
fi
@@ -20264,7 +20422,9 @@ fi
$as_echo "$gcc_cv_math_func_clog10" >&6; }
if test $gcc_cv_math_func_clog10 = yes; then
-$as_echo "#define HAVE_CLOG10 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CLOG10 1
+_ACEOF
fi
@@ -20310,7 +20470,9 @@ fi
$as_echo "$gcc_cv_math_func_clog10l" >&6; }
if test $gcc_cv_math_func_clog10l = yes; then
-$as_echo "#define HAVE_CLOG10L 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CLOG10L 1
+_ACEOF
fi
@@ -20356,7 +20518,9 @@ fi
$as_echo "$gcc_cv_math_func_nextafterf" >&6; }
if test $gcc_cv_math_func_nextafterf = yes; then
-$as_echo "#define HAVE_NEXTAFTERF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_NEXTAFTERF 1
+_ACEOF
fi
@@ -20402,7 +20566,9 @@ fi
$as_echo "$gcc_cv_math_func_nextafter" >&6; }
if test $gcc_cv_math_func_nextafter = yes; then
-$as_echo "#define HAVE_NEXTAFTER 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_NEXTAFTER 1
+_ACEOF
fi
@@ -20448,7 +20614,9 @@ fi
$as_echo "$gcc_cv_math_func_nextafterl" >&6; }
if test $gcc_cv_math_func_nextafterl = yes; then
-$as_echo "#define HAVE_NEXTAFTERL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_NEXTAFTERL 1
+_ACEOF
fi
@@ -20494,7 +20662,9 @@ fi
$as_echo "$gcc_cv_math_func_powf" >&6; }
if test $gcc_cv_math_func_powf = yes; then
-$as_echo "#define HAVE_POWF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_POWF 1
+_ACEOF
fi
@@ -20540,7 +20710,9 @@ fi
$as_echo "$gcc_cv_math_func_pow" >&6; }
if test $gcc_cv_math_func_pow = yes; then
-$as_echo "#define HAVE_POW 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_POW 1
+_ACEOF
fi
@@ -20586,7 +20758,9 @@ fi
$as_echo "$gcc_cv_math_func_powl" >&6; }
if test $gcc_cv_math_func_powl = yes; then
-$as_echo "#define HAVE_POWL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_POWL 1
+_ACEOF
fi
@@ -20632,7 +20806,9 @@ fi
$as_echo "$gcc_cv_math_func_cpowf" >&6; }
if test $gcc_cv_math_func_cpowf = yes; then
-$as_echo "#define HAVE_CPOWF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CPOWF 1
+_ACEOF
fi
@@ -20678,7 +20854,9 @@ fi
$as_echo "$gcc_cv_math_func_cpow" >&6; }
if test $gcc_cv_math_func_cpow = yes; then
-$as_echo "#define HAVE_CPOW 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CPOW 1
+_ACEOF
fi
@@ -20724,7 +20902,9 @@ fi
$as_echo "$gcc_cv_math_func_cpowl" >&6; }
if test $gcc_cv_math_func_cpowl = yes; then
-$as_echo "#define HAVE_CPOWL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CPOWL 1
+_ACEOF
fi
@@ -20770,7 +20950,9 @@ fi
$as_echo "$gcc_cv_math_func_roundf" >&6; }
if test $gcc_cv_math_func_roundf = yes; then
-$as_echo "#define HAVE_ROUNDF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ROUNDF 1
+_ACEOF
fi
@@ -20816,7 +20998,9 @@ fi
$as_echo "$gcc_cv_math_func_round" >&6; }
if test $gcc_cv_math_func_round = yes; then
-$as_echo "#define HAVE_ROUND 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ROUND 1
+_ACEOF
fi
@@ -20862,7 +21046,9 @@ fi
$as_echo "$gcc_cv_math_func_roundl" >&6; }
if test $gcc_cv_math_func_roundl = yes; then
-$as_echo "#define HAVE_ROUNDL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ROUNDL 1
+_ACEOF
fi
@@ -20908,7 +21094,9 @@ fi
$as_echo "$gcc_cv_math_func_lroundf" >&6; }
if test $gcc_cv_math_func_lroundf = yes; then
-$as_echo "#define HAVE_LROUNDF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LROUNDF 1
+_ACEOF
fi
@@ -20954,7 +21142,9 @@ fi
$as_echo "$gcc_cv_math_func_lround" >&6; }
if test $gcc_cv_math_func_lround = yes; then
-$as_echo "#define HAVE_LROUND 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LROUND 1
+_ACEOF
fi
@@ -21000,7 +21190,9 @@ fi
$as_echo "$gcc_cv_math_func_lroundl" >&6; }
if test $gcc_cv_math_func_lroundl = yes; then
-$as_echo "#define HAVE_LROUNDL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LROUNDL 1
+_ACEOF
fi
@@ -21046,7 +21238,9 @@ fi
$as_echo "$gcc_cv_math_func_llroundf" >&6; }
if test $gcc_cv_math_func_llroundf = yes; then
-$as_echo "#define HAVE_LLROUNDF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LLROUNDF 1
+_ACEOF
fi
@@ -21092,7 +21286,9 @@ fi
$as_echo "$gcc_cv_math_func_llround" >&6; }
if test $gcc_cv_math_func_llround = yes; then
-$as_echo "#define HAVE_LLROUND 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LLROUND 1
+_ACEOF
fi
@@ -21138,7 +21334,9 @@ fi
$as_echo "$gcc_cv_math_func_llroundl" >&6; }
if test $gcc_cv_math_func_llroundl = yes; then
-$as_echo "#define HAVE_LLROUNDL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LLROUNDL 1
+_ACEOF
fi
@@ -21184,7 +21382,9 @@ fi
$as_echo "$gcc_cv_math_func_scalbnf" >&6; }
if test $gcc_cv_math_func_scalbnf = yes; then
-$as_echo "#define HAVE_SCALBNF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SCALBNF 1
+_ACEOF
fi
@@ -21230,7 +21430,9 @@ fi
$as_echo "$gcc_cv_math_func_scalbn" >&6; }
if test $gcc_cv_math_func_scalbn = yes; then
-$as_echo "#define HAVE_SCALBN 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SCALBN 1
+_ACEOF
fi
@@ -21276,7 +21478,9 @@ fi
$as_echo "$gcc_cv_math_func_scalbnl" >&6; }
if test $gcc_cv_math_func_scalbnl = yes; then
-$as_echo "#define HAVE_SCALBNL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SCALBNL 1
+_ACEOF
fi
@@ -21322,7 +21526,9 @@ fi
$as_echo "$gcc_cv_math_func_sinf" >&6; }
if test $gcc_cv_math_func_sinf = yes; then
-$as_echo "#define HAVE_SINF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SINF 1
+_ACEOF
fi
@@ -21368,7 +21574,9 @@ fi
$as_echo "$gcc_cv_math_func_sin" >&6; }
if test $gcc_cv_math_func_sin = yes; then
-$as_echo "#define HAVE_SIN 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SIN 1
+_ACEOF
fi
@@ -21414,7 +21622,9 @@ fi
$as_echo "$gcc_cv_math_func_sinl" >&6; }
if test $gcc_cv_math_func_sinl = yes; then
-$as_echo "#define HAVE_SINL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SINL 1
+_ACEOF
fi
@@ -21460,7 +21670,9 @@ fi
$as_echo "$gcc_cv_math_func_csinf" >&6; }
if test $gcc_cv_math_func_csinf = yes; then
-$as_echo "#define HAVE_CSINF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CSINF 1
+_ACEOF
fi
@@ -21506,7 +21718,9 @@ fi
$as_echo "$gcc_cv_math_func_csin" >&6; }
if test $gcc_cv_math_func_csin = yes; then
-$as_echo "#define HAVE_CSIN 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CSIN 1
+_ACEOF
fi
@@ -21552,7 +21766,9 @@ fi
$as_echo "$gcc_cv_math_func_csinl" >&6; }
if test $gcc_cv_math_func_csinl = yes; then
-$as_echo "#define HAVE_CSINL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CSINL 1
+_ACEOF
fi
@@ -21598,7 +21814,9 @@ fi
$as_echo "$gcc_cv_math_func_sinhf" >&6; }
if test $gcc_cv_math_func_sinhf = yes; then
-$as_echo "#define HAVE_SINHF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SINHF 1
+_ACEOF
fi
@@ -21644,7 +21862,9 @@ fi
$as_echo "$gcc_cv_math_func_sinh" >&6; }
if test $gcc_cv_math_func_sinh = yes; then
-$as_echo "#define HAVE_SINH 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SINH 1
+_ACEOF
fi
@@ -21690,7 +21910,9 @@ fi
$as_echo "$gcc_cv_math_func_sinhl" >&6; }
if test $gcc_cv_math_func_sinhl = yes; then
-$as_echo "#define HAVE_SINHL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SINHL 1
+_ACEOF
fi
@@ -21736,7 +21958,9 @@ fi
$as_echo "$gcc_cv_math_func_csinhf" >&6; }
if test $gcc_cv_math_func_csinhf = yes; then
-$as_echo "#define HAVE_CSINHF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CSINHF 1
+_ACEOF
fi
@@ -21782,7 +22006,9 @@ fi
$as_echo "$gcc_cv_math_func_csinh" >&6; }
if test $gcc_cv_math_func_csinh = yes; then
-$as_echo "#define HAVE_CSINH 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CSINH 1
+_ACEOF
fi
@@ -21828,7 +22054,9 @@ fi
$as_echo "$gcc_cv_math_func_csinhl" >&6; }
if test $gcc_cv_math_func_csinhl = yes; then
-$as_echo "#define HAVE_CSINHL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CSINHL 1
+_ACEOF
fi
@@ -21874,7 +22102,9 @@ fi
$as_echo "$gcc_cv_math_func_sqrtf" >&6; }
if test $gcc_cv_math_func_sqrtf = yes; then
-$as_echo "#define HAVE_SQRTF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SQRTF 1
+_ACEOF
fi
@@ -21920,7 +22150,9 @@ fi
$as_echo "$gcc_cv_math_func_sqrt" >&6; }
if test $gcc_cv_math_func_sqrt = yes; then
-$as_echo "#define HAVE_SQRT 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SQRT 1
+_ACEOF
fi
@@ -21966,7 +22198,9 @@ fi
$as_echo "$gcc_cv_math_func_sqrtl" >&6; }
if test $gcc_cv_math_func_sqrtl = yes; then
-$as_echo "#define HAVE_SQRTL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SQRTL 1
+_ACEOF
fi
@@ -22012,7 +22246,9 @@ fi
$as_echo "$gcc_cv_math_func_csqrtf" >&6; }
if test $gcc_cv_math_func_csqrtf = yes; then
-$as_echo "#define HAVE_CSQRTF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CSQRTF 1
+_ACEOF
fi
@@ -22058,7 +22294,9 @@ fi
$as_echo "$gcc_cv_math_func_csqrt" >&6; }
if test $gcc_cv_math_func_csqrt = yes; then
-$as_echo "#define HAVE_CSQRT 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CSQRT 1
+_ACEOF
fi
@@ -22104,7 +22342,9 @@ fi
$as_echo "$gcc_cv_math_func_csqrtl" >&6; }
if test $gcc_cv_math_func_csqrtl = yes; then
-$as_echo "#define HAVE_CSQRTL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CSQRTL 1
+_ACEOF
fi
@@ -22150,7 +22390,9 @@ fi
$as_echo "$gcc_cv_math_func_tanf" >&6; }
if test $gcc_cv_math_func_tanf = yes; then
-$as_echo "#define HAVE_TANF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_TANF 1
+_ACEOF
fi
@@ -22196,7 +22438,9 @@ fi
$as_echo "$gcc_cv_math_func_tan" >&6; }
if test $gcc_cv_math_func_tan = yes; then
-$as_echo "#define HAVE_TAN 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_TAN 1
+_ACEOF
fi
@@ -22242,7 +22486,9 @@ fi
$as_echo "$gcc_cv_math_func_tanl" >&6; }
if test $gcc_cv_math_func_tanl = yes; then
-$as_echo "#define HAVE_TANL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_TANL 1
+_ACEOF
fi
@@ -22288,7 +22534,9 @@ fi
$as_echo "$gcc_cv_math_func_ctanf" >&6; }
if test $gcc_cv_math_func_ctanf = yes; then
-$as_echo "#define HAVE_CTANF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CTANF 1
+_ACEOF
fi
@@ -22334,7 +22582,9 @@ fi
$as_echo "$gcc_cv_math_func_ctan" >&6; }
if test $gcc_cv_math_func_ctan = yes; then
-$as_echo "#define HAVE_CTAN 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CTAN 1
+_ACEOF
fi
@@ -22380,7 +22630,9 @@ fi
$as_echo "$gcc_cv_math_func_ctanl" >&6; }
if test $gcc_cv_math_func_ctanl = yes; then
-$as_echo "#define HAVE_CTANL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CTANL 1
+_ACEOF
fi
@@ -22426,7 +22678,9 @@ fi
$as_echo "$gcc_cv_math_func_tanhf" >&6; }
if test $gcc_cv_math_func_tanhf = yes; then
-$as_echo "#define HAVE_TANHF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_TANHF 1
+_ACEOF
fi
@@ -22472,7 +22726,9 @@ fi
$as_echo "$gcc_cv_math_func_tanh" >&6; }
if test $gcc_cv_math_func_tanh = yes; then
-$as_echo "#define HAVE_TANH 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_TANH 1
+_ACEOF
fi
@@ -22518,7 +22774,9 @@ fi
$as_echo "$gcc_cv_math_func_tanhl" >&6; }
if test $gcc_cv_math_func_tanhl = yes; then
-$as_echo "#define HAVE_TANHL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_TANHL 1
+_ACEOF
fi
@@ -22564,7 +22822,9 @@ fi
$as_echo "$gcc_cv_math_func_ctanhf" >&6; }
if test $gcc_cv_math_func_ctanhf = yes; then
-$as_echo "#define HAVE_CTANHF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CTANHF 1
+_ACEOF
fi
@@ -22610,7 +22870,9 @@ fi
$as_echo "$gcc_cv_math_func_ctanh" >&6; }
if test $gcc_cv_math_func_ctanh = yes; then
-$as_echo "#define HAVE_CTANH 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CTANH 1
+_ACEOF
fi
@@ -22656,7 +22918,9 @@ fi
$as_echo "$gcc_cv_math_func_ctanhl" >&6; }
if test $gcc_cv_math_func_ctanhl = yes; then
-$as_echo "#define HAVE_CTANHL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CTANHL 1
+_ACEOF
fi
@@ -22702,7 +22966,9 @@ fi
$as_echo "$gcc_cv_math_func_truncf" >&6; }
if test $gcc_cv_math_func_truncf = yes; then
-$as_echo "#define HAVE_TRUNCF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_TRUNCF 1
+_ACEOF
fi
@@ -22748,7 +23014,9 @@ fi
$as_echo "$gcc_cv_math_func_trunc" >&6; }
if test $gcc_cv_math_func_trunc = yes; then
-$as_echo "#define HAVE_TRUNC 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_TRUNC 1
+_ACEOF
fi
@@ -22794,7 +23062,9 @@ fi
$as_echo "$gcc_cv_math_func_truncl" >&6; }
if test $gcc_cv_math_func_truncl = yes; then
-$as_echo "#define HAVE_TRUNCL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_TRUNCL 1
+_ACEOF
fi
@@ -22840,7 +23110,9 @@ fi
$as_echo "$gcc_cv_math_func_erff" >&6; }
if test $gcc_cv_math_func_erff = yes; then
-$as_echo "#define HAVE_ERFF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ERFF 1
+_ACEOF
fi
@@ -22886,7 +23158,9 @@ fi
$as_echo "$gcc_cv_math_func_erf" >&6; }
if test $gcc_cv_math_func_erf = yes; then
-$as_echo "#define HAVE_ERF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ERF 1
+_ACEOF
fi
@@ -22932,7 +23206,9 @@ fi
$as_echo "$gcc_cv_math_func_erfl" >&6; }
if test $gcc_cv_math_func_erfl = yes; then
-$as_echo "#define HAVE_ERFL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ERFL 1
+_ACEOF
fi
@@ -22978,7 +23254,9 @@ fi
$as_echo "$gcc_cv_math_func_erfcf" >&6; }
if test $gcc_cv_math_func_erfcf = yes; then
-$as_echo "#define HAVE_ERFCF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ERFCF 1
+_ACEOF
fi
@@ -23024,7 +23302,9 @@ fi
$as_echo "$gcc_cv_math_func_erfc" >&6; }
if test $gcc_cv_math_func_erfc = yes; then
-$as_echo "#define HAVE_ERFC 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ERFC 1
+_ACEOF
fi
@@ -23070,7 +23350,9 @@ fi
$as_echo "$gcc_cv_math_func_erfcl" >&6; }
if test $gcc_cv_math_func_erfcl = yes; then
-$as_echo "#define HAVE_ERFCL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ERFCL 1
+_ACEOF
fi
@@ -23116,7 +23398,9 @@ fi
$as_echo "$gcc_cv_math_func_j0f" >&6; }
if test $gcc_cv_math_func_j0f = yes; then
-$as_echo "#define HAVE_J0F 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_J0F 1
+_ACEOF
fi
@@ -23162,7 +23446,9 @@ fi
$as_echo "$gcc_cv_math_func_j0" >&6; }
if test $gcc_cv_math_func_j0 = yes; then
-$as_echo "#define HAVE_J0 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_J0 1
+_ACEOF
fi
@@ -23208,7 +23494,9 @@ fi
$as_echo "$gcc_cv_math_func_j0l" >&6; }
if test $gcc_cv_math_func_j0l = yes; then
-$as_echo "#define HAVE_J0L 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_J0L 1
+_ACEOF
fi
@@ -23254,7 +23542,9 @@ fi
$as_echo "$gcc_cv_math_func_j1f" >&6; }
if test $gcc_cv_math_func_j1f = yes; then
-$as_echo "#define HAVE_J1F 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_J1F 1
+_ACEOF
fi
@@ -23300,7 +23590,9 @@ fi
$as_echo "$gcc_cv_math_func_j1" >&6; }
if test $gcc_cv_math_func_j1 = yes; then
-$as_echo "#define HAVE_J1 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_J1 1
+_ACEOF
fi
@@ -23346,7 +23638,9 @@ fi
$as_echo "$gcc_cv_math_func_j1l" >&6; }
if test $gcc_cv_math_func_j1l = yes; then
-$as_echo "#define HAVE_J1L 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_J1L 1
+_ACEOF
fi
@@ -23392,7 +23686,9 @@ fi
$as_echo "$gcc_cv_math_func_jnf" >&6; }
if test $gcc_cv_math_func_jnf = yes; then
-$as_echo "#define HAVE_JNF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_JNF 1
+_ACEOF
fi
@@ -23438,7 +23734,9 @@ fi
$as_echo "$gcc_cv_math_func_jn" >&6; }
if test $gcc_cv_math_func_jn = yes; then
-$as_echo "#define HAVE_JN 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_JN 1
+_ACEOF
fi
@@ -23484,7 +23782,9 @@ fi
$as_echo "$gcc_cv_math_func_jnl" >&6; }
if test $gcc_cv_math_func_jnl = yes; then
-$as_echo "#define HAVE_JNL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_JNL 1
+_ACEOF
fi
@@ -23530,7 +23830,9 @@ fi
$as_echo "$gcc_cv_math_func_y0f" >&6; }
if test $gcc_cv_math_func_y0f = yes; then
-$as_echo "#define HAVE_Y0F 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_Y0F 1
+_ACEOF
fi
@@ -23576,7 +23878,9 @@ fi
$as_echo "$gcc_cv_math_func_y0" >&6; }
if test $gcc_cv_math_func_y0 = yes; then
-$as_echo "#define HAVE_Y0 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_Y0 1
+_ACEOF
fi
@@ -23622,7 +23926,9 @@ fi
$as_echo "$gcc_cv_math_func_y0l" >&6; }
if test $gcc_cv_math_func_y0l = yes; then
-$as_echo "#define HAVE_Y0L 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_Y0L 1
+_ACEOF
fi
@@ -23668,7 +23974,9 @@ fi
$as_echo "$gcc_cv_math_func_y1f" >&6; }
if test $gcc_cv_math_func_y1f = yes; then
-$as_echo "#define HAVE_Y1F 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_Y1F 1
+_ACEOF
fi
@@ -23714,7 +24022,9 @@ fi
$as_echo "$gcc_cv_math_func_y1" >&6; }
if test $gcc_cv_math_func_y1 = yes; then
-$as_echo "#define HAVE_Y1 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_Y1 1
+_ACEOF
fi
@@ -23760,7 +24070,9 @@ fi
$as_echo "$gcc_cv_math_func_y1l" >&6; }
if test $gcc_cv_math_func_y1l = yes; then
-$as_echo "#define HAVE_Y1L 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_Y1L 1
+_ACEOF
fi
@@ -23806,7 +24118,9 @@ fi
$as_echo "$gcc_cv_math_func_ynf" >&6; }
if test $gcc_cv_math_func_ynf = yes; then
-$as_echo "#define HAVE_YNF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_YNF 1
+_ACEOF
fi
@@ -23852,7 +24166,9 @@ fi
$as_echo "$gcc_cv_math_func_yn" >&6; }
if test $gcc_cv_math_func_yn = yes; then
-$as_echo "#define HAVE_YN 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_YN 1
+_ACEOF
fi
@@ -23898,7 +24214,9 @@ fi
$as_echo "$gcc_cv_math_func_ynl" >&6; }
if test $gcc_cv_math_func_ynl = yes; then
-$as_echo "#define HAVE_YNL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_YNL 1
+_ACEOF
fi
@@ -23944,7 +24262,9 @@ fi
$as_echo "$gcc_cv_math_func_tgamma" >&6; }
if test $gcc_cv_math_func_tgamma = yes; then
-$as_echo "#define HAVE_TGAMMA 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_TGAMMA 1
+_ACEOF
fi
@@ -23990,7 +24310,9 @@ fi
$as_echo "$gcc_cv_math_func_tgammaf" >&6; }
if test $gcc_cv_math_func_tgammaf = yes; then
-$as_echo "#define HAVE_TGAMMAF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_TGAMMAF 1
+_ACEOF
fi
@@ -24036,7 +24358,9 @@ fi
$as_echo "$gcc_cv_math_func_tgammal" >&6; }
if test $gcc_cv_math_func_tgammal = yes; then
-$as_echo "#define HAVE_TGAMMAL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_TGAMMAL 1
+_ACEOF
fi
@@ -24082,7 +24406,9 @@ fi
$as_echo "$gcc_cv_math_func_lgamma" >&6; }
if test $gcc_cv_math_func_lgamma = yes; then
-$as_echo "#define HAVE_LGAMMA 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LGAMMA 1
+_ACEOF
fi
@@ -24128,7 +24454,9 @@ fi
$as_echo "$gcc_cv_math_func_lgammaf" >&6; }
if test $gcc_cv_math_func_lgammaf = yes; then
-$as_echo "#define HAVE_LGAMMAF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LGAMMAF 1
+_ACEOF
fi
@@ -24174,7 +24502,9 @@ fi
$as_echo "$gcc_cv_math_func_lgammal" >&6; }
if test $gcc_cv_math_func_lgammal = yes; then
-$as_echo "#define HAVE_LGAMMAL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LGAMMAL 1
+_ACEOF
fi
@@ -24222,7 +24552,9 @@ fi
$as_echo "$gcc_cv_math_func_cacos" >&6; }
if test $gcc_cv_math_func_cacos = yes; then
-$as_echo "#define HAVE_CACOS 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CACOS 1
+_ACEOF
fi
@@ -24268,7 +24600,9 @@ fi
$as_echo "$gcc_cv_math_func_cacosf" >&6; }
if test $gcc_cv_math_func_cacosf = yes; then
-$as_echo "#define HAVE_CACOSF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CACOSF 1
+_ACEOF
fi
@@ -24314,7 +24648,9 @@ fi
$as_echo "$gcc_cv_math_func_cacosh" >&6; }
if test $gcc_cv_math_func_cacosh = yes; then
-$as_echo "#define HAVE_CACOSH 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CACOSH 1
+_ACEOF
fi
@@ -24360,7 +24696,9 @@ fi
$as_echo "$gcc_cv_math_func_cacoshf" >&6; }
if test $gcc_cv_math_func_cacoshf = yes; then
-$as_echo "#define HAVE_CACOSHF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CACOSHF 1
+_ACEOF
fi
@@ -24406,7 +24744,9 @@ fi
$as_echo "$gcc_cv_math_func_cacoshl" >&6; }
if test $gcc_cv_math_func_cacoshl = yes; then
-$as_echo "#define HAVE_CACOSHL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CACOSHL 1
+_ACEOF
fi
@@ -24452,7 +24792,9 @@ fi
$as_echo "$gcc_cv_math_func_cacosl" >&6; }
if test $gcc_cv_math_func_cacosl = yes; then
-$as_echo "#define HAVE_CACOSL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CACOSL 1
+_ACEOF
fi
@@ -24498,7 +24840,9 @@ fi
$as_echo "$gcc_cv_math_func_casin" >&6; }
if test $gcc_cv_math_func_casin = yes; then
-$as_echo "#define HAVE_CASIN 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CASIN 1
+_ACEOF
fi
@@ -24544,7 +24888,9 @@ fi
$as_echo "$gcc_cv_math_func_casinf" >&6; }
if test $gcc_cv_math_func_casinf = yes; then
-$as_echo "#define HAVE_CASINF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CASINF 1
+_ACEOF
fi
@@ -24590,7 +24936,9 @@ fi
$as_echo "$gcc_cv_math_func_casinh" >&6; }
if test $gcc_cv_math_func_casinh = yes; then
-$as_echo "#define HAVE_CASINH 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CASINH 1
+_ACEOF
fi
@@ -24636,7 +24984,9 @@ fi
$as_echo "$gcc_cv_math_func_casinhf" >&6; }
if test $gcc_cv_math_func_casinhf = yes; then
-$as_echo "#define HAVE_CASINHF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CASINHF 1
+_ACEOF
fi
@@ -24682,7 +25032,9 @@ fi
$as_echo "$gcc_cv_math_func_casinhl" >&6; }
if test $gcc_cv_math_func_casinhl = yes; then
-$as_echo "#define HAVE_CASINHL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CASINHL 1
+_ACEOF
fi
@@ -24728,7 +25080,9 @@ fi
$as_echo "$gcc_cv_math_func_casinl" >&6; }
if test $gcc_cv_math_func_casinl = yes; then
-$as_echo "#define HAVE_CASINL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CASINL 1
+_ACEOF
fi
@@ -24774,7 +25128,9 @@ fi
$as_echo "$gcc_cv_math_func_catan" >&6; }
if test $gcc_cv_math_func_catan = yes; then
-$as_echo "#define HAVE_CATAN 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CATAN 1
+_ACEOF
fi
@@ -24820,7 +25176,9 @@ fi
$as_echo "$gcc_cv_math_func_catanf" >&6; }
if test $gcc_cv_math_func_catanf = yes; then
-$as_echo "#define HAVE_CATANF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CATANF 1
+_ACEOF
fi
@@ -24866,7 +25224,9 @@ fi
$as_echo "$gcc_cv_math_func_catanh" >&6; }
if test $gcc_cv_math_func_catanh = yes; then
-$as_echo "#define HAVE_CATANH 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CATANH 1
+_ACEOF
fi
@@ -24912,7 +25272,9 @@ fi
$as_echo "$gcc_cv_math_func_catanhf" >&6; }
if test $gcc_cv_math_func_catanhf = yes; then
-$as_echo "#define HAVE_CATANHF 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CATANHF 1
+_ACEOF
fi
@@ -24958,7 +25320,9 @@ fi
$as_echo "$gcc_cv_math_func_catanhl" >&6; }
if test $gcc_cv_math_func_catanhl = yes; then
-$as_echo "#define HAVE_CATANHL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CATANHL 1
+_ACEOF
fi
@@ -25004,7 +25368,9 @@ fi
$as_echo "$gcc_cv_math_func_catanl" >&6; }
if test $gcc_cv_math_func_catanl = yes; then
-$as_echo "#define HAVE_CATANL 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CATANL 1
+_ACEOF
fi
diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac
index 08eb7896e38..d70924e8fcf 100644
--- a/libgfortran/configure.ac
+++ b/libgfortran/configure.ac
@@ -269,191 +269,191 @@ getcwd localtime_r gmtime_r strerror_r getpwuid_r ttyname_r clock_gettime \
readlink getgid getpid getppid getuid geteuid umask)
# Check for C99 (and other IEEE) math functions
-GCC_CHECK_MATH_FUNC([acosf],[AC_DEFINE([HAVE_ACOSF],[1],[acosf is available])])
-GCC_CHECK_MATH_FUNC([acos],[AC_DEFINE([HAVE_ACOS],[1],[acos is available])])
-GCC_CHECK_MATH_FUNC([acosl],[AC_DEFINE([HAVE_ACOSL],[1],[acosl is available])])
-GCC_CHECK_MATH_FUNC([acoshf],[AC_DEFINE([HAVE_ACOSHF],[1],[acoshf is available])])
-GCC_CHECK_MATH_FUNC([acosh],[AC_DEFINE([HAVE_ACOSH],[1],[acosh is available])])
-GCC_CHECK_MATH_FUNC([acoshl],[AC_DEFINE([HAVE_ACOSHL],[1],[acoshl is available])])
-GCC_CHECK_MATH_FUNC([asinf],[AC_DEFINE([HAVE_ASINF],[1],[asinf is available])])
-GCC_CHECK_MATH_FUNC([asin],[AC_DEFINE([HAVE_ASIN],[1],[asin is available])])
-GCC_CHECK_MATH_FUNC([asinl],[AC_DEFINE([HAVE_ASINL],[1],[asinl is available])])
-GCC_CHECK_MATH_FUNC([asinhf],[AC_DEFINE([HAVE_ASINHF],[1],[asinhf is available])])
-GCC_CHECK_MATH_FUNC([asinh],[AC_DEFINE([HAVE_ASINH],[1],[asinh is available])])
-GCC_CHECK_MATH_FUNC([asinhl],[AC_DEFINE([HAVE_ASINHL],[1],[asinhl is available])])
-GCC_CHECK_MATH_FUNC([atan2f],[AC_DEFINE([HAVE_ATAN2F],[1],[atan2f is available])])
-GCC_CHECK_MATH_FUNC([atan2],[AC_DEFINE([HAVE_ATAN2],[1],[atan2 is available])])
-GCC_CHECK_MATH_FUNC([atan2l],[AC_DEFINE([HAVE_ATAN2L],[1],[atan2l is available])])
-GCC_CHECK_MATH_FUNC([atanf],[AC_DEFINE([HAVE_ATANF],[1],[atanf is available])])
-GCC_CHECK_MATH_FUNC([atan],[AC_DEFINE([HAVE_ATAN],[1],[atan is available])])
-GCC_CHECK_MATH_FUNC([atanl],[AC_DEFINE([HAVE_ATANL],[1],[atanl is available])])
-GCC_CHECK_MATH_FUNC([atanhf],[AC_DEFINE([HAVE_ATANHF],[1],[atanhf is available])])
-GCC_CHECK_MATH_FUNC([atanh],[AC_DEFINE([HAVE_ATANH],[1],[atanh is available])])
-GCC_CHECK_MATH_FUNC([atanhl],[AC_DEFINE([HAVE_ATANHL],[1],[atanhl is available])])
-GCC_CHECK_MATH_FUNC([cargf],[AC_DEFINE([HAVE_CARGF],[1],[cargf is available])])
-GCC_CHECK_MATH_FUNC([carg],[AC_DEFINE([HAVE_CARG],[1],[carg is available])])
-GCC_CHECK_MATH_FUNC([cargl],[AC_DEFINE([HAVE_CARGL],[1],[cargl is available])])
-GCC_CHECK_MATH_FUNC([ceilf],[AC_DEFINE([HAVE_CEILF],[1],[ceilf is available])])
-GCC_CHECK_MATH_FUNC([ceil],[AC_DEFINE([HAVE_CEIL],[1],[ceil is available])])
-GCC_CHECK_MATH_FUNC([ceill],[AC_DEFINE([HAVE_CEILL],[1],[ceill is available])])
-GCC_CHECK_MATH_FUNC([copysignf],[AC_DEFINE([HAVE_COPYSIGNF],[1],[copysignf is available])])
-GCC_CHECK_MATH_FUNC([copysign],[AC_DEFINE([HAVE_COPYSIGN],[1],[copysign is available])])
-GCC_CHECK_MATH_FUNC([copysignl],[AC_DEFINE([HAVE_COPYSIGNL],[1],[copysignl is available])])
-GCC_CHECK_MATH_FUNC([cosf],[AC_DEFINE([HAVE_COSF],[1],[cosf is available])])
-GCC_CHECK_MATH_FUNC([cos],[AC_DEFINE([HAVE_COS],[1],[cos is available])])
-GCC_CHECK_MATH_FUNC([cosl],[AC_DEFINE([HAVE_COSL],[1],[cosl is available])])
-GCC_CHECK_MATH_FUNC([ccosf],[AC_DEFINE([HAVE_CCOSF],[1],[ccosf is available])])
-GCC_CHECK_MATH_FUNC([ccos],[AC_DEFINE([HAVE_CCOS],[1],[ccos is available])])
-GCC_CHECK_MATH_FUNC([ccosl],[AC_DEFINE([HAVE_CCOSL],[1],[ccosl is available])])
-GCC_CHECK_MATH_FUNC([coshf],[AC_DEFINE([HAVE_COSHF],[1],[coshf is available])])
-GCC_CHECK_MATH_FUNC([cosh],[AC_DEFINE([HAVE_COSH],[1],[cosh is available])])
-GCC_CHECK_MATH_FUNC([coshl],[AC_DEFINE([HAVE_COSHL],[1],[coshl is available])])
-GCC_CHECK_MATH_FUNC([ccoshf],[AC_DEFINE([HAVE_CCOSHF],[1],[ccoshf is available])])
-GCC_CHECK_MATH_FUNC([ccosh],[AC_DEFINE([HAVE_CCOSH],[1],[ccosh is available])])
-GCC_CHECK_MATH_FUNC([ccoshl],[AC_DEFINE([HAVE_CCOSHL],[1],[ccoshl is available])])
-GCC_CHECK_MATH_FUNC([expf],[AC_DEFINE([HAVE_EXPF],[1],[expf is available])])
-GCC_CHECK_MATH_FUNC([exp],[AC_DEFINE([HAVE_EXP],[1],[exp is available])])
-GCC_CHECK_MATH_FUNC([expl],[AC_DEFINE([HAVE_EXPL],[1],[expl is available])])
-GCC_CHECK_MATH_FUNC([cexpf],[AC_DEFINE([HAVE_CEXPF],[1],[cexpf is available])])
-GCC_CHECK_MATH_FUNC([cexp],[AC_DEFINE([HAVE_CEXP],[1],[cexp is available])])
-GCC_CHECK_MATH_FUNC([cexpl],[AC_DEFINE([HAVE_CEXPL],[1],[cexpl is available])])
-GCC_CHECK_MATH_FUNC([fabsf],[AC_DEFINE([HAVE_FABSF],[1],[fabsf is available])])
-GCC_CHECK_MATH_FUNC([fabs],[AC_DEFINE([HAVE_FABS],[1],[fabs is available])])
-GCC_CHECK_MATH_FUNC([fabsl],[AC_DEFINE([HAVE_FABSL],[1],[fabsl is available])])
-GCC_CHECK_MATH_FUNC([cabsf],[AC_DEFINE([HAVE_CABSF],[1],[cabsf is available])])
-GCC_CHECK_MATH_FUNC([cabs],[AC_DEFINE([HAVE_CABS],[1],[cabs is available])])
-GCC_CHECK_MATH_FUNC([cabsl],[AC_DEFINE([HAVE_CABSL],[1],[cabsl is available])])
-GCC_CHECK_MATH_FUNC([floorf],[AC_DEFINE([HAVE_FLOORF],[1],[floorf is available])])
-GCC_CHECK_MATH_FUNC([floor],[AC_DEFINE([HAVE_FLOOR],[1],[floor is available])])
-GCC_CHECK_MATH_FUNC([floorl],[AC_DEFINE([HAVE_FLOORL],[1],[floorl is available])])
-GCC_CHECK_MATH_FUNC([fmodf],[AC_DEFINE([HAVE_FMODF],[1],[fmodf is available])])
-GCC_CHECK_MATH_FUNC([fmod],[AC_DEFINE([HAVE_FMOD],[1],[fmod is available])])
-GCC_CHECK_MATH_FUNC([fmodl],[AC_DEFINE([HAVE_FMODL],[1],[fmodl is available])])
-GCC_CHECK_MATH_FUNC([frexpf],[AC_DEFINE([HAVE_FREXPF],[1],[frexpf is available])])
-GCC_CHECK_MATH_FUNC([frexp],[AC_DEFINE([HAVE_FREXP],[1],[frexp is available])])
-GCC_CHECK_MATH_FUNC([frexpl],[AC_DEFINE([HAVE_FREXPL],[1],[frexpl is available])])
-GCC_CHECK_MATH_FUNC([hypotf],[AC_DEFINE([HAVE_HYPOTF],[1],[hypotf is available])])
-GCC_CHECK_MATH_FUNC([hypot],[AC_DEFINE([HAVE_HYPOT],[1],[hypot is available])])
-GCC_CHECK_MATH_FUNC([hypotl],[AC_DEFINE([HAVE_HYPOTL],[1],[hypotl is available])])
-GCC_CHECK_MATH_FUNC([ldexpf],[AC_DEFINE([HAVE_LDEXPF],[1],[ldexpf is available])])
-GCC_CHECK_MATH_FUNC([ldexp],[AC_DEFINE([HAVE_LDEXP],[1],[ldexp is available])])
-GCC_CHECK_MATH_FUNC([ldexpl],[AC_DEFINE([HAVE_LDEXPL],[1],[ldexpl is available])])
-GCC_CHECK_MATH_FUNC([logf],[AC_DEFINE([HAVE_LOGF],[1],[logf is available])])
-GCC_CHECK_MATH_FUNC([log],[AC_DEFINE([HAVE_LOG],[1],[log is available])])
-GCC_CHECK_MATH_FUNC([logl],[AC_DEFINE([HAVE_LOGL],[1],[logl is available])])
-GCC_CHECK_MATH_FUNC([clogf],[AC_DEFINE([HAVE_CLOGF],[1],[clogf is available])])
-GCC_CHECK_MATH_FUNC([clog],[AC_DEFINE([HAVE_CLOG],[1],[clog is available])])
-GCC_CHECK_MATH_FUNC([clogl],[AC_DEFINE([HAVE_CLOGL],[1],[clogl is available])])
-GCC_CHECK_MATH_FUNC([log10f],[AC_DEFINE([HAVE_LOG10F],[1],[log10f is available])])
-GCC_CHECK_MATH_FUNC([log10],[AC_DEFINE([HAVE_LOG10],[1],[log10 is available])])
-GCC_CHECK_MATH_FUNC([log10l],[AC_DEFINE([HAVE_LOG10L],[1],[log10l is available])])
-GCC_CHECK_MATH_FUNC([clog10f],[AC_DEFINE([HAVE_CLOG10F],[1],[clog10f is available])])
-GCC_CHECK_MATH_FUNC([clog10],[AC_DEFINE([HAVE_CLOG10],[1],[clog10 is available])])
-GCC_CHECK_MATH_FUNC([clog10l],[AC_DEFINE([HAVE_CLOG10L],[1],[clog10l is available])])
-GCC_CHECK_MATH_FUNC([nextafterf],[AC_DEFINE([HAVE_NEXTAFTERF],[1],[nextafterf is available])])
-GCC_CHECK_MATH_FUNC([nextafter],[AC_DEFINE([HAVE_NEXTAFTER],[1],[nextafter is available])])
-GCC_CHECK_MATH_FUNC([nextafterl],[AC_DEFINE([HAVE_NEXTAFTERL],[1],[nextafterl is available])])
-GCC_CHECK_MATH_FUNC([powf],[AC_DEFINE([HAVE_POWF],[1],[powf is available])])
-GCC_CHECK_MATH_FUNC([pow],[AC_DEFINE([HAVE_POW],[1],[pow is available])])
-GCC_CHECK_MATH_FUNC([powl],[AC_DEFINE([HAVE_POWL],[1],[powl is available])])
-GCC_CHECK_MATH_FUNC([cpowf],[AC_DEFINE([HAVE_CPOWF],[1],[cpowf is available])])
-GCC_CHECK_MATH_FUNC([cpow],[AC_DEFINE([HAVE_CPOW],[1],[cpow is available])])
-GCC_CHECK_MATH_FUNC([cpowl],[AC_DEFINE([HAVE_CPOWL],[1],[cpowl is available])])
-GCC_CHECK_MATH_FUNC([roundf],[AC_DEFINE([HAVE_ROUNDF],[1],[roundf is available])])
-GCC_CHECK_MATH_FUNC([round],[AC_DEFINE([HAVE_ROUND],[1],[round is available])])
-GCC_CHECK_MATH_FUNC([roundl],[AC_DEFINE([HAVE_ROUNDL],[1],[roundl is available])])
-GCC_CHECK_MATH_FUNC([lroundf],[AC_DEFINE([HAVE_LROUNDF],[1],[lroundf is available])])
-GCC_CHECK_MATH_FUNC([lround],[AC_DEFINE([HAVE_LROUND],[1],[lround is available])])
-GCC_CHECK_MATH_FUNC([lroundl],[AC_DEFINE([HAVE_LROUNDL],[1],[lroundl is available])])
-GCC_CHECK_MATH_FUNC([llroundf],[AC_DEFINE([HAVE_LLROUNDF],[1],[llroundf is available])])
-GCC_CHECK_MATH_FUNC([llround],[AC_DEFINE([HAVE_LLROUND],[1],[llround is available])])
-GCC_CHECK_MATH_FUNC([llroundl],[AC_DEFINE([HAVE_LLROUNDL],[1],[llroundl is available])])
-GCC_CHECK_MATH_FUNC([scalbnf],[AC_DEFINE([HAVE_SCALBNF],[1],[scalbnf is available])])
-GCC_CHECK_MATH_FUNC([scalbn],[AC_DEFINE([HAVE_SCALBN],[1],[scalbn is available])])
-GCC_CHECK_MATH_FUNC([scalbnl],[AC_DEFINE([HAVE_SCALBNL],[1],[scalbnl is available])])
-GCC_CHECK_MATH_FUNC([sinf],[AC_DEFINE([HAVE_SINF],[1],[sinf is available])])
-GCC_CHECK_MATH_FUNC([sin],[AC_DEFINE([HAVE_SIN],[1],[sin is available])])
-GCC_CHECK_MATH_FUNC([sinl],[AC_DEFINE([HAVE_SINL],[1],[sinl is available])])
-GCC_CHECK_MATH_FUNC([csinf],[AC_DEFINE([HAVE_CSINF],[1],[csinf is available])])
-GCC_CHECK_MATH_FUNC([csin],[AC_DEFINE([HAVE_CSIN],[1],[csin is available])])
-GCC_CHECK_MATH_FUNC([csinl],[AC_DEFINE([HAVE_CSINL],[1],[csinl is available])])
-GCC_CHECK_MATH_FUNC([sinhf],[AC_DEFINE([HAVE_SINHF],[1],[sinhf is available])])
-GCC_CHECK_MATH_FUNC([sinh],[AC_DEFINE([HAVE_SINH],[1],[sinh is available])])
-GCC_CHECK_MATH_FUNC([sinhl],[AC_DEFINE([HAVE_SINHL],[1],[sinhl is available])])
-GCC_CHECK_MATH_FUNC([csinhf],[AC_DEFINE([HAVE_CSINHF],[1],[csinhf is available])])
-GCC_CHECK_MATH_FUNC([csinh],[AC_DEFINE([HAVE_CSINH],[1],[csinh is available])])
-GCC_CHECK_MATH_FUNC([csinhl],[AC_DEFINE([HAVE_CSINHL],[1],[csinhl is available])])
-GCC_CHECK_MATH_FUNC([sqrtf],[AC_DEFINE([HAVE_SQRTF],[1],[sqrtf is available])])
-GCC_CHECK_MATH_FUNC([sqrt],[AC_DEFINE([HAVE_SQRT],[1],[sqrt is available])])
-GCC_CHECK_MATH_FUNC([sqrtl],[AC_DEFINE([HAVE_SQRTL],[1],[sqrtl is available])])
-GCC_CHECK_MATH_FUNC([csqrtf],[AC_DEFINE([HAVE_CSQRTF],[1],[csqrtf is available])])
-GCC_CHECK_MATH_FUNC([csqrt],[AC_DEFINE([HAVE_CSQRT],[1],[csqrt is available])])
-GCC_CHECK_MATH_FUNC([csqrtl],[AC_DEFINE([HAVE_CSQRTL],[1],[csqrtl is available])])
-GCC_CHECK_MATH_FUNC([tanf],[AC_DEFINE([HAVE_TANF],[1],[tanf is available])])
-GCC_CHECK_MATH_FUNC([tan],[AC_DEFINE([HAVE_TAN],[1],[tan is available])])
-GCC_CHECK_MATH_FUNC([tanl],[AC_DEFINE([HAVE_TANL],[1],[tanl is available])])
-GCC_CHECK_MATH_FUNC([ctanf],[AC_DEFINE([HAVE_CTANF],[1],[ctanf is available])])
-GCC_CHECK_MATH_FUNC([ctan],[AC_DEFINE([HAVE_CTAN],[1],[ctan is available])])
-GCC_CHECK_MATH_FUNC([ctanl],[AC_DEFINE([HAVE_CTANL],[1],[ctanl is available])])
-GCC_CHECK_MATH_FUNC([tanhf],[AC_DEFINE([HAVE_TANHF],[1],[tanhf is available])])
-GCC_CHECK_MATH_FUNC([tanh],[AC_DEFINE([HAVE_TANH],[1],[tanh is available])])
-GCC_CHECK_MATH_FUNC([tanhl],[AC_DEFINE([HAVE_TANHL],[1],[tanhl is available])])
-GCC_CHECK_MATH_FUNC([ctanhf],[AC_DEFINE([HAVE_CTANHF],[1],[ctanhf is available])])
-GCC_CHECK_MATH_FUNC([ctanh],[AC_DEFINE([HAVE_CTANH],[1],[ctanh is available])])
-GCC_CHECK_MATH_FUNC([ctanhl],[AC_DEFINE([HAVE_CTANHL],[1],[ctanhl is available])])
-GCC_CHECK_MATH_FUNC([truncf],[AC_DEFINE([HAVE_TRUNCF],[1],[truncf is available])])
-GCC_CHECK_MATH_FUNC([trunc],[AC_DEFINE([HAVE_TRUNC],[1],[trunc is available])])
-GCC_CHECK_MATH_FUNC([truncl],[AC_DEFINE([HAVE_TRUNCL],[1],[truncl is available])])
-GCC_CHECK_MATH_FUNC([erff],[AC_DEFINE([HAVE_ERFF],[1],[erff is available])])
-GCC_CHECK_MATH_FUNC([erf],[AC_DEFINE([HAVE_ERF],[1],[erf is available])])
-GCC_CHECK_MATH_FUNC([erfl],[AC_DEFINE([HAVE_ERFL],[1],[erfl is available])])
-GCC_CHECK_MATH_FUNC([erfcf],[AC_DEFINE([HAVE_ERFCF],[1],[erfcf is available])])
-GCC_CHECK_MATH_FUNC([erfc],[AC_DEFINE([HAVE_ERFC],[1],[erfc is available])])
-GCC_CHECK_MATH_FUNC([erfcl],[AC_DEFINE([HAVE_ERFCL],[1],[erfcl is available])])
-GCC_CHECK_MATH_FUNC([j0f],[AC_DEFINE([HAVE_J0F],[1],[j0f is available])])
-GCC_CHECK_MATH_FUNC([j0],[AC_DEFINE([HAVE_J0],[1],[j0 is available])])
-GCC_CHECK_MATH_FUNC([j0l],[AC_DEFINE([HAVE_J0L],[1],[j0l is available])])
-GCC_CHECK_MATH_FUNC([j1f],[AC_DEFINE([HAVE_J1F],[1],[j1f is available])])
-GCC_CHECK_MATH_FUNC([j1],[AC_DEFINE([HAVE_J1],[1],[j1 is available])])
-GCC_CHECK_MATH_FUNC([j1l],[AC_DEFINE([HAVE_J1L],[1],[j1l is available])])
-GCC_CHECK_MATH_FUNC([jnf],[AC_DEFINE([HAVE_JNF],[1],[jnf is available])])
-GCC_CHECK_MATH_FUNC([jn],[AC_DEFINE([HAVE_JN],[1],[jn is available])])
-GCC_CHECK_MATH_FUNC([jnl],[AC_DEFINE([HAVE_JNL],[1],[jnl is available])])
-GCC_CHECK_MATH_FUNC([y0f],[AC_DEFINE([HAVE_Y0F],[1],[y0f is available])])
-GCC_CHECK_MATH_FUNC([y0],[AC_DEFINE([HAVE_Y0],[1],[y0 is available])])
-GCC_CHECK_MATH_FUNC([y0l],[AC_DEFINE([HAVE_Y0L],[1],[y0l is available])])
-GCC_CHECK_MATH_FUNC([y1f],[AC_DEFINE([HAVE_Y1F],[1],[y1f is available])])
-GCC_CHECK_MATH_FUNC([y1],[AC_DEFINE([HAVE_Y1],[1],[y1 is available])])
-GCC_CHECK_MATH_FUNC([y1l],[AC_DEFINE([HAVE_Y1L],[1],[y1l is available])])
-GCC_CHECK_MATH_FUNC([ynf],[AC_DEFINE([HAVE_YNF],[1],[ynf is available])])
-GCC_CHECK_MATH_FUNC([yn],[AC_DEFINE([HAVE_YN],[1],[yn is available])])
-GCC_CHECK_MATH_FUNC([ynl],[AC_DEFINE([HAVE_YNL],[1],[ynl is available])])
-GCC_CHECK_MATH_FUNC([tgamma],[AC_DEFINE([HAVE_TGAMMA],[1],[tgamma is available])])
-GCC_CHECK_MATH_FUNC([tgammaf],[AC_DEFINE([HAVE_TGAMMAF],[1],[tgammaf is available])])
-GCC_CHECK_MATH_FUNC([tgammal],[AC_DEFINE([HAVE_TGAMMAL],[1],[tgammal is available])])
-GCC_CHECK_MATH_FUNC([lgamma],[AC_DEFINE([HAVE_LGAMMA],[1],[lgamma is available])])
-GCC_CHECK_MATH_FUNC([lgammaf],[AC_DEFINE([HAVE_LGAMMAF],[1],[lgammaf is available])])
-GCC_CHECK_MATH_FUNC([lgammal],[AC_DEFINE([HAVE_LGAMMAL],[1],[lgammal is available])])
+GCC_CHECK_MATH_FUNC([acosf])
+GCC_CHECK_MATH_FUNC([acos])
+GCC_CHECK_MATH_FUNC([acosl])
+GCC_CHECK_MATH_FUNC([acoshf])
+GCC_CHECK_MATH_FUNC([acosh])
+GCC_CHECK_MATH_FUNC([acoshl])
+GCC_CHECK_MATH_FUNC([asinf])
+GCC_CHECK_MATH_FUNC([asin])
+GCC_CHECK_MATH_FUNC([asinl])
+GCC_CHECK_MATH_FUNC([asinhf])
+GCC_CHECK_MATH_FUNC([asinh])
+GCC_CHECK_MATH_FUNC([asinhl])
+GCC_CHECK_MATH_FUNC([atan2f])
+GCC_CHECK_MATH_FUNC([atan2])
+GCC_CHECK_MATH_FUNC([atan2l])
+GCC_CHECK_MATH_FUNC([atanf])
+GCC_CHECK_MATH_FUNC([atan])
+GCC_CHECK_MATH_FUNC([atanl])
+GCC_CHECK_MATH_FUNC([atanhf])
+GCC_CHECK_MATH_FUNC([atanh])
+GCC_CHECK_MATH_FUNC([atanhl])
+GCC_CHECK_MATH_FUNC([cargf])
+GCC_CHECK_MATH_FUNC([carg])
+GCC_CHECK_MATH_FUNC([cargl])
+GCC_CHECK_MATH_FUNC([ceilf])
+GCC_CHECK_MATH_FUNC([ceil])
+GCC_CHECK_MATH_FUNC([ceill])
+GCC_CHECK_MATH_FUNC([copysignf])
+GCC_CHECK_MATH_FUNC([copysign])
+GCC_CHECK_MATH_FUNC([copysignl])
+GCC_CHECK_MATH_FUNC([cosf])
+GCC_CHECK_MATH_FUNC([cos])
+GCC_CHECK_MATH_FUNC([cosl])
+GCC_CHECK_MATH_FUNC([ccosf])
+GCC_CHECK_MATH_FUNC([ccos])
+GCC_CHECK_MATH_FUNC([ccosl])
+GCC_CHECK_MATH_FUNC([coshf])
+GCC_CHECK_MATH_FUNC([cosh])
+GCC_CHECK_MATH_FUNC([coshl])
+GCC_CHECK_MATH_FUNC([ccoshf])
+GCC_CHECK_MATH_FUNC([ccosh])
+GCC_CHECK_MATH_FUNC([ccoshl])
+GCC_CHECK_MATH_FUNC([expf])
+GCC_CHECK_MATH_FUNC([exp])
+GCC_CHECK_MATH_FUNC([expl])
+GCC_CHECK_MATH_FUNC([cexpf])
+GCC_CHECK_MATH_FUNC([cexp])
+GCC_CHECK_MATH_FUNC([cexpl])
+GCC_CHECK_MATH_FUNC([fabsf])
+GCC_CHECK_MATH_FUNC([fabs])
+GCC_CHECK_MATH_FUNC([fabsl])
+GCC_CHECK_MATH_FUNC([cabsf])
+GCC_CHECK_MATH_FUNC([cabs])
+GCC_CHECK_MATH_FUNC([cabsl])
+GCC_CHECK_MATH_FUNC([floorf])
+GCC_CHECK_MATH_FUNC([floor])
+GCC_CHECK_MATH_FUNC([floorl])
+GCC_CHECK_MATH_FUNC([fmodf])
+GCC_CHECK_MATH_FUNC([fmod])
+GCC_CHECK_MATH_FUNC([fmodl])
+GCC_CHECK_MATH_FUNC([frexpf])
+GCC_CHECK_MATH_FUNC([frexp])
+GCC_CHECK_MATH_FUNC([frexpl])
+GCC_CHECK_MATH_FUNC([hypotf])
+GCC_CHECK_MATH_FUNC([hypot])
+GCC_CHECK_MATH_FUNC([hypotl])
+GCC_CHECK_MATH_FUNC([ldexpf])
+GCC_CHECK_MATH_FUNC([ldexp])
+GCC_CHECK_MATH_FUNC([ldexpl])
+GCC_CHECK_MATH_FUNC([logf])
+GCC_CHECK_MATH_FUNC([log])
+GCC_CHECK_MATH_FUNC([logl])
+GCC_CHECK_MATH_FUNC([clogf])
+GCC_CHECK_MATH_FUNC([clog])
+GCC_CHECK_MATH_FUNC([clogl])
+GCC_CHECK_MATH_FUNC([log10f])
+GCC_CHECK_MATH_FUNC([log10])
+GCC_CHECK_MATH_FUNC([log10l])
+GCC_CHECK_MATH_FUNC([clog10f])
+GCC_CHECK_MATH_FUNC([clog10])
+GCC_CHECK_MATH_FUNC([clog10l])
+GCC_CHECK_MATH_FUNC([nextafterf])
+GCC_CHECK_MATH_FUNC([nextafter])
+GCC_CHECK_MATH_FUNC([nextafterl])
+GCC_CHECK_MATH_FUNC([powf])
+GCC_CHECK_MATH_FUNC([pow])
+GCC_CHECK_MATH_FUNC([powl])
+GCC_CHECK_MATH_FUNC([cpowf])
+GCC_CHECK_MATH_FUNC([cpow])
+GCC_CHECK_MATH_FUNC([cpowl])
+GCC_CHECK_MATH_FUNC([roundf])
+GCC_CHECK_MATH_FUNC([round])
+GCC_CHECK_MATH_FUNC([roundl])
+GCC_CHECK_MATH_FUNC([lroundf])
+GCC_CHECK_MATH_FUNC([lround])
+GCC_CHECK_MATH_FUNC([lroundl])
+GCC_CHECK_MATH_FUNC([llroundf])
+GCC_CHECK_MATH_FUNC([llround])
+GCC_CHECK_MATH_FUNC([llroundl])
+GCC_CHECK_MATH_FUNC([scalbnf])
+GCC_CHECK_MATH_FUNC([scalbn])
+GCC_CHECK_MATH_FUNC([scalbnl])
+GCC_CHECK_MATH_FUNC([sinf])
+GCC_CHECK_MATH_FUNC([sin])
+GCC_CHECK_MATH_FUNC([sinl])
+GCC_CHECK_MATH_FUNC([csinf])
+GCC_CHECK_MATH_FUNC([csin])
+GCC_CHECK_MATH_FUNC([csinl])
+GCC_CHECK_MATH_FUNC([sinhf])
+GCC_CHECK_MATH_FUNC([sinh])
+GCC_CHECK_MATH_FUNC([sinhl])
+GCC_CHECK_MATH_FUNC([csinhf])
+GCC_CHECK_MATH_FUNC([csinh])
+GCC_CHECK_MATH_FUNC([csinhl])
+GCC_CHECK_MATH_FUNC([sqrtf])
+GCC_CHECK_MATH_FUNC([sqrt])
+GCC_CHECK_MATH_FUNC([sqrtl])
+GCC_CHECK_MATH_FUNC([csqrtf])
+GCC_CHECK_MATH_FUNC([csqrt])
+GCC_CHECK_MATH_FUNC([csqrtl])
+GCC_CHECK_MATH_FUNC([tanf])
+GCC_CHECK_MATH_FUNC([tan])
+GCC_CHECK_MATH_FUNC([tanl])
+GCC_CHECK_MATH_FUNC([ctanf])
+GCC_CHECK_MATH_FUNC([ctan])
+GCC_CHECK_MATH_FUNC([ctanl])
+GCC_CHECK_MATH_FUNC([tanhf])
+GCC_CHECK_MATH_FUNC([tanh])
+GCC_CHECK_MATH_FUNC([tanhl])
+GCC_CHECK_MATH_FUNC([ctanhf])
+GCC_CHECK_MATH_FUNC([ctanh])
+GCC_CHECK_MATH_FUNC([ctanhl])
+GCC_CHECK_MATH_FUNC([truncf])
+GCC_CHECK_MATH_FUNC([trunc])
+GCC_CHECK_MATH_FUNC([truncl])
+GCC_CHECK_MATH_FUNC([erff])
+GCC_CHECK_MATH_FUNC([erf])
+GCC_CHECK_MATH_FUNC([erfl])
+GCC_CHECK_MATH_FUNC([erfcf])
+GCC_CHECK_MATH_FUNC([erfc])
+GCC_CHECK_MATH_FUNC([erfcl])
+GCC_CHECK_MATH_FUNC([j0f])
+GCC_CHECK_MATH_FUNC([j0])
+GCC_CHECK_MATH_FUNC([j0l])
+GCC_CHECK_MATH_FUNC([j1f])
+GCC_CHECK_MATH_FUNC([j1])
+GCC_CHECK_MATH_FUNC([j1l])
+GCC_CHECK_MATH_FUNC([jnf])
+GCC_CHECK_MATH_FUNC([jn])
+GCC_CHECK_MATH_FUNC([jnl])
+GCC_CHECK_MATH_FUNC([y0f])
+GCC_CHECK_MATH_FUNC([y0])
+GCC_CHECK_MATH_FUNC([y0l])
+GCC_CHECK_MATH_FUNC([y1f])
+GCC_CHECK_MATH_FUNC([y1])
+GCC_CHECK_MATH_FUNC([y1l])
+GCC_CHECK_MATH_FUNC([ynf])
+GCC_CHECK_MATH_FUNC([yn])
+GCC_CHECK_MATH_FUNC([ynl])
+GCC_CHECK_MATH_FUNC([tgamma])
+GCC_CHECK_MATH_FUNC([tgammaf])
+GCC_CHECK_MATH_FUNC([tgammal])
+GCC_CHECK_MATH_FUNC([lgamma])
+GCC_CHECK_MATH_FUNC([lgammaf])
+GCC_CHECK_MATH_FUNC([lgammal])
# Check for GFORTRAN_C99_1.1 funcs
-GCC_CHECK_MATH_FUNC([cacos],[AC_DEFINE([HAVE_CACOS],[1],[cacos is available])])
-GCC_CHECK_MATH_FUNC([cacosf],[AC_DEFINE([HAVE_CACOSF],[1],[cacosf is available])])
-GCC_CHECK_MATH_FUNC([cacosh],[AC_DEFINE([HAVE_CACOSH],[1],[cacosh is available])])
-GCC_CHECK_MATH_FUNC([cacoshf],[AC_DEFINE([HAVE_CACOSHF],[1],[cacoshf is available])])
-GCC_CHECK_MATH_FUNC([cacoshl],[AC_DEFINE([HAVE_CACOSHL],[1],[cacoshl is available])])
-GCC_CHECK_MATH_FUNC([cacosl],[AC_DEFINE([HAVE_CACOSL],[1],[cacosl is available])])
-GCC_CHECK_MATH_FUNC([casin],[AC_DEFINE([HAVE_CASIN],[1],[casin is available])])
-GCC_CHECK_MATH_FUNC([casinf],[AC_DEFINE([HAVE_CASINF],[1],[casinf is available])])
-GCC_CHECK_MATH_FUNC([casinh],[AC_DEFINE([HAVE_CASINH],[1],[casinh is available])])
-GCC_CHECK_MATH_FUNC([casinhf],[AC_DEFINE([HAVE_CASINHF],[1],[casinhf is available])])
-GCC_CHECK_MATH_FUNC([casinhl],[AC_DEFINE([HAVE_CASINHL],[1],[casinhl is available])])
-GCC_CHECK_MATH_FUNC([casinl],[AC_DEFINE([HAVE_CASINL],[1],[casinl is available])])
-GCC_CHECK_MATH_FUNC([catan],[AC_DEFINE([HAVE_CATAN],[1],[catan is available])])
-GCC_CHECK_MATH_FUNC([catanf],[AC_DEFINE([HAVE_CATANF],[1],[catanf is available])])
-GCC_CHECK_MATH_FUNC([catanh],[AC_DEFINE([HAVE_CATANH],[1],[catanh is available])])
-GCC_CHECK_MATH_FUNC([catanhf],[AC_DEFINE([HAVE_CATANHF],[1],[catanhf is available])])
-GCC_CHECK_MATH_FUNC([catanhl],[AC_DEFINE([HAVE_CATANHL],[1],[catanhl is available])])
-GCC_CHECK_MATH_FUNC([catanl],[AC_DEFINE([HAVE_CATANL],[1],[catanl is available])])
+GCC_CHECK_MATH_FUNC([cacos])
+GCC_CHECK_MATH_FUNC([cacosf])
+GCC_CHECK_MATH_FUNC([cacosh])
+GCC_CHECK_MATH_FUNC([cacoshf])
+GCC_CHECK_MATH_FUNC([cacoshl])
+GCC_CHECK_MATH_FUNC([cacosl])
+GCC_CHECK_MATH_FUNC([casin])
+GCC_CHECK_MATH_FUNC([casinf])
+GCC_CHECK_MATH_FUNC([casinh])
+GCC_CHECK_MATH_FUNC([casinhf])
+GCC_CHECK_MATH_FUNC([casinhl])
+GCC_CHECK_MATH_FUNC([casinl])
+GCC_CHECK_MATH_FUNC([catan])
+GCC_CHECK_MATH_FUNC([catanf])
+GCC_CHECK_MATH_FUNC([catanh])
+GCC_CHECK_MATH_FUNC([catanhf])
+GCC_CHECK_MATH_FUNC([catanhl])
+GCC_CHECK_MATH_FUNC([catanl])
# On AIX, clog is present in libm as __clog
AC_CHECK_LIB([m],[__clog],[AC_DEFINE([HAVE_CLOG],[1],[libm includes clog])])
diff --git a/libgfortran/intrinsics/chmod.c b/libgfortran/intrinsics/chmod.c
index 01db8beb9e0..91563033f13 100644
--- a/libgfortran/intrinsics/chmod.c
+++ b/libgfortran/intrinsics/chmod.c
@@ -141,7 +141,6 @@ chmod_func (char *name, char *mode, gfc_charlen_type name_len,
rwxXstugo[6] = false;
rwxXstugo[7] = false;
rwxXstugo[8] = false;
- rwxXstugo[9] = false;
part = 0;
set_mode = -1;
for (; i < mode_len; i++)
diff --git a/libgo/MERGE b/libgo/MERGE
index 17d01ce7265..46a35888aa7 100644
--- a/libgo/MERGE
+++ b/libgo/MERGE
@@ -1,4 +1,4 @@
-f4470a54e6db
+dc5e410f0b4c
The first line of this file holds the Mercurial revision number of the
last merge done from the master library sources.
diff --git a/libgo/Makefile.am b/libgo/Makefile.am
index 99294f12c12..14f72ecdc7d 100644
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -813,6 +813,7 @@ go_net_rpc_files = \
go/net/rpc/server.go
go_runtime_files = \
+ go/runtime/compiler.go \
go/runtime/debug.go \
go/runtime/error.go \
go/runtime/extern.go \
@@ -843,6 +844,7 @@ go_strconv_files = \
go/strconv/decimal.go \
go/strconv/extfloat.go \
go/strconv/ftoa.go \
+ go/strconv/isprint.go \
go/strconv/itoa.go \
go/strconv/quote.go
@@ -1000,12 +1002,13 @@ go_crypto_tls_files = \
go/crypto/tls/handshake_server.go \
go/crypto/tls/key_agreement.go \
go/crypto/tls/prf.go \
- go/crypto/tls/root_unix.go \
go/crypto/tls/tls.go
go_crypto_x509_files = \
go/crypto/x509/cert_pool.go \
go/crypto/x509/pkcs1.go \
go/crypto/x509/pkcs8.go \
+ go/crypto/x509/root.go \
+ go/crypto/x509/root_unix.go \
go/crypto/x509/verify.go \
go/crypto/x509/x509.go
@@ -1320,7 +1323,8 @@ go_os_user_files = \
go_path_filepath_files = \
go/path/filepath/match.go \
go/path/filepath/path.go \
- go/path/filepath/path_unix.go
+ go/path/filepath/path_unix.go \
+ go/path/filepath/symlink.go
go_regexp_syntax_files = \
go/regexp/syntax/compile.go \
diff --git a/libgo/Makefile.in b/libgo/Makefile.in
index b57d92919b5..720d57e04f0 100644
--- a/libgo/Makefile.in
+++ b/libgo/Makefile.in
@@ -1131,6 +1131,7 @@ go_net_rpc_files = \
go/net/rpc/server.go
go_runtime_files = \
+ go/runtime/compiler.go \
go/runtime/debug.go \
go/runtime/error.go \
go/runtime/extern.go \
@@ -1150,6 +1151,7 @@ go_strconv_files = \
go/strconv/decimal.go \
go/strconv/extfloat.go \
go/strconv/ftoa.go \
+ go/strconv/isprint.go \
go/strconv/itoa.go \
go/strconv/quote.go
@@ -1315,13 +1317,14 @@ go_crypto_tls_files = \
go/crypto/tls/handshake_server.go \
go/crypto/tls/key_agreement.go \
go/crypto/tls/prf.go \
- go/crypto/tls/root_unix.go \
go/crypto/tls/tls.go
go_crypto_x509_files = \
go/crypto/x509/cert_pool.go \
go/crypto/x509/pkcs1.go \
go/crypto/x509/pkcs8.go \
+ go/crypto/x509/root.go \
+ go/crypto/x509/root_unix.go \
go/crypto/x509/verify.go \
go/crypto/x509/x509.go
@@ -1677,7 +1680,8 @@ go_os_user_files = \
go_path_filepath_files = \
go/path/filepath/match.go \
go/path/filepath/path.go \
- go/path/filepath/path_unix.go
+ go/path/filepath/path_unix.go \
+ go/path/filepath/symlink.go
go_regexp_syntax_files = \
go/regexp/syntax/compile.go \
diff --git a/libgo/go/archive/tar/reader.go b/libgo/go/archive/tar/reader.go
index 755a730c8b4..1b40af812ae 100644
--- a/libgo/go/archive/tar/reader.go
+++ b/libgo/go/archive/tar/reader.go
@@ -18,7 +18,7 @@ import (
)
var (
- ErrHeader = errors.New("invalid tar header")
+ ErrHeader = errors.New("archive/tar: invalid tar header")
)
// A Reader provides sequential access to the contents of a tar archive.
diff --git a/libgo/go/archive/tar/writer.go b/libgo/go/archive/tar/writer.go
index d35726bf9d8..b2b7a58a10a 100644
--- a/libgo/go/archive/tar/writer.go
+++ b/libgo/go/archive/tar/writer.go
@@ -5,18 +5,19 @@
package tar
// TODO(dsymonds):
-// - catch more errors (no first header, write after close, etc.)
+// - catch more errors (no first header, etc.)
import (
"errors"
+ "fmt"
"io"
"strconv"
)
var (
- ErrWriteTooLong = errors.New("write too long")
- ErrFieldTooLong = errors.New("header field too long")
- ErrWriteAfterClose = errors.New("write after close")
+ ErrWriteTooLong = errors.New("archive/tar: write too long")
+ ErrFieldTooLong = errors.New("archive/tar: header field too long")
+ ErrWriteAfterClose = errors.New("archive/tar: write after close")
)
// A Writer provides sequential writing of a tar archive in POSIX.1 format.
@@ -48,6 +49,11 @@ func NewWriter(w io.Writer) *Writer { return &Writer{w: w} }
// Flush finishes writing the current file (optional).
func (tw *Writer) Flush() error {
+ if tw.nb > 0 {
+ tw.err = fmt.Errorf("archive/tar: missed writing %d bytes", tw.nb)
+ return tw.err
+ }
+
n := tw.nb + tw.pad
for n > 0 && tw.err == nil {
nr := n
@@ -193,6 +199,9 @@ func (tw *Writer) Close() error {
}
tw.Flush()
tw.closed = true
+ if tw.err != nil {
+ return tw.err
+ }
// trailer: two zero blocks
for i := 0; i < 2; i++ {
diff --git a/libgo/go/archive/tar/writer_test.go b/libgo/go/archive/tar/writer_test.go
index 0b413722dd3..a214e57b9fc 100644
--- a/libgo/go/archive/tar/writer_test.go
+++ b/libgo/go/archive/tar/writer_test.go
@@ -9,6 +9,7 @@ import (
"fmt"
"io"
"io/ioutil"
+ "strings"
"testing"
"testing/iotest"
"time"
@@ -95,7 +96,8 @@ var writerTests = []*writerTest{
Uname: "dsymonds",
Gname: "eng",
},
- // no contents
+ // fake contents
+ contents: strings.Repeat("\x00", 4<<10),
},
},
},
@@ -150,7 +152,9 @@ testLoop:
buf := new(bytes.Buffer)
tw := NewWriter(iotest.TruncateWriter(buf, 4<<10)) // only catch the first 4 KB
+ big := false
for j, entry := range test.entries {
+ big = big || entry.header.Size > 1<<10
if err := tw.WriteHeader(entry.header); err != nil {
t.Errorf("test %d, entry %d: Failed writing header: %v", i, j, err)
continue testLoop
@@ -160,7 +164,8 @@ testLoop:
continue testLoop
}
}
- if err := tw.Close(); err != nil {
+ // Only interested in Close failures for the small tests.
+ if err := tw.Close(); err != nil && !big {
t.Errorf("test %d: Failed closing archive: %v", i, err)
continue testLoop
}
diff --git a/libgo/go/archive/zip/reader.go b/libgo/go/archive/zip/reader.go
index f3826dcc48d..ddd507538b3 100644
--- a/libgo/go/archive/zip/reader.go
+++ b/libgo/go/archive/zip/reader.go
@@ -124,10 +124,6 @@ func (f *File) Open() (rc io.ReadCloser, err error) {
return
}
size := int64(f.CompressedSize)
- if size == 0 && f.hasDataDescriptor() {
- // permit SectionReader to see the rest of the file
- size = f.zipsize - (f.headerOffset + bodyOffset)
- }
r := io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset, size)
switch f.Method {
case Store: // (no compression)
@@ -136,10 +132,13 @@ func (f *File) Open() (rc io.ReadCloser, err error) {
rc = flate.NewReader(r)
default:
err = ErrAlgorithm
+ return
}
- if rc != nil {
- rc = &checksumReader{rc, crc32.NewIEEE(), f, r}
+ var desr io.Reader
+ if f.hasDataDescriptor() {
+ desr = io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset+size, dataDescriptorLen)
}
+ rc = &checksumReader{rc, crc32.NewIEEE(), f, desr, nil}
return
}
@@ -147,23 +146,36 @@ type checksumReader struct {
rc io.ReadCloser
hash hash.Hash32
f *File
- zipr io.Reader // for reading the data descriptor
+ desr io.Reader // if non-nil, where to read the data descriptor
+ err error // sticky error
}
func (r *checksumReader) Read(b []byte) (n int, err error) {
+ if r.err != nil {
+ return 0, r.err
+ }
n, err = r.rc.Read(b)
r.hash.Write(b[:n])
- if err != io.EOF {
+ if err == nil {
return
}
- if r.f.hasDataDescriptor() {
- if err = readDataDescriptor(r.zipr, r.f); err != nil {
- return
+ if err == io.EOF {
+ if r.desr != nil {
+ if err1 := readDataDescriptor(r.desr, r.f); err1 != nil {
+ err = err1
+ } else if r.hash.Sum32() != r.f.CRC32 {
+ err = ErrChecksum
+ }
+ } else {
+ // If there's not a data descriptor, we still compare
+ // the CRC32 of what we've read against the file header
+ // or TOC's CRC32, if it seems like it was set.
+ if r.f.CRC32 != 0 && r.hash.Sum32() != r.f.CRC32 {
+ err = ErrChecksum
+ }
}
}
- if r.hash.Sum32() != r.f.CRC32 {
- err = ErrChecksum
- }
+ r.err = err
return
}
@@ -226,10 +238,31 @@ func readDirectoryHeader(f *File, r io.Reader) error {
func readDataDescriptor(r io.Reader, f *File) error {
var buf [dataDescriptorLen]byte
- if _, err := io.ReadFull(r, buf[:]); err != nil {
+
+ // The spec says: "Although not originally assigned a
+ // signature, the value 0x08074b50 has commonly been adopted
+ // as a signature value for the data descriptor record.
+ // Implementers should be aware that ZIP files may be
+ // encountered with or without this signature marking data
+ // descriptors and should account for either case when reading
+ // ZIP files to ensure compatibility."
+ //
+ // dataDescriptorLen includes the size of the signature but
+ // first read just those 4 bytes to see if it exists.
+ if _, err := io.ReadFull(r, buf[:4]); err != nil {
return err
}
- b := readBuf(buf[:])
+ off := 0
+ maybeSig := readBuf(buf[:4])
+ if maybeSig.uint32() != dataDescriptorSignature {
+ // No data descriptor signature. Keep these four
+ // bytes.
+ off += 4
+ }
+ if _, err := io.ReadFull(r, buf[off:12]); err != nil {
+ return err
+ }
+ b := readBuf(buf[:12])
f.CRC32 = b.uint32()
f.CompressedSize = b.uint32()
f.UncompressedSize = b.uint32()
diff --git a/libgo/go/archive/zip/reader_test.go b/libgo/go/archive/zip/reader_test.go
index 066a61580c5..5f1d1b28a98 100644
--- a/libgo/go/archive/zip/reader_test.go
+++ b/libgo/go/archive/zip/reader_test.go
@@ -7,26 +7,31 @@ package zip
import (
"bytes"
"encoding/binary"
+ "encoding/hex"
"io"
"io/ioutil"
"os"
+ "path/filepath"
+ "regexp"
"testing"
"time"
)
type ZipTest struct {
Name string
+ Source func() (r io.ReaderAt, size int64) // if non-nil, used instead of testdata/<Name> file
Comment string
File []ZipTestFile
Error error // the error that Opening this file should return
}
type ZipTestFile struct {
- Name string
- Content []byte // if blank, will attempt to compare against File
- File string // name of file to compare to (relative to testdata/)
- Mtime string // modified time in format "mm-dd-yy hh:mm:ss"
- Mode os.FileMode
+ Name string
+ Content []byte // if blank, will attempt to compare against File
+ ContentErr error
+ File string // name of file to compare to (relative to testdata/)
+ Mtime string // modified time in format "mm-dd-yy hh:mm:ss"
+ Mode os.FileMode
}
// Caution: The Mtime values found for the test files should correspond to
@@ -59,13 +64,14 @@ var tests = []ZipTest{
},
},
{
- Name: "r.zip",
+ Name: "r.zip",
+ Source: returnRecursiveZip,
File: []ZipTestFile{
{
- Name: "r/r.zip",
- File: "r.zip",
- Mtime: "03-04-10 00:24:16",
- Mode: 0666,
+ Name: "r/r.zip",
+ Content: rZipBytes(),
+ Mtime: "03-04-10 00:24:16",
+ Mode: 0666,
},
},
},
@@ -107,6 +113,99 @@ var tests = []ZipTest{
Name: "unix.zip",
File: crossPlatform,
},
+ {
+ // created by Go, before we wrote the "optional" data
+ // descriptor signatures (which are required by OS X)
+ Name: "go-no-datadesc-sig.zip",
+ File: []ZipTestFile{
+ {
+ Name: "foo.txt",
+ Content: []byte("foo\n"),
+ Mtime: "03-08-12 16:59:10",
+ Mode: 0644,
+ },
+ {
+ Name: "bar.txt",
+ Content: []byte("bar\n"),
+ Mtime: "03-08-12 16:59:12",
+ Mode: 0644,
+ },
+ },
+ },
+ {
+ // created by Go, after we wrote the "optional" data
+ // descriptor signatures (which are required by OS X)
+ Name: "go-with-datadesc-sig.zip",
+ File: []ZipTestFile{
+ {
+ Name: "foo.txt",
+ Content: []byte("foo\n"),
+ Mode: 0666,
+ },
+ {
+ Name: "bar.txt",
+ Content: []byte("bar\n"),
+ Mode: 0666,
+ },
+ },
+ },
+ {
+ Name: "Bad-CRC32-in-data-descriptor",
+ Source: returnCorruptCRC32Zip,
+ File: []ZipTestFile{
+ {
+ Name: "foo.txt",
+ Content: []byte("foo\n"),
+ Mode: 0666,
+ ContentErr: ErrChecksum,
+ },
+ {
+ Name: "bar.txt",
+ Content: []byte("bar\n"),
+ Mode: 0666,
+ },
+ },
+ },
+ // Tests that we verify (and accept valid) crc32s on files
+ // with crc32s in their file header (not in data descriptors)
+ {
+ Name: "crc32-not-streamed.zip",
+ File: []ZipTestFile{
+ {
+ Name: "foo.txt",
+ Content: []byte("foo\n"),
+ Mtime: "03-08-12 16:59:10",
+ Mode: 0644,
+ },
+ {
+ Name: "bar.txt",
+ Content: []byte("bar\n"),
+ Mtime: "03-08-12 16:59:12",
+ Mode: 0644,
+ },
+ },
+ },
+ // Tests that we verify (and reject invalid) crc32s on files
+ // with crc32s in their file header (not in data descriptors)
+ {
+ Name: "crc32-not-streamed.zip",
+ Source: returnCorruptNotStreamedZip,
+ File: []ZipTestFile{
+ {
+ Name: "foo.txt",
+ Content: []byte("foo\n"),
+ Mtime: "03-08-12 16:59:10",
+ Mode: 0644,
+ ContentErr: ErrChecksum,
+ },
+ {
+ Name: "bar.txt",
+ Content: []byte("bar\n"),
+ Mtime: "03-08-12 16:59:12",
+ Mode: 0644,
+ },
+ },
+ },
}
var crossPlatform = []ZipTestFile{
@@ -139,7 +238,18 @@ func TestReader(t *testing.T) {
}
func readTestZip(t *testing.T, zt ZipTest) {
- z, err := OpenReader("testdata/" + zt.Name)
+ var z *Reader
+ var err error
+ if zt.Source != nil {
+ rat, size := zt.Source()
+ z, err = NewReader(rat, size)
+ } else {
+ var rc *ReadCloser
+ rc, err = OpenReader(filepath.Join("testdata", zt.Name))
+ if err == nil {
+ z = &rc.Reader
+ }
+ }
if err != zt.Error {
t.Errorf("error=%v, want %v", err, zt.Error)
return
@@ -149,11 +259,6 @@ func readTestZip(t *testing.T, zt ZipTest) {
if err == ErrFormat {
return
}
- defer func() {
- if err := z.Close(); err != nil {
- t.Errorf("error %q when closing zip file", err)
- }
- }()
// bail here if no Files expected to be tested
// (there may actually be files in the zip, but we don't care)
@@ -170,7 +275,7 @@ func readTestZip(t *testing.T, zt ZipTest) {
// test read of each file
for i, ft := range zt.File {
- readTestFile(t, ft, z.File[i])
+ readTestFile(t, zt, ft, z.File[i])
}
// test simultaneous reads
@@ -179,7 +284,7 @@ func readTestZip(t *testing.T, zt ZipTest) {
for i := 0; i < 5; i++ {
for j, ft := range zt.File {
go func(j int, ft ZipTestFile) {
- readTestFile(t, ft, z.File[j])
+ readTestFile(t, zt, ft, z.File[j])
done <- true
}(j, ft)
n++
@@ -188,26 +293,11 @@ func readTestZip(t *testing.T, zt ZipTest) {
for ; n > 0; n-- {
<-done
}
-
- // test invalid checksum
- if !z.File[0].hasDataDescriptor() { // skip test when crc32 in dd
- z.File[0].CRC32++ // invalidate
- r, err := z.File[0].Open()
- if err != nil {
- t.Error(err)
- return
- }
- var b bytes.Buffer
- _, err = io.Copy(&b, r)
- if err != ErrChecksum {
- t.Errorf("%s: copy error=%v, want %v", z.File[0].Name, err, ErrChecksum)
- }
- }
}
-func readTestFile(t *testing.T, ft ZipTestFile, f *File) {
+func readTestFile(t *testing.T, zt ZipTest, ft ZipTestFile, f *File) {
if f.Name != ft.Name {
- t.Errorf("name=%q, want %q", f.Name, ft.Name)
+ t.Errorf("%s: name=%q, want %q", zt.Name, f.Name, ft.Name)
}
if ft.Mtime != "" {
@@ -217,11 +307,11 @@ func readTestFile(t *testing.T, ft ZipTestFile, f *File) {
return
}
if ft := f.ModTime(); !ft.Equal(mtime) {
- t.Errorf("%s: mtime=%s, want %s", f.Name, ft, mtime)
+ t.Errorf("%s: %s: mtime=%s, want %s", zt.Name, f.Name, ft, mtime)
}
}
- testFileMode(t, f, ft.Mode)
+ testFileMode(t, zt.Name, f, ft.Mode)
size0 := f.UncompressedSize
@@ -237,8 +327,10 @@ func readTestFile(t *testing.T, ft ZipTestFile, f *File) {
}
_, err = io.Copy(&b, r)
+ if err != ft.ContentErr {
+ t.Errorf("%s: copying contents: %v (want %v)", zt.Name, err, ft.ContentErr)
+ }
if err != nil {
- t.Error(err)
return
}
r.Close()
@@ -264,12 +356,12 @@ func readTestFile(t *testing.T, ft ZipTestFile, f *File) {
}
}
-func testFileMode(t *testing.T, f *File, want os.FileMode) {
+func testFileMode(t *testing.T, zipName string, f *File, want os.FileMode) {
mode := f.Mode()
if want == 0 {
- t.Errorf("%s mode: got %v, want none", f.Name, mode)
+ t.Errorf("%s: %s mode: got %v, want none", zipName, f.Name, mode)
} else if mode != want {
- t.Errorf("%s mode: want %v, got %v", f.Name, want, mode)
+ t.Errorf("%s: %s mode: want %v, got %v", zipName, f.Name, want, mode)
}
}
@@ -294,3 +386,81 @@ func TestInvalidFiles(t *testing.T) {
t.Errorf("sigs: error=%v, want %v", err, ErrFormat)
}
}
+
+func messWith(fileName string, corrupter func(b []byte)) (r io.ReaderAt, size int64) {
+ data, err := ioutil.ReadFile(filepath.Join("testdata", fileName))
+ if err != nil {
+ panic("Error reading " + fileName + ": " + err.Error())
+ }
+ corrupter(data)
+ return bytes.NewReader(data), int64(len(data))
+}
+
+func returnCorruptCRC32Zip() (r io.ReaderAt, size int64) {
+ return messWith("go-with-datadesc-sig.zip", func(b []byte) {
+ // Corrupt one of the CRC32s in the data descriptor:
+ b[0x2d]++
+ })
+}
+
+func returnCorruptNotStreamedZip() (r io.ReaderAt, size int64) {
+ return messWith("crc32-not-streamed.zip", func(b []byte) {
+ // Corrupt foo.txt's final crc32 byte, in both
+ // the file header and TOC. (0x7e -> 0x7f)
+ b[0x11]++
+ b[0x9d]++
+
+ // TODO(bradfitz): add a new test that only corrupts
+ // one of these values, and verify that that's also an
+ // error. Currently, the reader code doesn't verify the
+ // fileheader and TOC's crc32 match if they're both
+ // non-zero and only the second line above, the TOC,
+ // is what matters.
+ })
+}
+
+// rZipBytes returns the bytes of a recursive zip file, without
+// putting it on disk and triggering certain virus scanners.
+func rZipBytes() []byte {
+ s := `
+0000000 50 4b 03 04 14 00 00 00 08 00 08 03 64 3c f9 f4
+0000010 89 64 48 01 00 00 b8 01 00 00 07 00 00 00 72 2f
+0000020 72 2e 7a 69 70 00 25 00 da ff 50 4b 03 04 14 00
+0000030 00 00 08 00 08 03 64 3c f9 f4 89 64 48 01 00 00
+0000040 b8 01 00 00 07 00 00 00 72 2f 72 2e 7a 69 70 00
+0000050 2f 00 d0 ff 00 25 00 da ff 50 4b 03 04 14 00 00
+0000060 00 08 00 08 03 64 3c f9 f4 89 64 48 01 00 00 b8
+0000070 01 00 00 07 00 00 00 72 2f 72 2e 7a 69 70 00 2f
+0000080 00 d0 ff c2 54 8e 57 39 00 05 00 fa ff c2 54 8e
+0000090 57 39 00 05 00 fa ff 00 05 00 fa ff 00 14 00 eb
+00000a0 ff c2 54 8e 57 39 00 05 00 fa ff 00 05 00 fa ff
+00000b0 00 14 00 eb ff 42 88 21 c4 00 00 14 00 eb ff 42
+00000c0 88 21 c4 00 00 14 00 eb ff 42 88 21 c4 00 00 14
+00000d0 00 eb ff 42 88 21 c4 00 00 14 00 eb ff 42 88 21
+00000e0 c4 00 00 00 00 ff ff 00 00 00 ff ff 00 34 00 cb
+00000f0 ff 42 88 21 c4 00 00 00 00 ff ff 00 00 00 ff ff
+0000100 00 34 00 cb ff 42 e8 21 5e 0f 00 00 00 ff ff 0a
+0000110 f0 66 64 12 61 c0 15 dc e8 a0 48 bf 48 af 2a b3
+0000120 20 c0 9b 95 0d c4 67 04 42 53 06 06 06 40 00 06
+0000130 00 f9 ff 6d 01 00 00 00 00 42 e8 21 5e 0f 00 00
+0000140 00 ff ff 0a f0 66 64 12 61 c0 15 dc e8 a0 48 bf
+0000150 48 af 2a b3 20 c0 9b 95 0d c4 67 04 42 53 06 06
+0000160 06 40 00 06 00 f9 ff 6d 01 00 00 00 00 50 4b 01
+0000170 02 14 00 14 00 00 00 08 00 08 03 64 3c f9 f4 89
+0000180 64 48 01 00 00 b8 01 00 00 07 00 00 00 00 00 00
+0000190 00 00 00 00 00 00 00 00 00 00 00 72 2f 72 2e 7a
+00001a0 69 70 50 4b 05 06 00 00 00 00 01 00 01 00 35 00
+00001b0 00 00 6d 01 00 00 00 00`
+ s = regexp.MustCompile(`[0-9a-f]{7}`).ReplaceAllString(s, "")
+ s = regexp.MustCompile(`\s+`).ReplaceAllString(s, "")
+ b, err := hex.DecodeString(s)
+ if err != nil {
+ panic(err)
+ }
+ return b
+}
+
+func returnRecursiveZip() (r io.ReaderAt, size int64) {
+ b := rZipBytes()
+ return bytes.NewReader(b), int64(len(b))
+}
diff --git a/libgo/go/archive/zip/struct.go b/libgo/go/archive/zip/struct.go
index fdbd16da048..55f3dcfb82e 100644
--- a/libgo/go/archive/zip/struct.go
+++ b/libgo/go/archive/zip/struct.go
@@ -27,10 +27,11 @@ const (
fileHeaderSignature = 0x04034b50
directoryHeaderSignature = 0x02014b50
directoryEndSignature = 0x06054b50
- fileHeaderLen = 30 // + filename + extra
- directoryHeaderLen = 46 // + filename + extra + comment
- directoryEndLen = 22 // + comment
- dataDescriptorLen = 12
+ dataDescriptorSignature = 0x08074b50 // de-facto standard; required by OS X Finder
+ fileHeaderLen = 30 // + filename + extra
+ directoryHeaderLen = 46 // + filename + extra + comment
+ directoryEndLen = 22 // + comment
+ dataDescriptorLen = 16 // four uint32: descriptor signature, crc32, compressed size, size
// Constants for the first byte in CreatorVersion
creatorFAT = 0
diff --git a/libgo/go/archive/zip/testdata/crc32-not-streamed.zip b/libgo/go/archive/zip/testdata/crc32-not-streamed.zip
new file mode 100644
index 00000000000..f268d88732f
--- /dev/null
+++ b/libgo/go/archive/zip/testdata/crc32-not-streamed.zip
Binary files differ
diff --git a/libgo/go/archive/zip/testdata/go-no-datadesc-sig.zip b/libgo/go/archive/zip/testdata/go-no-datadesc-sig.zip
new file mode 100644
index 00000000000..c3d593f44f9
--- /dev/null
+++ b/libgo/go/archive/zip/testdata/go-no-datadesc-sig.zip
Binary files differ
diff --git a/libgo/go/archive/zip/testdata/go-with-datadesc-sig.zip b/libgo/go/archive/zip/testdata/go-with-datadesc-sig.zip
new file mode 100644
index 00000000000..bcfe121bb63
--- /dev/null
+++ b/libgo/go/archive/zip/testdata/go-with-datadesc-sig.zip
Binary files differ
diff --git a/libgo/go/archive/zip/testdata/r.zip b/libgo/go/archive/zip/testdata/r.zip
deleted file mode 100644
index ea0fa2ffccc..00000000000
--- a/libgo/go/archive/zip/testdata/r.zip
+++ /dev/null
Binary files differ
diff --git a/libgo/go/archive/zip/writer.go b/libgo/go/archive/zip/writer.go
index b2cc55bc93b..45eb6bd730d 100644
--- a/libgo/go/archive/zip/writer.go
+++ b/libgo/go/archive/zip/writer.go
@@ -224,6 +224,7 @@ func (w *fileWriter) close() error {
// write data descriptor
var buf [dataDescriptorLen]byte
b := writeBuf(buf[:])
+ b.uint32(dataDescriptorSignature) // de-facto standard, required by OS X
b.uint32(fh.CRC32)
b.uint32(fh.CompressedSize)
b.uint32(fh.UncompressedSize)
diff --git a/libgo/go/archive/zip/writer_test.go b/libgo/go/archive/zip/writer_test.go
index 88e5211ff7b..8b1c4dfd265 100644
--- a/libgo/go/archive/zip/writer_test.go
+++ b/libgo/go/archive/zip/writer_test.go
@@ -108,7 +108,7 @@ func testReadFile(t *testing.T, f *File, wt *WriteTest) {
if f.Name != wt.Name {
t.Fatalf("File name: got %q, want %q", f.Name, wt.Name)
}
- testFileMode(t, f, wt.Mode)
+ testFileMode(t, wt.Name, f, wt.Mode)
rc, err := f.Open()
if err != nil {
t.Fatal("opening:", err)
diff --git a/libgo/go/crypto/tls/common.go b/libgo/go/crypto/tls/common.go
index 25f7a920cd3..4ba0bf87481 100644
--- a/libgo/go/crypto/tls/common.go
+++ b/libgo/go/crypto/tls/common.go
@@ -198,14 +198,6 @@ func (c *Config) time() time.Time {
return t()
}
-func (c *Config) rootCAs() *x509.CertPool {
- s := c.RootCAs
- if s == nil {
- s = defaultRoots()
- }
- return s
-}
-
func (c *Config) cipherSuites() []uint16 {
s := c.CipherSuites
if s == nil {
@@ -311,28 +303,16 @@ func defaultConfig() *Config {
return &emptyConfig
}
-var once sync.Once
-
-func defaultRoots() *x509.CertPool {
- once.Do(initDefaults)
- return varDefaultRoots
-}
+var (
+ once sync.Once
+ varDefaultCipherSuites []uint16
+)
func defaultCipherSuites() []uint16 {
- once.Do(initDefaults)
+ once.Do(initDefaultCipherSuites)
return varDefaultCipherSuites
}
-func initDefaults() {
- initDefaultRoots()
- initDefaultCipherSuites()
-}
-
-var (
- varDefaultRoots *x509.CertPool
- varDefaultCipherSuites []uint16
-)
-
func initDefaultCipherSuites() {
varDefaultCipherSuites = make([]uint16, len(cipherSuites))
for i, suite := range cipherSuites {
diff --git a/libgo/go/crypto/tls/handshake_client.go b/libgo/go/crypto/tls/handshake_client.go
index 0d7b806ff5b..2877f17387d 100644
--- a/libgo/go/crypto/tls/handshake_client.go
+++ b/libgo/go/crypto/tls/handshake_client.go
@@ -102,7 +102,7 @@ func (c *Conn) clientHandshake() error {
if !c.config.InsecureSkipVerify {
opts := x509.VerifyOptions{
- Roots: c.config.rootCAs(),
+ Roots: c.config.RootCAs,
CurrentTime: c.config.time(),
DNSName: c.config.ServerName,
Intermediates: x509.NewCertPool(),
@@ -166,8 +166,11 @@ func (c *Conn) clientHandshake() error {
}
var certToSend *Certificate
+ var certRequested bool
certReq, ok := msg.(*certificateRequestMsg)
if ok {
+ certRequested = true
+
// RFC 4346 on the certificateAuthorities field:
// A list of the distinguished names of acceptable certificate
// authorities. These distinguished names may specify a desired
@@ -238,9 +241,14 @@ func (c *Conn) clientHandshake() error {
}
finishedHash.Write(shd.marshal())
- if certToSend != nil {
+ // If the server requested a certificate then we have to send a
+ // Certificate message, even if it's empty because we don't have a
+ // certificate to send.
+ if certRequested {
certMsg = new(certificateMsg)
- certMsg.certificates = certToSend.Certificate
+ if certToSend != nil {
+ certMsg.certificates = certToSend.Certificate
+ }
finishedHash.Write(certMsg.marshal())
c.writeRecord(recordTypeHandshake, certMsg.marshal())
}
diff --git a/libgo/go/crypto/tls/handshake_server.go b/libgo/go/crypto/tls/handshake_server.go
index 23ec5587235..77e56a75456 100644
--- a/libgo/go/crypto/tls/handshake_server.go
+++ b/libgo/go/crypto/tls/handshake_server.go
@@ -60,21 +60,23 @@ FindCipherSuite:
for _, id := range clientHello.cipherSuites {
for _, supported := range config.cipherSuites() {
if id == supported {
- suite = nil
+ var candidate *cipherSuite
+
for _, s := range cipherSuites {
if s.id == id {
- suite = s
+ candidate = s
break
}
}
- if suite == nil {
+ if candidate == nil {
continue
}
// Don't select a ciphersuite which we can't
// support for this client.
- if suite.elliptic && !ellipticOk {
+ if candidate.elliptic && !ellipticOk {
continue
}
+ suite = candidate
break FindCipherSuite
}
}
diff --git a/libgo/go/crypto/tls/handshake_server_test.go b/libgo/go/crypto/tls/handshake_server_test.go
index bd31d31ae1a..08a0ccb0980 100644
--- a/libgo/go/crypto/tls/handshake_server_test.go
+++ b/libgo/go/crypto/tls/handshake_server_test.go
@@ -143,7 +143,7 @@ func testServerScript(t *testing.T, name string, serverScript [][]byte, config *
if peers != nil {
gotpeers := <-pchan
if len(peers) == len(gotpeers) {
- for i, _ := range peers {
+ for i := range peers {
if !peers[i].Equal(gotpeers[i]) {
t.Fatalf("%s: mismatch on peer cert %d", name, i)
}
diff --git a/libgo/go/crypto/tls/key_agreement.go b/libgo/go/crypto/tls/key_agreement.go
index 75f5c73464a..a931d8fb555 100644
--- a/libgo/go/crypto/tls/key_agreement.go
+++ b/libgo/go/crypto/tls/key_agreement.go
@@ -130,6 +130,10 @@ Curve:
}
}
+ if curveid == 0 {
+ return nil, errors.New("tls: no supported elliptic curves offered")
+ }
+
var x, y *big.Int
var err error
ka.privateKey, x, y, err = elliptic.GenerateKey(ka.curve, config.rand())
diff --git a/libgo/go/crypto/tls/root_test.go b/libgo/go/crypto/tls/root_test.go
index 95a89d843c8..e61c2185126 100644
--- a/libgo/go/crypto/tls/root_test.go
+++ b/libgo/go/crypto/tls/root_test.go
@@ -5,25 +5,25 @@
package tls
import (
+ "crypto/x509"
+ "runtime"
"testing"
)
var tlsServers = []string{
- "google.com:443",
- "github.com:443",
- "twitter.com:443",
+ "google.com",
+ "github.com",
+ "twitter.com",
}
func TestOSCertBundles(t *testing.T) {
- defaultRoots()
-
if testing.Short() {
t.Logf("skipping certificate tests in short mode")
return
}
for _, addr := range tlsServers {
- conn, err := Dial("tcp", addr, nil)
+ conn, err := Dial("tcp", addr+":443", &Config{ServerName: addr})
if err != nil {
t.Errorf("unable to verify %v: %v", addr, err)
continue
@@ -34,3 +34,28 @@ func TestOSCertBundles(t *testing.T) {
}
}
}
+
+func TestCertHostnameVerifyWindows(t *testing.T) {
+ if runtime.GOOS != "windows" {
+ return
+ }
+
+ if testing.Short() {
+ t.Logf("skipping certificate tests in short mode")
+ return
+ }
+
+ for _, addr := range tlsServers {
+ cfg := &Config{ServerName: "example.com"}
+ conn, err := Dial("tcp", addr+":443", cfg)
+ if err == nil {
+ conn.Close()
+ t.Errorf("should fail to verify for example.com: %v", addr)
+ continue
+ }
+ _, ok := err.(x509.HostnameError)
+ if !ok {
+ t.Errorf("error type mismatch, got: %v", err)
+ }
+ }
+}
diff --git a/libgo/go/crypto/tls/root_windows.go b/libgo/go/crypto/tls/root_windows.go
deleted file mode 100644
index 319309ae6e7..00000000000
--- a/libgo/go/crypto/tls/root_windows.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tls
-
-import (
- "crypto/x509"
- "syscall"
- "unsafe"
-)
-
-func loadStore(roots *x509.CertPool, name string) {
- store, err := syscall.CertOpenSystemStore(syscall.InvalidHandle, syscall.StringToUTF16Ptr(name))
- if err != nil {
- return
- }
- defer syscall.CertCloseStore(store, 0)
-
- var cert *syscall.CertContext
- for {
- cert, err = syscall.CertEnumCertificatesInStore(store, cert)
- if err != nil {
- return
- }
-
- buf := (*[1 << 20]byte)(unsafe.Pointer(cert.EncodedCert))[:]
- // ParseCertificate requires its own copy of certificate data to keep.
- buf2 := make([]byte, cert.Length)
- copy(buf2, buf)
- if c, err := x509.ParseCertificate(buf2); err == nil {
- roots.AddCert(c)
- }
- }
-}
-
-func initDefaultRoots() {
- roots := x509.NewCertPool()
-
- // Roots
- loadStore(roots, "ROOT")
-
- // Intermediates
- loadStore(roots, "CA")
-
- varDefaultRoots = roots
-}
diff --git a/libgo/go/crypto/tls/tls.go b/libgo/go/crypto/tls/tls.go
index 9184e8e8118..09df5ad445c 100644
--- a/libgo/go/crypto/tls/tls.go
+++ b/libgo/go/crypto/tls/tls.go
@@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Package tls partially implements the TLS 1.1 protocol, as specified in RFC
-// 4346.
+// Package tls partially implements TLS 1.0, as specified in RFC 2246.
package tls
import (
@@ -98,7 +97,9 @@ func Dial(network, addr string, config *Config) (*Conn, error) {
if config == nil {
config = defaultConfig()
}
- if config.ServerName != "" {
+ // If no ServerName is set, infer the ServerName
+ // from the hostname we're connecting to.
+ if config.ServerName == "" {
// Make a copy to avoid polluting argument or default.
c := *config
c.ServerName = hostname
diff --git a/libgo/go/crypto/x509/pkcs1.go b/libgo/go/crypto/x509/pkcs1.go
index 3aaa8c5832a..873d3966eb5 100644
--- a/libgo/go/crypto/x509/pkcs1.go
+++ b/libgo/go/crypto/x509/pkcs1.go
@@ -24,7 +24,7 @@ type pkcs1PrivateKey struct {
Dq *big.Int `asn1:"optional"`
Qinv *big.Int `asn1:"optional"`
- AdditionalPrimes []pkcs1AdditionalRSAPrime `asn1:"optional"`
+ AdditionalPrimes []pkcs1AdditionalRSAPrime `asn1:"optional,omitempty"`
}
type pkcs1AdditionalRSAPrime struct {
diff --git a/libgo/go/crypto/x509/root.go b/libgo/go/crypto/x509/root.go
new file mode 100644
index 00000000000..8aae14e09ee
--- /dev/null
+++ b/libgo/go/crypto/x509/root.go
@@ -0,0 +1,17 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package x509
+
+import "sync"
+
+var (
+ once sync.Once
+ systemRoots *CertPool
+)
+
+func systemRootsPool() *CertPool {
+ once.Do(initSystemRoots)
+ return systemRoots
+}
diff --git a/libgo/go/crypto/tls/root_darwin.go b/libgo/go/crypto/x509/root_darwin.go
index 911a9a62e3c..0f99581e8a7 100644
--- a/libgo/go/crypto/tls/root_darwin.go
+++ b/libgo/go/crypto/x509/root_darwin.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package tls
+package x509
/*
#cgo CFLAGS: -mmacosx-version-min=10.6 -D__MAC_OS_X_VERSION_MAX_ALLOWED=1060
@@ -59,13 +59,14 @@ int FetchPEMRoots(CFDataRef *pemRoots) {
}
*/
import "C"
-import (
- "crypto/x509"
- "unsafe"
-)
+import "unsafe"
-func initDefaultRoots() {
- roots := x509.NewCertPool()
+func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
+ return nil, nil
+}
+
+func initSystemRoots() {
+ roots := NewCertPool()
var data C.CFDataRef = nil
err := C.FetchPEMRoots(&data)
@@ -75,5 +76,5 @@ func initDefaultRoots() {
roots.AppendCertsFromPEM(buf)
}
- varDefaultRoots = roots
+ systemRoots = roots
}
diff --git a/libgo/go/crypto/tls/root_stub.go b/libgo/go/crypto/x509/root_stub.go
index ee2c3e01795..568004108b5 100644
--- a/libgo/go/crypto/tls/root_stub.go
+++ b/libgo/go/crypto/x509/root_stub.go
@@ -4,7 +4,12 @@
// +build plan9 darwin,!cgo
-package tls
+package x509
-func initDefaultRoots() {
+func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
+ return nil, nil
+}
+
+func initSystemRoots() {
+ systemRoots = NewCertPool()
}
diff --git a/libgo/go/crypto/tls/root_unix.go b/libgo/go/crypto/x509/root_unix.go
index acaf3dd9d67..76e79f494f7 100644
--- a/libgo/go/crypto/tls/root_unix.go
+++ b/libgo/go/crypto/x509/root_unix.go
@@ -4,12 +4,9 @@
// +build freebsd linux openbsd netbsd
-package tls
+package x509
-import (
- "crypto/x509"
- "io/ioutil"
-)
+import "io/ioutil"
// Possible certificate files; stop after finding one.
var certFiles = []string{
@@ -20,8 +17,12 @@ var certFiles = []string{
"/usr/local/share/certs/ca-root-nss.crt", // FreeBSD
}
-func initDefaultRoots() {
- roots := x509.NewCertPool()
+func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
+ return nil, nil
+}
+
+func initSystemRoots() {
+ roots := NewCertPool()
for _, file := range certFiles {
data, err := ioutil.ReadFile(file)
if err == nil {
@@ -29,5 +30,6 @@ func initDefaultRoots() {
break
}
}
- varDefaultRoots = roots
+
+ systemRoots = roots
}
diff --git a/libgo/go/crypto/x509/root_windows.go b/libgo/go/crypto/x509/root_windows.go
new file mode 100644
index 00000000000..7e8f2af4b0e
--- /dev/null
+++ b/libgo/go/crypto/x509/root_windows.go
@@ -0,0 +1,226 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package x509
+
+import (
+ "errors"
+ "syscall"
+ "unsafe"
+)
+
+// Creates a new *syscall.CertContext representing the leaf certificate in an in-memory
+// certificate store containing itself and all of the intermediate certificates specified
+// in the opts.Intermediates CertPool.
+//
+// A pointer to the in-memory store is available in the returned CertContext's Store field.
+// The store is automatically freed when the CertContext is freed using
+// syscall.CertFreeCertificateContext.
+func createStoreContext(leaf *Certificate, opts *VerifyOptions) (*syscall.CertContext, error) {
+ var storeCtx *syscall.CertContext
+
+ leafCtx, err := syscall.CertCreateCertificateContext(syscall.X509_ASN_ENCODING|syscall.PKCS_7_ASN_ENCODING, &leaf.Raw[0], uint32(len(leaf.Raw)))
+ if err != nil {
+ return nil, err
+ }
+ defer syscall.CertFreeCertificateContext(leafCtx)
+
+ handle, err := syscall.CertOpenStore(syscall.CERT_STORE_PROV_MEMORY, 0, 0, syscall.CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, 0)
+ if err != nil {
+ return nil, err
+ }
+ defer syscall.CertCloseStore(handle, 0)
+
+ err = syscall.CertAddCertificateContextToStore(handle, leafCtx, syscall.CERT_STORE_ADD_ALWAYS, &storeCtx)
+ if err != nil {
+ return nil, err
+ }
+
+ if opts.Intermediates != nil {
+ for _, intermediate := range opts.Intermediates.certs {
+ ctx, err := syscall.CertCreateCertificateContext(syscall.X509_ASN_ENCODING|syscall.PKCS_7_ASN_ENCODING, &intermediate.Raw[0], uint32(len(intermediate.Raw)))
+ if err != nil {
+ return nil, err
+ }
+
+ err = syscall.CertAddCertificateContextToStore(handle, ctx, syscall.CERT_STORE_ADD_ALWAYS, nil)
+ syscall.CertFreeCertificateContext(ctx)
+ if err != nil {
+ return nil, err
+ }
+ }
+ }
+
+ return storeCtx, nil
+}
+
+// extractSimpleChain extracts the final certificate chain from a CertSimpleChain.
+func extractSimpleChain(simpleChain **syscall.CertSimpleChain, count int) (chain []*Certificate, err error) {
+ if simpleChain == nil || count == 0 {
+ return nil, errors.New("x509: invalid simple chain")
+ }
+
+ simpleChains := (*[1 << 20]*syscall.CertSimpleChain)(unsafe.Pointer(simpleChain))[:]
+ lastChain := simpleChains[count-1]
+ elements := (*[1 << 20]*syscall.CertChainElement)(unsafe.Pointer(lastChain.Elements))[:]
+ for i := 0; i < int(lastChain.NumElements); i++ {
+ // Copy the buf, since ParseCertificate does not create its own copy.
+ cert := elements[i].CertContext
+ encodedCert := (*[1 << 20]byte)(unsafe.Pointer(cert.EncodedCert))[:]
+ buf := make([]byte, cert.Length)
+ copy(buf, encodedCert[:])
+ parsedCert, err := ParseCertificate(buf)
+ if err != nil {
+ return nil, err
+ }
+ chain = append(chain, parsedCert)
+ }
+
+ return chain, nil
+}
+
+// checkChainTrustStatus checks the trust status of the certificate chain, translating
+// any errors it finds into Go errors in the process.
+func checkChainTrustStatus(c *Certificate, chainCtx *syscall.CertChainContext) error {
+ if chainCtx.TrustStatus.ErrorStatus != syscall.CERT_TRUST_NO_ERROR {
+ status := chainCtx.TrustStatus.ErrorStatus
+ switch status {
+ case syscall.CERT_TRUST_IS_NOT_TIME_VALID:
+ return CertificateInvalidError{c, Expired}
+ default:
+ return UnknownAuthorityError{c}
+ }
+ }
+ return nil
+}
+
+// checkChainSSLServerPolicy checks that the certificate chain in chainCtx is valid for
+// use as a certificate chain for a SSL/TLS server.
+func checkChainSSLServerPolicy(c *Certificate, chainCtx *syscall.CertChainContext, opts *VerifyOptions) error {
+ sslPara := &syscall.SSLExtraCertChainPolicyPara{
+ AuthType: syscall.AUTHTYPE_SERVER,
+ ServerName: syscall.StringToUTF16Ptr(opts.DNSName),
+ }
+ sslPara.Size = uint32(unsafe.Sizeof(*sslPara))
+
+ para := &syscall.CertChainPolicyPara{
+ ExtraPolicyPara: uintptr(unsafe.Pointer(sslPara)),
+ }
+ para.Size = uint32(unsafe.Sizeof(*para))
+
+ status := syscall.CertChainPolicyStatus{}
+ err := syscall.CertVerifyCertificateChainPolicy(syscall.CERT_CHAIN_POLICY_SSL, chainCtx, para, &status)
+ if err != nil {
+ return err
+ }
+
+ // TODO(mkrautz): use the lChainIndex and lElementIndex fields
+ // of the CertChainPolicyStatus to provide proper context, instead
+ // using c.
+ if status.Error != 0 {
+ switch status.Error {
+ case syscall.CERT_E_EXPIRED:
+ return CertificateInvalidError{c, Expired}
+ case syscall.CERT_E_CN_NO_MATCH:
+ return HostnameError{c, opts.DNSName}
+ case syscall.CERT_E_UNTRUSTEDROOT:
+ return UnknownAuthorityError{c}
+ default:
+ return UnknownAuthorityError{c}
+ }
+ }
+
+ return nil
+}
+
+// systemVerify is like Verify, except that it uses CryptoAPI calls
+// to build certificate chains and verify them.
+func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
+ hasDNSName := opts != nil && len(opts.DNSName) > 0
+
+ storeCtx, err := createStoreContext(c, opts)
+ if err != nil {
+ return nil, err
+ }
+ defer syscall.CertFreeCertificateContext(storeCtx)
+
+ para := new(syscall.CertChainPara)
+ para.Size = uint32(unsafe.Sizeof(*para))
+
+ // If there's a DNSName set in opts, assume we're verifying
+ // a certificate from a TLS server.
+ if hasDNSName {
+ oids := []*byte{
+ &syscall.OID_PKIX_KP_SERVER_AUTH[0],
+ // Both IE and Chrome allow certificates with
+ // Server Gated Crypto as well. Some certificates
+ // in the wild require them.
+ &syscall.OID_SERVER_GATED_CRYPTO[0],
+ &syscall.OID_SGC_NETSCAPE[0],
+ }
+ para.RequestedUsage.Type = syscall.USAGE_MATCH_TYPE_OR
+ para.RequestedUsage.Usage.Length = uint32(len(oids))
+ para.RequestedUsage.Usage.UsageIdentifiers = &oids[0]
+ } else {
+ para.RequestedUsage.Type = syscall.USAGE_MATCH_TYPE_AND
+ para.RequestedUsage.Usage.Length = 0
+ para.RequestedUsage.Usage.UsageIdentifiers = nil
+ }
+
+ var verifyTime *syscall.Filetime
+ if opts != nil && !opts.CurrentTime.IsZero() {
+ ft := syscall.NsecToFiletime(opts.CurrentTime.UnixNano())
+ verifyTime = &ft
+ }
+
+ // CertGetCertificateChain will traverse Windows's root stores
+ // in an attempt to build a verified certificate chain. Once
+ // it has found a verified chain, it stops. MSDN docs on
+ // CERT_CHAIN_CONTEXT:
+ //
+ // When a CERT_CHAIN_CONTEXT is built, the first simple chain
+ // begins with an end certificate and ends with a self-signed
+ // certificate. If that self-signed certificate is not a root
+ // or otherwise trusted certificate, an attempt is made to
+ // build a new chain. CTLs are used to create the new chain
+ // beginning with the self-signed certificate from the original
+ // chain as the end certificate of the new chain. This process
+ // continues building additional simple chains until the first
+ // self-signed certificate is a trusted certificate or until
+ // an additional simple chain cannot be built.
+ //
+ // The result is that we'll only get a single trusted chain to
+ // return to our caller.
+ var chainCtx *syscall.CertChainContext
+ err = syscall.CertGetCertificateChain(syscall.Handle(0), storeCtx, verifyTime, storeCtx.Store, para, 0, 0, &chainCtx)
+ if err != nil {
+ return nil, err
+ }
+ defer syscall.CertFreeCertificateChain(chainCtx)
+
+ err = checkChainTrustStatus(c, chainCtx)
+ if err != nil {
+ return nil, err
+ }
+
+ if hasDNSName {
+ err = checkChainSSLServerPolicy(c, chainCtx, opts)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ chain, err := extractSimpleChain(chainCtx.Chains, int(chainCtx.ChainCount))
+ if err != nil {
+ return nil, err
+ }
+
+ chains = append(chains, chain)
+
+ return chains, nil
+}
+
+func initSystemRoots() {
+ systemRoots = NewCertPool()
+}
diff --git a/libgo/go/crypto/x509/verify.go b/libgo/go/crypto/x509/verify.go
index 3859dd8d488..307c5ef0339 100644
--- a/libgo/go/crypto/x509/verify.go
+++ b/libgo/go/crypto/x509/verify.go
@@ -5,6 +5,7 @@
package x509
import (
+ "runtime"
"strings"
"time"
"unicode/utf8"
@@ -23,6 +24,9 @@ const (
// certificate has a name constraint which doesn't include the name
// being checked.
CANotAuthorizedForThisName
+ // TooManyIntermediates results when a path length constraint is
+ // violated.
+ TooManyIntermediates
)
// CertificateInvalidError results when an odd error occurs. Users of this
@@ -40,6 +44,8 @@ func (e CertificateInvalidError) Error() string {
return "x509: certificate has expired or is not yet valid"
case CANotAuthorizedForThisName:
return "x509: a root or intermediate certificate is not authorized to sign in this domain"
+ case TooManyIntermediates:
+ return "x509: too many intermediates for path length constraint"
}
return "x509: unknown error"
}
@@ -76,7 +82,7 @@ func (e UnknownAuthorityError) Error() string {
type VerifyOptions struct {
DNSName string
Intermediates *CertPool
- Roots *CertPool
+ Roots *CertPool // if nil, the system roots are used
CurrentTime time.Time // if zero, the current time is used
}
@@ -87,7 +93,7 @@ const (
)
// isValid performs validity checks on the c.
-func (c *Certificate) isValid(certType int, opts *VerifyOptions) error {
+func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *VerifyOptions) error {
now := opts.CurrentTime
if now.IsZero() {
now = time.Now()
@@ -130,26 +136,44 @@ func (c *Certificate) isValid(certType int, opts *VerifyOptions) error {
return CertificateInvalidError{c, NotAuthorizedToSign}
}
+ if c.BasicConstraintsValid && c.MaxPathLen >= 0 {
+ numIntermediates := len(currentChain) - 1
+ if numIntermediates > c.MaxPathLen {
+ return CertificateInvalidError{c, TooManyIntermediates}
+ }
+ }
+
return nil
}
// Verify attempts to verify c by building one or more chains from c to a
-// certificate in opts.roots, using certificates in opts.Intermediates if
+// certificate in opts.Roots, using certificates in opts.Intermediates if
// needed. If successful, it returns one or more chains where the first
// element of the chain is c and the last element is from opts.Roots.
//
// WARNING: this doesn't do any revocation checking.
func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err error) {
- err = c.isValid(leafCertificate, &opts)
+ // Use Windows's own verification and chain building.
+ if opts.Roots == nil && runtime.GOOS == "windows" {
+ return c.systemVerify(&opts)
+ }
+
+ if opts.Roots == nil {
+ opts.Roots = systemRootsPool()
+ }
+
+ err = c.isValid(leafCertificate, nil, &opts)
if err != nil {
return
}
+
if len(opts.DNSName) > 0 {
err = c.VerifyHostname(opts.DNSName)
if err != nil {
return
}
}
+
return c.buildChains(make(map[int][][]*Certificate), []*Certificate{c}, &opts)
}
@@ -163,7 +187,7 @@ func appendToFreshChain(chain []*Certificate, cert *Certificate) []*Certificate
func (c *Certificate) buildChains(cache map[int][][]*Certificate, currentChain []*Certificate, opts *VerifyOptions) (chains [][]*Certificate, err error) {
for _, rootNum := range opts.Roots.findVerifiedParents(c) {
root := opts.Roots.certs[rootNum]
- err = root.isValid(rootCertificate, opts)
+ err = root.isValid(rootCertificate, currentChain, opts)
if err != nil {
continue
}
@@ -178,7 +202,7 @@ nextIntermediate:
continue nextIntermediate
}
}
- err = intermediate.isValid(intermediateCertificate, opts)
+ err = intermediate.isValid(intermediateCertificate, currentChain, opts)
if err != nil {
continue
}
diff --git a/libgo/go/crypto/x509/verify_test.go b/libgo/go/crypto/x509/verify_test.go
index 2cdd66a5589..7b171b291a4 100644
--- a/libgo/go/crypto/x509/verify_test.go
+++ b/libgo/go/crypto/x509/verify_test.go
@@ -8,6 +8,7 @@ import (
"crypto/x509/pkix"
"encoding/pem"
"errors"
+ "runtime"
"strings"
"testing"
"time"
@@ -19,7 +20,7 @@ type verifyTest struct {
roots []string
currentTime int64
dnsName string
- nilRoots bool
+ systemSkip bool
errorCallback func(*testing.T, int, error) bool
expectedChains [][]string
@@ -60,14 +61,6 @@ var verifyTests = []verifyTest{
{
leaf: googleLeaf,
intermediates: []string{thawteIntermediate},
- nilRoots: true, // verifies that we don't crash
- currentTime: 1302726541,
- dnsName: "www.google.com",
- errorCallback: expectAuthorityUnknown,
- },
- {
- leaf: googleLeaf,
- intermediates: []string{thawteIntermediate},
roots: []string{verisignRoot},
currentTime: 1,
dnsName: "www.example.com",
@@ -80,6 +73,9 @@ var verifyTests = []verifyTest{
currentTime: 1302726541,
dnsName: "www.google.com",
+ // Skip when using systemVerify, since Windows
+ // *will* find the missing intermediate cert.
+ systemSkip: true,
errorCallback: expectAuthorityUnknown,
},
{
@@ -109,6 +105,9 @@ var verifyTests = []verifyTest{
roots: []string{startComRoot},
currentTime: 1302726541,
+ // Skip when using systemVerify, since Windows
+ // can only return a single chain to us (for now).
+ systemSkip: true,
expectedChains: [][]string{
{"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"},
{"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority", "StartCom Certification Authority"},
@@ -148,23 +147,26 @@ func certificateFromPEM(pemBytes string) (*Certificate, error) {
return ParseCertificate(block.Bytes)
}
-func TestVerify(t *testing.T) {
+func testVerify(t *testing.T, useSystemRoots bool) {
for i, test := range verifyTests {
+ if useSystemRoots && test.systemSkip {
+ continue
+ }
+
opts := VerifyOptions{
- Roots: NewCertPool(),
Intermediates: NewCertPool(),
DNSName: test.dnsName,
CurrentTime: time.Unix(test.currentTime, 0),
}
- if test.nilRoots {
- opts.Roots = nil
- }
- for j, root := range test.roots {
- ok := opts.Roots.AppendCertsFromPEM([]byte(root))
- if !ok {
- t.Errorf("#%d: failed to parse root #%d", i, j)
- return
+ if !useSystemRoots {
+ opts.Roots = NewCertPool()
+ for j, root := range test.roots {
+ ok := opts.Roots.AppendCertsFromPEM([]byte(root))
+ if !ok {
+ t.Errorf("#%d: failed to parse root #%d", i, j)
+ return
+ }
}
}
@@ -225,6 +227,19 @@ func TestVerify(t *testing.T) {
}
}
+func TestGoVerify(t *testing.T) {
+ testVerify(t, false)
+}
+
+func TestSystemVerify(t *testing.T) {
+ if runtime.GOOS != "windows" {
+ t.Logf("skipping verify test using system APIs on %q", runtime.GOOS)
+ return
+ }
+
+ testVerify(t, true)
+}
+
func chainToDebugString(chain []*Certificate) string {
var chainStr string
for _, cert := range chain {
diff --git a/libgo/go/crypto/x509/x509.go b/libgo/go/crypto/x509/x509.go
index f5da86b54a0..8dae7e7fcf9 100644
--- a/libgo/go/crypto/x509/x509.go
+++ b/libgo/go/crypto/x509/x509.go
@@ -429,7 +429,7 @@ func (h UnhandledCriticalExtension) Error() string {
type basicConstraints struct {
IsCA bool `asn1:"optional"`
- MaxPathLen int `asn1:"optional"`
+ MaxPathLen int `asn1:"optional,default:-1"`
}
// RFC 5280 4.2.1.4
diff --git a/libgo/go/database/sql/driver/driver.go b/libgo/go/database/sql/driver/driver.go
index 7f986b80f2c..2f5280db810 100644
--- a/libgo/go/database/sql/driver/driver.go
+++ b/libgo/go/database/sql/driver/driver.go
@@ -43,6 +43,17 @@ type Driver interface {
// documented.
var ErrSkip = errors.New("driver: skip fast-path; continue as if unimplemented")
+// ErrBadConn should be returned by a driver to signal to the sql
+// package that a driver.Conn is in a bad state (such as the server
+// having earlier closed the connection) and the sql package should
+// retry on a new connection.
+//
+// To prevent duplicate operations, ErrBadConn should NOT be returned
+// if there's a possibility that the database server might have
+// performed the operation. Even if the server sends back an error,
+// you shouldn't return ErrBadConn.
+var ErrBadConn = errors.New("driver: bad connection")
+
// Execer is an optional interface that may be implemented by a Conn.
//
// If a Conn does not implement Execer, the db package's DB.Exec will
diff --git a/libgo/go/database/sql/fakedb_test.go b/libgo/go/database/sql/fakedb_test.go
index fc63f03740a..184e7756c51 100644
--- a/libgo/go/database/sql/fakedb_test.go
+++ b/libgo/go/database/sql/fakedb_test.go
@@ -82,6 +82,7 @@ type fakeConn struct {
mu sync.Mutex
stmtsMade int
stmtsClosed int
+ numPrepare int
}
func (c *fakeConn) incrStat(v *int) {
@@ -208,10 +209,13 @@ func (c *fakeConn) Begin() (driver.Tx, error) {
func (c *fakeConn) Close() error {
if c.currTx != nil {
- return errors.New("can't close; in a Transaction")
+ return errors.New("can't close fakeConn; in a Transaction")
}
if c.db == nil {
- return errors.New("can't close; already closed")
+ return errors.New("can't close fakeConn; already closed")
+ }
+ if c.stmtsMade > c.stmtsClosed {
+ return errors.New("can't close; dangling statement(s)")
}
c.db = nil
return nil
@@ -249,6 +253,7 @@ func errf(msg string, args ...interface{}) error {
// just a limitation for fakedb)
func (c *fakeConn) prepareSelect(stmt *fakeStmt, parts []string) (driver.Stmt, error) {
if len(parts) != 3 {
+ stmt.Close()
return nil, errf("invalid SELECT syntax with %d parts; want 3", len(parts))
}
stmt.table = parts[0]
@@ -259,14 +264,17 @@ func (c *fakeConn) prepareSelect(stmt *fakeStmt, parts []string) (driver.Stmt, e
}
nameVal := strings.Split(colspec, "=")
if len(nameVal) != 2 {
+ stmt.Close()
return nil, errf("SELECT on table %q has invalid column spec of %q (index %d)", stmt.table, colspec, n)
}
column, value := nameVal[0], nameVal[1]
_, ok := c.db.columnType(stmt.table, column)
if !ok {
+ stmt.Close()
return nil, errf("SELECT on table %q references non-existent column %q", stmt.table, column)
}
if value != "?" {
+ stmt.Close()
return nil, errf("SELECT on table %q has pre-bound value for where column %q; need a question mark",
stmt.table, column)
}
@@ -279,12 +287,14 @@ func (c *fakeConn) prepareSelect(stmt *fakeStmt, parts []string) (driver.Stmt, e
// parts are table|col=type,col2=type2
func (c *fakeConn) prepareCreate(stmt *fakeStmt, parts []string) (driver.Stmt, error) {
if len(parts) != 2 {
+ stmt.Close()
return nil, errf("invalid CREATE syntax with %d parts; want 2", len(parts))
}
stmt.table = parts[0]
for n, colspec := range strings.Split(parts[1], ",") {
nameType := strings.Split(colspec, "=")
if len(nameType) != 2 {
+ stmt.Close()
return nil, errf("CREATE table %q has invalid column spec of %q (index %d)", stmt.table, colspec, n)
}
stmt.colName = append(stmt.colName, nameType[0])
@@ -296,17 +306,20 @@ func (c *fakeConn) prepareCreate(stmt *fakeStmt, parts []string) (driver.Stmt, e
// parts are table|col=?,col2=val
func (c *fakeConn) prepareInsert(stmt *fakeStmt, parts []string) (driver.Stmt, error) {
if len(parts) != 2 {
+ stmt.Close()
return nil, errf("invalid INSERT syntax with %d parts; want 2", len(parts))
}
stmt.table = parts[0]
for n, colspec := range strings.Split(parts[1], ",") {
nameVal := strings.Split(colspec, "=")
if len(nameVal) != 2 {
+ stmt.Close()
return nil, errf("INSERT table %q has invalid column spec of %q (index %d)", stmt.table, colspec, n)
}
column, value := nameVal[0], nameVal[1]
ctype, ok := c.db.columnType(stmt.table, column)
if !ok {
+ stmt.Close()
return nil, errf("INSERT table %q references non-existent column %q", stmt.table, column)
}
stmt.colName = append(stmt.colName, column)
@@ -322,10 +335,12 @@ func (c *fakeConn) prepareInsert(stmt *fakeStmt, parts []string) (driver.Stmt, e
case "int32":
i, err := strconv.Atoi(value)
if err != nil {
+ stmt.Close()
return nil, errf("invalid conversion to int32 from %q", value)
}
subsetVal = int64(i) // int64 is a subset type, but not int32
default:
+ stmt.Close()
return nil, errf("unsupported conversion for pre-bound parameter %q to type %q", value, ctype)
}
stmt.colValue = append(stmt.colValue, subsetVal)
@@ -339,6 +354,7 @@ func (c *fakeConn) prepareInsert(stmt *fakeStmt, parts []string) (driver.Stmt, e
}
func (c *fakeConn) Prepare(query string) (driver.Stmt, error) {
+ c.numPrepare++
if c.db == nil {
panic("nil c.db; conn = " + fmt.Sprintf("%#v", c))
}
@@ -360,6 +376,7 @@ func (c *fakeConn) Prepare(query string) (driver.Stmt, error) {
case "INSERT":
return c.prepareInsert(stmt, parts)
default:
+ stmt.Close()
return nil, errf("unsupported command type %q", cmd)
}
return stmt, nil
diff --git a/libgo/go/database/sql/sql.go b/libgo/go/database/sql/sql.go
index 62b551d89b5..51a357b37de 100644
--- a/libgo/go/database/sql/sql.go
+++ b/libgo/go/database/sql/sql.go
@@ -175,6 +175,16 @@ var ErrNoRows = errors.New("sql: no rows in result set")
// DB is a database handle. It's safe for concurrent use by multiple
// goroutines.
+//
+// If the underlying database driver has the concept of a connection
+// and per-connection session state, the sql package manages creating
+// and freeing connections automatically, including maintaining a free
+// pool of idle connections. If observing session state is required,
+// either do not share a *DB between multiple concurrent goroutines or
+// create and observe all state only within a transaction. Once
+// DB.Open is called, the returned Tx is bound to a single isolated
+// connection. Once Tx.Commit or Tx.Rollback is called, that
+// connection is returned to DB's idle connection pool.
type DB struct {
driver driver.Driver
dsn string
@@ -241,34 +251,56 @@ func (db *DB) conn() (driver.Conn, error) {
func (db *DB) connIfFree(wanted driver.Conn) (conn driver.Conn, ok bool) {
db.mu.Lock()
defer db.mu.Unlock()
- for n, conn := range db.freeConn {
- if conn == wanted {
- db.freeConn[n] = db.freeConn[len(db.freeConn)-1]
- db.freeConn = db.freeConn[:len(db.freeConn)-1]
- return wanted, true
+ for i, conn := range db.freeConn {
+ if conn != wanted {
+ continue
}
+ db.freeConn[i] = db.freeConn[len(db.freeConn)-1]
+ db.freeConn = db.freeConn[:len(db.freeConn)-1]
+ return wanted, true
}
return nil, false
}
-func (db *DB) putConn(c driver.Conn) {
+// putConnHook is a hook for testing.
+var putConnHook func(*DB, driver.Conn)
+
+// putConn adds a connection to the db's free pool.
+// err is optionally the last error that occured on this connection.
+func (db *DB) putConn(c driver.Conn, err error) {
+ if err == driver.ErrBadConn {
+ // Don't reuse bad connections.
+ return
+ }
db.mu.Lock()
- defer db.mu.Unlock()
+ if putConnHook != nil {
+ putConnHook(db, c)
+ }
if n := len(db.freeConn); !db.closed && n < db.maxIdleConns() {
db.freeConn = append(db.freeConn, c)
+ db.mu.Unlock()
return
}
- db.closeConn(c) // TODO(bradfitz): release lock before calling this?
-}
-
-func (db *DB) closeConn(c driver.Conn) {
- // TODO: check to see if we need this Conn for any prepared statements
- // that are active.
+ // TODO: check to see if we need this Conn for any prepared
+ // statements which are still active?
+ db.mu.Unlock()
c.Close()
}
// Prepare creates a prepared statement for later execution.
func (db *DB) Prepare(query string) (*Stmt, error) {
+ var stmt *Stmt
+ var err error
+ for i := 0; i < 10; i++ {
+ stmt, err = db.prepare(query)
+ if err != driver.ErrBadConn {
+ break
+ }
+ }
+ return stmt, err
+}
+
+func (db *DB) prepare(query string) (stmt *Stmt, err error) {
// TODO: check if db.driver supports an optional
// driver.Preparer interface and call that instead, if so,
// otherwise we make a prepared statement that's bound
@@ -279,12 +311,12 @@ func (db *DB) Prepare(query string) (*Stmt, error) {
if err != nil {
return nil, err
}
- defer db.putConn(ci)
+ defer db.putConn(ci, err)
si, err := ci.Prepare(query)
if err != nil {
return nil, err
}
- stmt := &Stmt{
+ stmt = &Stmt{
db: db,
query: query,
css: []connStmt{{ci, si}},
@@ -295,15 +327,22 @@ func (db *DB) Prepare(query string) (*Stmt, error) {
// Exec executes a query without returning any rows.
func (db *DB) Exec(query string, args ...interface{}) (Result, error) {
sargs, err := subsetTypeArgs(args)
- if err != nil {
- return nil, err
+ var res Result
+ for i := 0; i < 10; i++ {
+ res, err = db.exec(query, sargs)
+ if err != driver.ErrBadConn {
+ break
+ }
}
+ return res, err
+}
+func (db *DB) exec(query string, sargs []driver.Value) (res Result, err error) {
ci, err := db.conn()
if err != nil {
return nil, err
}
- defer db.putConn(ci)
+ defer db.putConn(ci, err)
if execer, ok := ci.(driver.Execer); ok {
resi, err := execer.Exec(query, sargs)
@@ -354,13 +393,25 @@ func (db *DB) QueryRow(query string, args ...interface{}) *Row {
// Begin starts a transaction. The isolation level is dependent on
// the driver.
func (db *DB) Begin() (*Tx, error) {
+ var tx *Tx
+ var err error
+ for i := 0; i < 10; i++ {
+ tx, err = db.begin()
+ if err != driver.ErrBadConn {
+ break
+ }
+ }
+ return tx, err
+}
+
+func (db *DB) begin() (tx *Tx, err error) {
ci, err := db.conn()
if err != nil {
return nil, err
}
txi, err := ci.Begin()
if err != nil {
- db.putConn(ci)
+ db.putConn(ci, err)
return nil, fmt.Errorf("sql: failed to Begin transaction: %v", err)
}
return &Tx{
@@ -406,7 +457,7 @@ func (tx *Tx) close() {
panic("double close") // internal error
}
tx.done = true
- tx.db.putConn(tx.ci)
+ tx.db.putConn(tx.ci, nil)
tx.ci = nil
tx.txi = nil
}
@@ -561,9 +612,11 @@ func (tx *Tx) Query(query string, args ...interface{}) (*Rows, error) {
return nil, err
}
rows, err := stmt.Query(args...)
- if err == nil {
- rows.closeStmt = stmt
+ if err != nil {
+ stmt.Close()
+ return nil, err
}
+ rows.closeStmt = stmt
return rows, err
}
@@ -609,7 +662,7 @@ func (s *Stmt) Exec(args ...interface{}) (Result, error) {
if err != nil {
return nil, err
}
- defer releaseConn()
+ defer releaseConn(nil)
// -1 means the driver doesn't know how to count the number of
// placeholders, so we won't sanity check input here and instead let the
@@ -672,7 +725,7 @@ func (s *Stmt) Exec(args ...interface{}) (Result, error) {
// connStmt returns a free driver connection on which to execute the
// statement, a function to call to release the connection, and a
// statement bound to that connection.
-func (s *Stmt) connStmt() (ci driver.Conn, releaseConn func(), si driver.Stmt, err error) {
+func (s *Stmt) connStmt() (ci driver.Conn, releaseConn func(error), si driver.Stmt, err error) {
if err = s.stickyErr; err != nil {
return
}
@@ -691,7 +744,7 @@ func (s *Stmt) connStmt() (ci driver.Conn, releaseConn func(), si driver.Stmt, e
if err != nil {
return
}
- releaseConn = func() { s.tx.releaseConn() }
+ releaseConn = func(error) { s.tx.releaseConn() }
return ci, releaseConn, s.txsi, nil
}
@@ -700,7 +753,7 @@ func (s *Stmt) connStmt() (ci driver.Conn, releaseConn func(), si driver.Stmt, e
for _, v := range s.css {
// TODO(bradfitz): lazily clean up entries in this
// list with dead conns while enumerating
- if _, match = s.db.connIfFree(cs.ci); match {
+ if _, match = s.db.connIfFree(v.ci); match {
cs = v
break
}
@@ -710,22 +763,28 @@ func (s *Stmt) connStmt() (ci driver.Conn, releaseConn func(), si driver.Stmt, e
// Make a new conn if all are busy.
// TODO(bradfitz): or wait for one? make configurable later?
if !match {
- ci, err := s.db.conn()
- if err != nil {
- return nil, nil, nil, err
- }
- si, err := ci.Prepare(s.query)
- if err != nil {
- return nil, nil, nil, err
+ for i := 0; ; i++ {
+ ci, err := s.db.conn()
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ si, err := ci.Prepare(s.query)
+ if err == driver.ErrBadConn && i < 10 {
+ continue
+ }
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ s.mu.Lock()
+ cs = connStmt{ci, si}
+ s.css = append(s.css, cs)
+ s.mu.Unlock()
+ break
}
- s.mu.Lock()
- cs = connStmt{ci, si}
- s.css = append(s.css, cs)
- s.mu.Unlock()
}
conn := cs.ci
- releaseConn = func() { s.db.putConn(conn) }
+ releaseConn = func(err error) { s.db.putConn(conn, err) }
return conn, releaseConn, cs.si, nil
}
@@ -749,7 +808,7 @@ func (s *Stmt) Query(args ...interface{}) (*Rows, error) {
}
rowsi, err := si.Query(sargs)
if err != nil {
- s.db.putConn(ci)
+ releaseConn(err)
return nil, err
}
// Note: ownership of ci passes to the *Rows, to be freed
@@ -800,7 +859,7 @@ func (s *Stmt) Close() error {
for _, v := range s.css {
if ci, match := s.db.connIfFree(v.ci); match {
v.si.Close()
- s.db.putConn(ci)
+ s.db.putConn(ci, nil)
} else {
// TODO(bradfitz): care that we can't close
// this statement because the statement's
@@ -827,7 +886,7 @@ func (s *Stmt) Close() error {
type Rows struct {
db *DB
ci driver.Conn // owned; must call putconn when closed to release
- releaseConn func()
+ releaseConn func(error)
rowsi driver.Rows
closed bool
@@ -939,7 +998,7 @@ func (rs *Rows) Close() error {
}
rs.closed = true
err := rs.rowsi.Close()
- rs.releaseConn()
+ rs.releaseConn(err)
if rs.closeStmt != nil {
rs.closeStmt.Close()
}
@@ -963,7 +1022,7 @@ func (r *Row) Scan(dest ...interface{}) error {
}
// TODO(bradfitz): for now we need to defensively clone all
- // []byte that the driver returned (not permitting
+ // []byte that the driver returned (not permitting
// *RawBytes in Rows.Scan), since we're about to close
// the Rows in our defer, when we return from this function.
// the contract with the driver.Next(...) interface is that it
diff --git a/libgo/go/database/sql/sql_test.go b/libgo/go/database/sql/sql_test.go
index c985a10beee..b296705865f 100644
--- a/libgo/go/database/sql/sql_test.go
+++ b/libgo/go/database/sql/sql_test.go
@@ -5,13 +5,35 @@
package sql
import (
+ "database/sql/driver"
"fmt"
"reflect"
+ "runtime"
"strings"
"testing"
"time"
)
+func init() {
+ type dbConn struct {
+ db *DB
+ c driver.Conn
+ }
+ freedFrom := make(map[dbConn]string)
+ putConnHook = func(db *DB, c driver.Conn) {
+ for _, oc := range db.freeConn {
+ if oc == c {
+ // print before panic, as panic may get lost due to conflicting panic
+ // (all goroutines asleep) elsewhere, since we might not unlock
+ // the mutex in freeConn here.
+ println("double free of conn. conflicts are:\nA) " + freedFrom[dbConn{db, c}] + "\n\nand\nB) " + stack())
+ panic("double free of conn.")
+ }
+ }
+ freedFrom[dbConn{db, c}] = stack()
+ }
+}
+
const fakeDBName = "foo"
var chrisBirthday = time.Unix(123456789, 0)
@@ -47,9 +69,19 @@ func closeDB(t *testing.T, db *DB) {
}
}
+// numPrepares assumes that db has exactly 1 idle conn and returns
+// its count of calls to Prepare
+func numPrepares(t *testing.T, db *DB) int {
+ if n := len(db.freeConn); n != 1 {
+ t.Fatalf("free conns = %d; want 1", n)
+ }
+ return db.freeConn[0].(*fakeConn).numPrepare
+}
+
func TestQuery(t *testing.T) {
db := newTestDB(t, "people")
defer closeDB(t, db)
+ prepares0 := numPrepares(t, db)
rows, err := db.Query("SELECT|people|age,name|")
if err != nil {
t.Fatalf("Query: %v", err)
@@ -83,7 +115,10 @@ func TestQuery(t *testing.T) {
// And verify that the final rows.Next() call, which hit EOF,
// also closed the rows connection.
if n := len(db.freeConn); n != 1 {
- t.Errorf("free conns after query hitting EOF = %d; want 1", n)
+ t.Fatalf("free conns after query hitting EOF = %d; want 1", n)
+ }
+ if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
+ t.Errorf("executed %d Prepare statements; want 1", prepares)
}
}
@@ -216,6 +251,7 @@ func TestStatementQueryRow(t *testing.T) {
if err != nil {
t.Fatalf("Prepare: %v", err)
}
+ defer stmt.Close()
var age int
for n, tt := range []struct {
name string
@@ -256,6 +292,7 @@ func TestExec(t *testing.T) {
if err != nil {
t.Errorf("Stmt, err = %v, %v", stmt, err)
}
+ defer stmt.Close()
type execTest struct {
args []interface{}
@@ -297,11 +334,14 @@ func TestTxStmt(t *testing.T) {
if err != nil {
t.Fatalf("Stmt, err = %v, %v", stmt, err)
}
+ defer stmt.Close()
tx, err := db.Begin()
if err != nil {
t.Fatalf("Begin = %v", err)
}
- _, err = tx.Stmt(stmt).Exec("Bobby", 7)
+ txs := tx.Stmt(stmt)
+ defer txs.Close()
+ _, err = txs.Exec("Bobby", 7)
if err != nil {
t.Fatalf("Exec = %v", err)
}
@@ -330,6 +370,7 @@ func TestTxQuery(t *testing.T) {
if err != nil {
t.Fatal(err)
}
+ defer r.Close()
if !r.Next() {
if r.Err() != nil {
@@ -345,6 +386,22 @@ func TestTxQuery(t *testing.T) {
}
}
+func TestTxQueryInvalid(t *testing.T) {
+ db := newTestDB(t, "")
+ defer closeDB(t, db)
+
+ tx, err := db.Begin()
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer tx.Rollback()
+
+ _, err = tx.Query("SELECT|t1|name|")
+ if err == nil {
+ t.Fatal("Error expected")
+ }
+}
+
// Tests fix for issue 2542, that we release a lock when querying on
// a closed connection.
func TestIssue2542Deadlock(t *testing.T) {
@@ -450,48 +507,48 @@ type nullTestSpec struct {
func TestNullStringParam(t *testing.T) {
spec := nullTestSpec{"nullstring", "string", [6]nullTestRow{
- nullTestRow{NullString{"aqua", true}, "", NullString{"aqua", true}},
- nullTestRow{NullString{"brown", false}, "", NullString{"", false}},
- nullTestRow{"chartreuse", "", NullString{"chartreuse", true}},
- nullTestRow{NullString{"darkred", true}, "", NullString{"darkred", true}},
- nullTestRow{NullString{"eel", false}, "", NullString{"", false}},
- nullTestRow{"foo", NullString{"black", false}, nil},
+ {NullString{"aqua", true}, "", NullString{"aqua", true}},
+ {NullString{"brown", false}, "", NullString{"", false}},
+ {"chartreuse", "", NullString{"chartreuse", true}},
+ {NullString{"darkred", true}, "", NullString{"darkred", true}},
+ {NullString{"eel", false}, "", NullString{"", false}},
+ {"foo", NullString{"black", false}, nil},
}}
nullTestRun(t, spec)
}
func TestNullInt64Param(t *testing.T) {
spec := nullTestSpec{"nullint64", "int64", [6]nullTestRow{
- nullTestRow{NullInt64{31, true}, 1, NullInt64{31, true}},
- nullTestRow{NullInt64{-22, false}, 1, NullInt64{0, false}},
- nullTestRow{22, 1, NullInt64{22, true}},
- nullTestRow{NullInt64{33, true}, 1, NullInt64{33, true}},
- nullTestRow{NullInt64{222, false}, 1, NullInt64{0, false}},
- nullTestRow{0, NullInt64{31, false}, nil},
+ {NullInt64{31, true}, 1, NullInt64{31, true}},
+ {NullInt64{-22, false}, 1, NullInt64{0, false}},
+ {22, 1, NullInt64{22, true}},
+ {NullInt64{33, true}, 1, NullInt64{33, true}},
+ {NullInt64{222, false}, 1, NullInt64{0, false}},
+ {0, NullInt64{31, false}, nil},
}}
nullTestRun(t, spec)
}
func TestNullFloat64Param(t *testing.T) {
spec := nullTestSpec{"nullfloat64", "float64", [6]nullTestRow{
- nullTestRow{NullFloat64{31.2, true}, 1, NullFloat64{31.2, true}},
- nullTestRow{NullFloat64{13.1, false}, 1, NullFloat64{0, false}},
- nullTestRow{-22.9, 1, NullFloat64{-22.9, true}},
- nullTestRow{NullFloat64{33.81, true}, 1, NullFloat64{33.81, true}},
- nullTestRow{NullFloat64{222, false}, 1, NullFloat64{0, false}},
- nullTestRow{10, NullFloat64{31.2, false}, nil},
+ {NullFloat64{31.2, true}, 1, NullFloat64{31.2, true}},
+ {NullFloat64{13.1, false}, 1, NullFloat64{0, false}},
+ {-22.9, 1, NullFloat64{-22.9, true}},
+ {NullFloat64{33.81, true}, 1, NullFloat64{33.81, true}},
+ {NullFloat64{222, false}, 1, NullFloat64{0, false}},
+ {10, NullFloat64{31.2, false}, nil},
}}
nullTestRun(t, spec)
}
func TestNullBoolParam(t *testing.T) {
spec := nullTestSpec{"nullbool", "bool", [6]nullTestRow{
- nullTestRow{NullBool{false, true}, true, NullBool{false, true}},
- nullTestRow{NullBool{true, false}, false, NullBool{false, false}},
- nullTestRow{true, true, NullBool{true, true}},
- nullTestRow{NullBool{true, true}, false, NullBool{true, true}},
- nullTestRow{NullBool{true, false}, true, NullBool{false, false}},
- nullTestRow{true, NullBool{true, false}, nil},
+ {NullBool{false, true}, true, NullBool{false, true}},
+ {NullBool{true, false}, false, NullBool{false, false}},
+ {true, true, NullBool{true, true}},
+ {NullBool{true, true}, false, NullBool{true, true}},
+ {NullBool{true, false}, true, NullBool{false, false}},
+ {true, NullBool{true, false}, nil},
}}
nullTestRun(t, spec)
}
@@ -510,6 +567,7 @@ func nullTestRun(t *testing.T, spec nullTestSpec) {
if err != nil {
t.Fatalf("prepare: %v", err)
}
+ defer stmt.Close()
if _, err := stmt.Exec(3, "chris", spec.rows[2].nullParam, spec.rows[2].notNullParam); err != nil {
t.Errorf("exec insert chris: %v", err)
}
@@ -549,3 +607,8 @@ func nullTestRun(t *testing.T, spec nullTestSpec) {
}
}
}
+
+func stack() string {
+ buf := make([]byte, 1024)
+ return string(buf[:runtime.Stack(buf, false)])
+}
diff --git a/libgo/go/encoding/asn1/asn1.go b/libgo/go/encoding/asn1/asn1.go
index 4d1ae38c4ed..3bf81a68cf4 100644
--- a/libgo/go/encoding/asn1/asn1.go
+++ b/libgo/go/encoding/asn1/asn1.go
@@ -250,10 +250,14 @@ func parseBase128Int(bytes []byte, initOffset int) (ret, offset int, err error)
func parseUTCTime(bytes []byte) (ret time.Time, err error) {
s := string(bytes)
ret, err = time.Parse("0601021504Z0700", s)
- if err == nil {
- return
+ if err != nil {
+ ret, err = time.Parse("060102150405Z0700", s)
}
- ret, err = time.Parse("060102150405Z0700", s)
+ if err == nil && ret.Year() >= 2050 {
+ // UTCTime only encodes times prior to 2050. See https://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
+ ret = ret.AddDate(-100, 0, 0)
+ }
+
return
}
diff --git a/libgo/go/encoding/asn1/asn1_test.go b/libgo/go/encoding/asn1/asn1_test.go
index 92c9eb62d2c..93803f43532 100644
--- a/libgo/go/encoding/asn1/asn1_test.go
+++ b/libgo/go/encoding/asn1/asn1_test.go
@@ -321,7 +321,7 @@ var parseFieldParametersTestData []parseFieldParametersTest = []parseFieldParame
{"default:42", fieldParameters{defaultValue: newInt64(42)}},
{"tag:17", fieldParameters{tag: newInt(17)}},
{"optional,explicit,default:42,tag:17", fieldParameters{optional: true, explicit: true, defaultValue: newInt64(42), tag: newInt(17)}},
- {"optional,explicit,default:42,tag:17,rubbish1", fieldParameters{true, true, false, newInt64(42), newInt(17), 0, false}},
+ {"optional,explicit,default:42,tag:17,rubbish1", fieldParameters{true, true, false, newInt64(42), newInt(17), 0, false, false}},
{"set", fieldParameters{set: true}},
}
diff --git a/libgo/go/encoding/asn1/common.go b/libgo/go/encoding/asn1/common.go
index f7cb3acbb86..03856bc55c5 100644
--- a/libgo/go/encoding/asn1/common.go
+++ b/libgo/go/encoding/asn1/common.go
@@ -75,6 +75,7 @@ type fieldParameters struct {
tag *int // the EXPLICIT or IMPLICIT tag (maybe nil).
stringType int // the string tag to use when marshaling.
set bool // true iff this should be encoded as a SET
+ omitEmpty bool // true iff this should be omitted if empty when marshaling.
// Invariants:
// if explicit is set, tag is non-nil.
@@ -116,6 +117,8 @@ func parseFieldParameters(str string) (ret fieldParameters) {
if ret.tag == nil {
ret.tag = new(int)
}
+ case part == "omitempty":
+ ret.omitEmpty = true
}
}
return
diff --git a/libgo/go/encoding/asn1/marshal.go b/libgo/go/encoding/asn1/marshal.go
index 774bee74baa..163bca575de 100644
--- a/libgo/go/encoding/asn1/marshal.go
+++ b/libgo/go/encoding/asn1/marshal.go
@@ -463,6 +463,10 @@ func marshalField(out *forkableWriter, v reflect.Value, params fieldParameters)
return marshalField(out, v.Elem(), params)
}
+ if v.Kind() == reflect.Slice && v.Len() == 0 && params.omitEmpty {
+ return
+ }
+
if params.optional && reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface()) {
return
}
diff --git a/libgo/go/encoding/asn1/marshal_test.go b/libgo/go/encoding/asn1/marshal_test.go
index a7447f97812..f43bcae681a 100644
--- a/libgo/go/encoding/asn1/marshal_test.go
+++ b/libgo/go/encoding/asn1/marshal_test.go
@@ -54,6 +54,10 @@ type optionalRawValueTest struct {
A RawValue `asn1:"optional"`
}
+type omitEmptyTest struct {
+ A []string `asn1:"omitempty"`
+}
+
type testSET []int
var PST = time.FixedZone("PST", -8*60*60)
@@ -116,6 +120,8 @@ var marshalTests = []marshalTest{
{rawContentsStruct{[]byte{0x30, 3, 1, 2, 3}, 64}, "3003010203"},
{RawValue{Tag: 1, Class: 2, IsCompound: false, Bytes: []byte{1, 2, 3}}, "8103010203"},
{testSET([]int{10}), "310302010a"},
+ {omitEmptyTest{[]string{}}, "3000"},
+ {omitEmptyTest{[]string{"1"}}, "30053003130131"},
}
func TestMarshal(t *testing.T) {
diff --git a/libgo/go/encoding/binary/binary.go b/libgo/go/encoding/binary/binary.go
index 02f090d53f3..712e490e656 100644
--- a/libgo/go/encoding/binary/binary.go
+++ b/libgo/go/encoding/binary/binary.go
@@ -2,12 +2,17 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Package binary implements translation between
-// unsigned integer values and byte sequences
-// and the reading and writing of fixed-size values.
+// Package binary implements translation between numbers and byte sequences
+// and encoding and decoding of varints.
+//
+// Numbers are translated by reading and writing fixed-size values.
// A fixed-size value is either a fixed-size arithmetic
// type (int8, uint8, int16, float32, complex64, ...)
// or an array or struct containing only fixed-size values.
+//
+// Varints are a method of encoding integers using one or more bytes;
+// numbers with smaller absolute value take a smaller number of bytes.
+// For a specification, see http://code.google.com/apis/protocolbuffers/docs/encoding.html.
package binary
import (
diff --git a/libgo/go/encoding/csv/reader.go b/libgo/go/encoding/csv/reader.go
index 9aa398e58b2..db4d988526f 100644
--- a/libgo/go/encoding/csv/reader.go
+++ b/libgo/go/encoding/csv/reader.go
@@ -92,7 +92,8 @@ var (
// If FieldsPerRecord is positive, Read requires each record to
// have the given number of fields. If FieldsPerRecord is 0, Read sets it to
// the number of fields in the first record, so that future records must
-// have the same field count.
+// have the same field count. If FieldsPerRecord is negative, no check is
+// made and records may have a variable number of fields.
//
// If LazyQuotes is true, a quote may appear in an unquoted field and a
// non-doubled quote may appear in a quoted field.
diff --git a/libgo/go/encoding/gob/decode.go b/libgo/go/encoding/gob/decode.go
index 0708a83c99a..e32a178aba3 100644
--- a/libgo/go/encoding/gob/decode.go
+++ b/libgo/go/encoding/gob/decode.go
@@ -707,6 +707,9 @@ func (dec *Decoder) decodeInterface(ityp reflect.Type, state *decoderState, p ui
if name == "" {
// Copy the representation of the nil interface value to the target.
// This is horribly unsafe and special.
+ if indir > 0 {
+ p = allocate(ityp, p, 1) // All but the last level has been allocated by dec.Indirect
+ }
*(*[2]uintptr)(unsafe.Pointer(p)) = ivalue.InterfaceData()
return
}
diff --git a/libgo/go/encoding/gob/doc.go b/libgo/go/encoding/gob/doc.go
index c9ad18e7641..96885f8ded4 100644
--- a/libgo/go/encoding/gob/doc.go
+++ b/libgo/go/encoding/gob/doc.go
@@ -226,7 +226,7 @@ where * signifies zero or more repetitions and the type id of a value must
be predefined or be defined before the value in the stream.
See "Gobs of data" for a design discussion of the gob wire format:
-http://blog.golang.org/2011/03/gobs-of-data.html
+http://golang.org/doc/articles/gobs_of_data.html
*/
package gob
diff --git a/libgo/go/encoding/gob/encoder_test.go b/libgo/go/encoding/gob/encoder_test.go
index 050786dfd1f..c4947cbb8d3 100644
--- a/libgo/go/encoding/gob/encoder_test.go
+++ b/libgo/go/encoding/gob/encoder_test.go
@@ -694,8 +694,8 @@ type Bug3 struct {
func TestGobPtrSlices(t *testing.T) {
in := []*Bug3{
- &Bug3{1, nil},
- &Bug3{2, nil},
+ {1, nil},
+ {2, nil},
}
b := new(bytes.Buffer)
err := NewEncoder(b).Encode(&in)
diff --git a/libgo/go/encoding/gob/gobencdec_test.go b/libgo/go/encoding/gob/gobencdec_test.go
index 83644c0331b..45240d764dc 100644
--- a/libgo/go/encoding/gob/gobencdec_test.go
+++ b/libgo/go/encoding/gob/gobencdec_test.go
@@ -573,3 +573,22 @@ func TestGobEncodeIsZero(t *testing.T) {
t.Fatalf("%v != %v", x, y)
}
}
+
+func TestGobEncodePtrError(t *testing.T) {
+ var err error
+ b := new(bytes.Buffer)
+ enc := NewEncoder(b)
+ err = enc.Encode(&err)
+ if err != nil {
+ t.Fatal("encode:", err)
+ }
+ dec := NewDecoder(b)
+ err2 := fmt.Errorf("foo")
+ err = dec.Decode(&err2)
+ if err != nil {
+ t.Fatal("decode:", err)
+ }
+ if err2 != nil {
+ t.Fatalf("expected nil, got %v", err2)
+ }
+}
diff --git a/libgo/go/encoding/json/encode.go b/libgo/go/encoding/json/encode.go
index 5425a3a90a1..14957b8487b 100644
--- a/libgo/go/encoding/json/encode.go
+++ b/libgo/go/encoding/json/encode.go
@@ -6,7 +6,7 @@
// RFC 4627.
//
// See "JSON and Go" for an introduction to this package:
-// http://blog.golang.org/2011/01/json-and-go.html
+// http://golang.org/doc/articles/json_and_go.html
package json
import (
@@ -43,7 +43,8 @@ import (
// to keep some browsers from misinterpreting JSON output as HTML.
//
// Array and slice values encode as JSON arrays, except that
-// []byte encodes as a base64-encoded string.
+// []byte encodes as a base64-encoded string, and a nil slice
+// encodes as the null JSON object.
//
// Struct values encode as JSON objects. Each exported struct field
// becomes a member of the object unless
diff --git a/libgo/go/exp/gotype/gotype.go b/libgo/go/exp/gotype/gotype.go
index 30eaf22fca6..3aca40e8e74 100644
--- a/libgo/go/exp/gotype/gotype.go
+++ b/libgo/go/exp/gotype/gotype.go
@@ -171,7 +171,7 @@ func processFiles(filenames []string, allFiles bool) {
func processPackage(fset *token.FileSet, files map[string]*ast.File) {
// make a package (resolve all identifiers)
- pkg, err := ast.NewPackage(fset, files, types.GcImporter, types.Universe)
+ pkg, err := ast.NewPackage(fset, files, types.GcImport, types.Universe)
if err != nil {
report(err)
return
diff --git a/libgo/go/exp/norm/maketables.go b/libgo/go/exp/norm/maketables.go
index bb21bb58109..1deedc949c2 100644
--- a/libgo/go/exp/norm/maketables.go
+++ b/libgo/go/exp/norm/maketables.go
@@ -577,7 +577,7 @@ type decompSet [4]map[string]bool
func makeDecompSet() decompSet {
m := decompSet{}
- for i, _ := range m {
+ for i := range m {
m[i] = make(map[string]bool)
}
return m
@@ -646,7 +646,7 @@ func printCharInfoTables() int {
fmt.Println("const (")
for i, m := range decompSet {
sa := []string{}
- for s, _ := range m {
+ for s := range m {
sa = append(sa, s)
}
sort.Strings(sa)
diff --git a/libgo/go/exp/norm/normalize.go b/libgo/go/exp/norm/normalize.go
index b5cd44abfa0..c1d74f89d01 100644
--- a/libgo/go/exp/norm/normalize.go
+++ b/libgo/go/exp/norm/normalize.go
@@ -356,7 +356,7 @@ func lastBoundary(fd *formInfo, b []byte) int {
return -1
}
if info.size == 0 { // ends with incomplete rune
- if p == 0 { // starts wtih incomplete rune
+ if p == 0 { // starts with incomplete rune
return -1
}
i = p
diff --git a/libgo/go/exp/types/check_test.go b/libgo/go/exp/types/check_test.go
index 0e20646a005..34c26c9908c 100644
--- a/libgo/go/exp/types/check_test.go
+++ b/libgo/go/exp/types/check_test.go
@@ -184,7 +184,7 @@ func check(t *testing.T, testname string, testfiles []string) {
eliminate(t, errors, err)
// verify errors returned after resolving identifiers
- pkg, err := ast.NewPackage(fset, files, GcImporter, Universe)
+ pkg, err := ast.NewPackage(fset, files, GcImport, Universe)
eliminate(t, errors, err)
// verify errors returned by the typechecker
diff --git a/libgo/go/exp/types/exportdata.go b/libgo/go/exp/types/exportdata.go
index fa5b6a37fe8..bca2038804e 100644
--- a/libgo/go/exp/types/exportdata.go
+++ b/libgo/go/exp/types/exportdata.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// This file implements ExportData.
+// This file implements FindGcExportData.
package types
@@ -11,15 +11,14 @@ import (
"errors"
"fmt"
"io"
- "os"
"strconv"
"strings"
)
-func readGopackHeader(buf *bufio.Reader) (name string, size int, err error) {
+func readGopackHeader(r *bufio.Reader) (name string, size int, err error) {
// See $GOROOT/include/ar.h.
hdr := make([]byte, 16+12+6+6+8+10+2)
- _, err = io.ReadFull(buf, hdr)
+ _, err = io.ReadFull(r, hdr)
if err != nil {
return
}
@@ -36,33 +35,14 @@ func readGopackHeader(buf *bufio.Reader) (name string, size int, err error) {
return
}
-type dataReader struct {
- *bufio.Reader
- io.Closer
-}
-
-// ExportData returns a readCloser positioned at the beginning of the
-// export data section of the given object/archive file, or an error.
-// It is the caller's responsibility to close the readCloser.
+// FindGcExportData positions the reader r at the beginning of the
+// export data section of an underlying GC-created object/archive
+// file by reading from it. The reader must be positioned at the
+// start of the file before calling this function.
//
-func ExportData(filename string) (rc io.ReadCloser, err error) {
- file, err := os.Open(filename)
- if err != nil {
- return
- }
-
- defer func() {
- if err != nil {
- file.Close()
- // Add file name to error.
- err = fmt.Errorf("reading export data: %s: %v", filename, err)
- }
- }()
-
- buf := bufio.NewReader(file)
-
+func FindGcExportData(r *bufio.Reader) (err error) {
// Read first line to make sure this is an object file.
- line, err := buf.ReadSlice('\n')
+ line, err := r.ReadSlice('\n')
if err != nil {
return
}
@@ -74,7 +54,7 @@ func ExportData(filename string) (rc io.ReadCloser, err error) {
// First entry should be __.SYMDEF.
// Read and discard.
- if name, size, err = readGopackHeader(buf); err != nil {
+ if name, size, err = readGopackHeader(r); err != nil {
return
}
if name != "__.SYMDEF" {
@@ -88,15 +68,14 @@ func ExportData(filename string) (rc io.ReadCloser, err error) {
if n > block {
n = block
}
- _, err = io.ReadFull(buf, tmp[:n])
- if err != nil {
+ if _, err = io.ReadFull(r, tmp[:n]); err != nil {
return
}
size -= n
}
// Second entry should be __.PKGDEF.
- if name, size, err = readGopackHeader(buf); err != nil {
+ if name, size, err = readGopackHeader(r); err != nil {
return
}
if name != "__.PKGDEF" {
@@ -106,8 +85,7 @@ func ExportData(filename string) (rc io.ReadCloser, err error) {
// Read first line of __.PKGDEF data, so that line
// is once again the first line of the input.
- line, err = buf.ReadSlice('\n')
- if err != nil {
+ if line, err = r.ReadSlice('\n'); err != nil {
return
}
}
@@ -122,12 +100,10 @@ func ExportData(filename string) (rc io.ReadCloser, err error) {
// Skip over object header to export data.
// Begins after first line with $$.
for line[0] != '$' {
- line, err = buf.ReadSlice('\n')
- if err != nil {
+ if line, err = r.ReadSlice('\n'); err != nil {
return
}
}
- rc = &dataReader{buf, file}
return
}
diff --git a/libgo/go/exp/types/gcimporter.go b/libgo/go/exp/types/gcimporter.go
index cb996f28055..07ab087abf8 100644
--- a/libgo/go/exp/types/gcimporter.go
+++ b/libgo/go/exp/types/gcimporter.go
@@ -2,12 +2,13 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// This file implements an ast.Importer for gc generated object files.
+// This file implements an ast.Importer for gc-generated object files.
// TODO(gri) Eventually move this into a separate package outside types.
package types
import (
+ "bufio"
"errors"
"fmt"
"go/ast"
@@ -24,41 +25,40 @@ import (
const trace = false // set to true for debugging
-var (
- pkgExts = [...]string{".a", ".5", ".6", ".8"}
-)
+var pkgExts = [...]string{".a", ".5", ".6", ".8"}
-// findPkg returns the filename and package id for an import path.
+// FindPkg returns the filename and unique package id for an import
+// path based on package information provided by build.Import (using
+// the build.Default build.Context).
// If no file was found, an empty filename is returned.
-func findPkg(path string) (filename, id string) {
+//
+func FindPkg(path, srcDir string) (filename, id string) {
if len(path) == 0 {
return
}
id = path
var noext string
- switch path[0] {
+ switch {
default:
// "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
- bp, _ := build.Import(path, "", build.FindOnly)
+ bp, _ := build.Import(path, srcDir, build.FindOnly)
if bp.PkgObj == "" {
return
}
noext = bp.PkgObj
if strings.HasSuffix(noext, ".a") {
- noext = noext[:len(noext)-2]
+ noext = noext[:len(noext)-len(".a")]
}
- case '.':
+ case build.IsLocalImport(path):
// "./x" -> "/this/directory/x.ext", "/this/directory/x"
- cwd, err := os.Getwd()
- if err != nil {
- return
- }
- noext = filepath.Join(cwd, path)
+ noext = filepath.Join(srcDir, path)
id = noext
- case '/':
+ case filepath.IsAbs(path):
+ // for completeness only - go/build.Import
+ // does not support absolute imports
// "/x" -> "/x.ext", "/x"
noext = path
}
@@ -75,6 +75,89 @@ func findPkg(path string) (filename, id string) {
return
}
+// GcImportData imports a package by reading the gc-generated export data,
+// adds the corresponding package object to the imports map indexed by id,
+// and returns the object.
+//
+// The imports map must contains all packages already imported, and no map
+// entry with id as the key must be present. The data reader position must
+// be the beginning of the export data section. The filename is only used
+// in error messages.
+//
+func GcImportData(imports map[string]*ast.Object, filename, id string, data *bufio.Reader) (pkg *ast.Object, err error) {
+ if trace {
+ fmt.Printf("importing %s (%s)\n", id, filename)
+ }
+
+ if imports[id] != nil {
+ panic(fmt.Sprintf("package %s already imported", id))
+ }
+
+ // support for gcParser error handling
+ defer func() {
+ if r := recover(); r != nil {
+ err = r.(importError) // will re-panic if r is not an importError
+ }
+ }()
+
+ var p gcParser
+ p.init(filename, id, data, imports)
+ pkg = p.parseExport()
+
+ return
+}
+
+// GcImport imports a gc-generated package given its import path, adds the
+// corresponding package object to the imports map, and returns the object.
+// Local import paths are interpreted relative to the current working directory.
+// The imports map must contains all packages already imported.
+// GcImport satisfies the ast.Importer signature.
+//
+func GcImport(imports map[string]*ast.Object, path string) (pkg *ast.Object, err error) {
+ if path == "unsafe" {
+ return Unsafe, nil
+ }
+
+ srcDir, err := os.Getwd()
+ if err != nil {
+ return
+ }
+ filename, id := FindPkg(path, srcDir)
+ if filename == "" {
+ err = errors.New("can't find import: " + id)
+ return
+ }
+
+ if pkg = imports[id]; pkg != nil {
+ return // package was imported before
+ }
+
+ // open file
+ f, err := os.Open(filename)
+ if err != nil {
+ return
+ }
+ defer func() {
+ f.Close()
+ if err != nil {
+ // Add file name to error.
+ err = fmt.Errorf("reading export data: %s: %v", filename, err)
+ }
+ }()
+
+ buf := bufio.NewReader(f)
+ if err = FindGcExportData(buf); err != nil {
+ return
+ }
+
+ pkg, err = GcImportData(imports, filename, id, buf)
+
+ return
+}
+
+// ----------------------------------------------------------------------------
+// gcParser
+
// gcParser parses the exports inside a gc compiler-produced
// object/archive file and populates its scope with the results.
type gcParser struct {
@@ -109,47 +192,6 @@ func (p *gcParser) next() {
}
}
-// GcImporter implements the ast.Importer signature.
-func GcImporter(imports map[string]*ast.Object, path string) (pkg *ast.Object, err error) {
- if path == "unsafe" {
- return Unsafe, nil
- }
-
- defer func() {
- if r := recover(); r != nil {
- err = r.(importError) // will re-panic if r is not an importError
- if trace {
- panic(err) // force a stack trace
- }
- }
- }()
-
- filename, id := findPkg(path)
- if filename == "" {
- err = errors.New("can't find import: " + id)
- return
- }
-
- if pkg = imports[id]; pkg != nil {
- return // package was imported before
- }
-
- buf, err := ExportData(filename)
- if err != nil {
- return
- }
- defer buf.Close()
-
- if trace {
- fmt.Printf("importing %s (%s)\n", id, filename)
- }
-
- var p gcParser
- p.init(filename, id, buf, imports)
- pkg = p.parseExport()
- return
-}
-
// Declare inserts a named object of the given kind in scope.
func (p *gcParser) declare(scope *ast.Scope, kind ast.ObjKind, name string) *ast.Object {
// the object may have been imported before - if it exists
@@ -707,7 +749,6 @@ func (p *gcParser) parseConstDecl() {
p.next()
typ = String.Underlying
default:
- println(p.tok)
p.errorf("expected literal got %s", scanner.TokenString(p.tok))
}
if obj.Type == nil {
diff --git a/libgo/go/exp/types/gcimporter_test.go b/libgo/go/exp/types/gcimporter_test.go
index c229b50113d..20247b0dc44 100644
--- a/libgo/go/exp/types/gcimporter_test.go
+++ b/libgo/go/exp/types/gcimporter_test.go
@@ -17,23 +17,23 @@ import (
"time"
)
-var gcName, gcPath string // compiler name and path
+var gcPath string // Go compiler path
func init() {
// determine compiler
+ var gc string
switch runtime.GOARCH {
case "386":
- gcName = "8g"
+ gc = "8g"
case "amd64":
- gcName = "6g"
+ gc = "6g"
case "arm":
- gcName = "5g"
+ gc = "5g"
default:
- gcName = "unknown-GOARCH-compiler"
- gcPath = gcName
+ gcPath = "unknown-GOARCH-compiler"
return
}
- gcPath = filepath.Join(build.ToolDir, gcName)
+ gcPath = filepath.Join(build.ToolDir, gc)
}
func compile(t *testing.T, dirname, filename string) {
@@ -41,7 +41,7 @@ func compile(t *testing.T, dirname, filename string) {
cmd.Dir = dirname
out, err := cmd.CombinedOutput()
if err != nil {
- t.Errorf("%s %s failed: %s", gcName, filename, err)
+ t.Errorf("%s %s failed: %s", gcPath, filename, err)
return
}
t.Logf("%s", string(out))
@@ -52,7 +52,7 @@ func compile(t *testing.T, dirname, filename string) {
var imports = make(map[string]*ast.Object)
func testPath(t *testing.T, path string) bool {
- _, err := GcImporter(imports, path)
+ _, err := GcImport(imports, path)
if err != nil {
t.Errorf("testPath(%s): %s", path, err)
return false
diff --git a/libgo/go/exp/types/universe.go b/libgo/go/exp/types/universe.go
index 46cff31bce8..cb89397b2e5 100644
--- a/libgo/go/exp/types/universe.go
+++ b/libgo/go/exp/types/universe.go
@@ -102,11 +102,6 @@ func init() {
defType("Pointer")
defFun("Alignof")
- defFun("New")
- defFun("NewArray")
defFun("Offsetof")
- defFun("Reflect")
defFun("Sizeof")
- defFun("Typeof")
- defFun("Unreflect")
}
diff --git a/libgo/go/exp/wingui/gui.go b/libgo/go/exp/wingui/gui.go
deleted file mode 100644
index 3b79873fa2b..00000000000
--- a/libgo/go/exp/wingui/gui.go
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build windows
-
-package main
-
-import (
- "fmt"
- "os"
- "syscall"
- "unsafe"
-)
-
-// some help functions
-
-func abortf(format string, a ...interface{}) {
- fmt.Fprintf(os.Stdout, format, a...)
- os.Exit(1)
-}
-
-func abortErrNo(funcname string, err error) {
- errno, _ := err.(syscall.Errno)
- abortf("%s failed: %d %s\n", funcname, uint32(errno), err)
-}
-
-// global vars
-
-var (
- mh syscall.Handle
- bh syscall.Handle
-)
-
-// WinProc called by windows to notify us of all windows events we might be interested in.
-func WndProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (rc uintptr) {
- switch msg {
- case WM_CREATE:
- var e error
- // CreateWindowEx
- bh, e = CreateWindowEx(
- 0,
- syscall.StringToUTF16Ptr("button"),
- syscall.StringToUTF16Ptr("Quit"),
- WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON,
- 75, 70, 140, 25,
- hwnd, 1, mh, 0)
- if e != nil {
- abortErrNo("CreateWindowEx", e)
- }
- fmt.Printf("button handle is %x\n", bh)
- rc = DefWindowProc(hwnd, msg, wparam, lparam)
- case WM_COMMAND:
- switch syscall.Handle(lparam) {
- case bh:
- e := PostMessage(hwnd, WM_CLOSE, 0, 0)
- if e != nil {
- abortErrNo("PostMessage", e)
- }
- default:
- rc = DefWindowProc(hwnd, msg, wparam, lparam)
- }
- case WM_CLOSE:
- DestroyWindow(hwnd)
- case WM_DESTROY:
- PostQuitMessage(0)
- default:
- rc = DefWindowProc(hwnd, msg, wparam, lparam)
- }
- //fmt.Printf("WndProc(0x%08x, %d, 0x%08x, 0x%08x) (%d)\n", hwnd, msg, wparam, lparam, rc)
- return
-}
-
-func rungui() int {
- var e error
-
- // GetModuleHandle
- mh, e = GetModuleHandle(nil)
- if e != nil {
- abortErrNo("GetModuleHandle", e)
- }
-
- // Get icon we're going to use.
- myicon, e := LoadIcon(0, IDI_APPLICATION)
- if e != nil {
- abortErrNo("LoadIcon", e)
- }
-
- // Get cursor we're going to use.
- mycursor, e := LoadCursor(0, IDC_ARROW)
- if e != nil {
- abortErrNo("LoadCursor", e)
- }
-
- // Create callback
- wproc := syscall.NewCallback(WndProc)
-
- // RegisterClassEx
- wcname := syscall.StringToUTF16Ptr("myWindowClass")
- var wc Wndclassex
- wc.Size = uint32(unsafe.Sizeof(wc))
- wc.WndProc = wproc
- wc.Instance = mh
- wc.Icon = myicon
- wc.Cursor = mycursor
- wc.Background = COLOR_BTNFACE + 1
- wc.MenuName = nil
- wc.ClassName = wcname
- wc.IconSm = myicon
- if _, e := RegisterClassEx(&wc); e != nil {
- abortErrNo("RegisterClassEx", e)
- }
-
- // CreateWindowEx
- wh, e := CreateWindowEx(
- WS_EX_CLIENTEDGE,
- wcname,
- syscall.StringToUTF16Ptr("My window"),
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT, 300, 200,
- 0, 0, mh, 0)
- if e != nil {
- abortErrNo("CreateWindowEx", e)
- }
- fmt.Printf("main window handle is %x\n", wh)
-
- // ShowWindow
- ShowWindow(wh, SW_SHOWDEFAULT)
-
- // UpdateWindow
- if e := UpdateWindow(wh); e != nil {
- abortErrNo("UpdateWindow", e)
- }
-
- // Process all windows messages until WM_QUIT.
- var m Msg
- for {
- r, e := GetMessage(&m, 0, 0, 0)
- if e != nil {
- abortErrNo("GetMessage", e)
- }
- if r == 0 {
- // WM_QUIT received -> get out
- break
- }
- TranslateMessage(&m)
- DispatchMessage(&m)
- }
- return int(m.Wparam)
-}
-
-func main() {
- rc := rungui()
- os.Exit(rc)
-}
diff --git a/libgo/go/exp/wingui/winapi.go b/libgo/go/exp/wingui/winapi.go
deleted file mode 100644
index f876088e91f..00000000000
--- a/libgo/go/exp/wingui/winapi.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build windows
-
-package main
-
-import (
- "syscall"
- "unsafe"
-)
-
-type Wndclassex struct {
- Size uint32
- Style uint32
- WndProc uintptr
- ClsExtra int32
- WndExtra int32
- Instance syscall.Handle
- Icon syscall.Handle
- Cursor syscall.Handle
- Background syscall.Handle
- MenuName *uint16
- ClassName *uint16
- IconSm syscall.Handle
-}
-
-type Point struct {
- X uintptr
- Y uintptr
-}
-
-type Msg struct {
- Hwnd syscall.Handle
- Message uint32
- Wparam uintptr
- Lparam uintptr
- Time uint32
- Pt Point
-}
-
-const (
- // Window styles
- WS_OVERLAPPED = 0
- WS_POPUP = 0x80000000
- WS_CHILD = 0x40000000
- WS_MINIMIZE = 0x20000000
- WS_VISIBLE = 0x10000000
- WS_DISABLED = 0x8000000
- WS_CLIPSIBLINGS = 0x4000000
- WS_CLIPCHILDREN = 0x2000000
- WS_MAXIMIZE = 0x1000000
- WS_CAPTION = WS_BORDER | WS_DLGFRAME
- WS_BORDER = 0x800000
- WS_DLGFRAME = 0x400000
- WS_VSCROLL = 0x200000
- WS_HSCROLL = 0x100000
- WS_SYSMENU = 0x80000
- WS_THICKFRAME = 0x40000
- WS_GROUP = 0x20000
- WS_TABSTOP = 0x10000
- WS_MINIMIZEBOX = 0x20000
- WS_MAXIMIZEBOX = 0x10000
- WS_TILED = WS_OVERLAPPED
- WS_ICONIC = WS_MINIMIZE
- WS_SIZEBOX = WS_THICKFRAME
- // Common Window Styles
- WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
- WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW
- WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU
- WS_CHILDWINDOW = WS_CHILD
-
- WS_EX_CLIENTEDGE = 0x200
-
- // Some windows messages
- WM_CREATE = 1
- WM_DESTROY = 2
- WM_CLOSE = 16
- WM_COMMAND = 273
-
- // Some button control styles
- BS_DEFPUSHBUTTON = 1
-
- // Some color constants
- COLOR_WINDOW = 5
- COLOR_BTNFACE = 15
-
- // Default window position
- CW_USEDEFAULT = 0x80000000 - 0x100000000
-
- // Show window default style
- SW_SHOWDEFAULT = 10
-)
-
-var (
- // Some globally known cursors
- IDC_ARROW = MakeIntResource(32512)
- IDC_IBEAM = MakeIntResource(32513)
- IDC_WAIT = MakeIntResource(32514)
- IDC_CROSS = MakeIntResource(32515)
-
- // Some globally known icons
- IDI_APPLICATION = MakeIntResource(32512)
- IDI_HAND = MakeIntResource(32513)
- IDI_QUESTION = MakeIntResource(32514)
- IDI_EXCLAMATION = MakeIntResource(32515)
- IDI_ASTERISK = MakeIntResource(32516)
- IDI_WINLOGO = MakeIntResource(32517)
- IDI_WARNING = IDI_EXCLAMATION
- IDI_ERROR = IDI_HAND
- IDI_INFORMATION = IDI_ASTERISK
-)
-
-//sys GetModuleHandle(modname *uint16) (handle syscall.Handle, err error) = GetModuleHandleW
-//sys RegisterClassEx(wndclass *Wndclassex) (atom uint16, err error) = user32.RegisterClassExW
-//sys CreateWindowEx(exstyle uint32, classname *uint16, windowname *uint16, style uint32, x int32, y int32, width int32, height int32, wndparent syscall.Handle, menu syscall.Handle, instance syscall.Handle, param uintptr) (hwnd syscall.Handle, err error) = user32.CreateWindowExW
-//sys DefWindowProc(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (lresult uintptr) = user32.DefWindowProcW
-//sys DestroyWindow(hwnd syscall.Handle) (err error) = user32.DestroyWindow
-//sys PostQuitMessage(exitcode int32) = user32.PostQuitMessage
-//sys ShowWindow(hwnd syscall.Handle, cmdshow int32) (wasvisible bool) = user32.ShowWindow
-//sys UpdateWindow(hwnd syscall.Handle) (err error) = user32.UpdateWindow
-//sys GetMessage(msg *Msg, hwnd syscall.Handle, MsgFilterMin uint32, MsgFilterMax uint32) (ret int32, err error) [failretval==-1] = user32.GetMessageW
-//sys TranslateMessage(msg *Msg) (done bool) = user32.TranslateMessage
-//sys DispatchMessage(msg *Msg) (ret int32) = user32.DispatchMessageW
-//sys LoadIcon(instance syscall.Handle, iconname *uint16) (icon syscall.Handle, err error) = user32.LoadIconW
-//sys LoadCursor(instance syscall.Handle, cursorname *uint16) (cursor syscall.Handle, err error) = user32.LoadCursorW
-//sys SetCursor(cursor syscall.Handle) (precursor syscall.Handle, err error) = user32.SetCursor
-//sys SendMessage(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (lresult uintptr) = user32.SendMessageW
-//sys PostMessage(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (err error) = user32.PostMessageW
-
-func MakeIntResource(id uint16) *uint16 {
- return (*uint16)(unsafe.Pointer(uintptr(id)))
-}
diff --git a/libgo/go/exp/wingui/zwinapi.go b/libgo/go/exp/wingui/zwinapi.go
deleted file mode 100644
index 5666c6de530..00000000000
--- a/libgo/go/exp/wingui/zwinapi.go
+++ /dev/null
@@ -1,192 +0,0 @@
-// +build windows
-// mksyscall_windows.pl winapi.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package main
-
-import "unsafe"
-import "syscall"
-
-var (
- modkernel32 = syscall.NewLazyDLL("kernel32.dll")
- moduser32 = syscall.NewLazyDLL("user32.dll")
-
- procGetModuleHandleW = modkernel32.NewProc("GetModuleHandleW")
- procRegisterClassExW = moduser32.NewProc("RegisterClassExW")
- procCreateWindowExW = moduser32.NewProc("CreateWindowExW")
- procDefWindowProcW = moduser32.NewProc("DefWindowProcW")
- procDestroyWindow = moduser32.NewProc("DestroyWindow")
- procPostQuitMessage = moduser32.NewProc("PostQuitMessage")
- procShowWindow = moduser32.NewProc("ShowWindow")
- procUpdateWindow = moduser32.NewProc("UpdateWindow")
- procGetMessageW = moduser32.NewProc("GetMessageW")
- procTranslateMessage = moduser32.NewProc("TranslateMessage")
- procDispatchMessageW = moduser32.NewProc("DispatchMessageW")
- procLoadIconW = moduser32.NewProc("LoadIconW")
- procLoadCursorW = moduser32.NewProc("LoadCursorW")
- procSetCursor = moduser32.NewProc("SetCursor")
- procSendMessageW = moduser32.NewProc("SendMessageW")
- procPostMessageW = moduser32.NewProc("PostMessageW")
-)
-
-func GetModuleHandle(modname *uint16) (handle syscall.Handle, err error) {
- r0, _, e1 := syscall.Syscall(procGetModuleHandleW.Addr(), 1, uintptr(unsafe.Pointer(modname)), 0, 0)
- handle = syscall.Handle(r0)
- if handle == 0 {
- if e1 != 0 {
- err = error(e1)
- } else {
- err = syscall.EINVAL
- }
- }
- return
-}
-
-func RegisterClassEx(wndclass *Wndclassex) (atom uint16, err error) {
- r0, _, e1 := syscall.Syscall(procRegisterClassExW.Addr(), 1, uintptr(unsafe.Pointer(wndclass)), 0, 0)
- atom = uint16(r0)
- if atom == 0 {
- if e1 != 0 {
- err = error(e1)
- } else {
- err = syscall.EINVAL
- }
- }
- return
-}
-
-func CreateWindowEx(exstyle uint32, classname *uint16, windowname *uint16, style uint32, x int32, y int32, width int32, height int32, wndparent syscall.Handle, menu syscall.Handle, instance syscall.Handle, param uintptr) (hwnd syscall.Handle, err error) {
- r0, _, e1 := syscall.Syscall12(procCreateWindowExW.Addr(), 12, uintptr(exstyle), uintptr(unsafe.Pointer(classname)), uintptr(unsafe.Pointer(windowname)), uintptr(style), uintptr(x), uintptr(y), uintptr(width), uintptr(height), uintptr(wndparent), uintptr(menu), uintptr(instance), uintptr(param))
- hwnd = syscall.Handle(r0)
- if hwnd == 0 {
- if e1 != 0 {
- err = error(e1)
- } else {
- err = syscall.EINVAL
- }
- }
- return
-}
-
-func DefWindowProc(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (lresult uintptr) {
- r0, _, _ := syscall.Syscall6(procDefWindowProcW.Addr(), 4, uintptr(hwnd), uintptr(msg), uintptr(wparam), uintptr(lparam), 0, 0)
- lresult = uintptr(r0)
- return
-}
-
-func DestroyWindow(hwnd syscall.Handle) (err error) {
- r1, _, e1 := syscall.Syscall(procDestroyWindow.Addr(), 1, uintptr(hwnd), 0, 0)
- if int(r1) == 0 {
- if e1 != 0 {
- err = error(e1)
- } else {
- err = syscall.EINVAL
- }
- }
- return
-}
-
-func PostQuitMessage(exitcode int32) {
- syscall.Syscall(procPostQuitMessage.Addr(), 1, uintptr(exitcode), 0, 0)
- return
-}
-
-func ShowWindow(hwnd syscall.Handle, cmdshow int32) (wasvisible bool) {
- r0, _, _ := syscall.Syscall(procShowWindow.Addr(), 2, uintptr(hwnd), uintptr(cmdshow), 0)
- wasvisible = bool(r0 != 0)
- return
-}
-
-func UpdateWindow(hwnd syscall.Handle) (err error) {
- r1, _, e1 := syscall.Syscall(procUpdateWindow.Addr(), 1, uintptr(hwnd), 0, 0)
- if int(r1) == 0 {
- if e1 != 0 {
- err = error(e1)
- } else {
- err = syscall.EINVAL
- }
- }
- return
-}
-
-func GetMessage(msg *Msg, hwnd syscall.Handle, MsgFilterMin uint32, MsgFilterMax uint32) (ret int32, err error) {
- r0, _, e1 := syscall.Syscall6(procGetMessageW.Addr(), 4, uintptr(unsafe.Pointer(msg)), uintptr(hwnd), uintptr(MsgFilterMin), uintptr(MsgFilterMax), 0, 0)
- ret = int32(r0)
- if ret == -1 {
- if e1 != 0 {
- err = error(e1)
- } else {
- err = syscall.EINVAL
- }
- }
- return
-}
-
-func TranslateMessage(msg *Msg) (done bool) {
- r0, _, _ := syscall.Syscall(procTranslateMessage.Addr(), 1, uintptr(unsafe.Pointer(msg)), 0, 0)
- done = bool(r0 != 0)
- return
-}
-
-func DispatchMessage(msg *Msg) (ret int32) {
- r0, _, _ := syscall.Syscall(procDispatchMessageW.Addr(), 1, uintptr(unsafe.Pointer(msg)), 0, 0)
- ret = int32(r0)
- return
-}
-
-func LoadIcon(instance syscall.Handle, iconname *uint16) (icon syscall.Handle, err error) {
- r0, _, e1 := syscall.Syscall(procLoadIconW.Addr(), 2, uintptr(instance), uintptr(unsafe.Pointer(iconname)), 0)
- icon = syscall.Handle(r0)
- if icon == 0 {
- if e1 != 0 {
- err = error(e1)
- } else {
- err = syscall.EINVAL
- }
- }
- return
-}
-
-func LoadCursor(instance syscall.Handle, cursorname *uint16) (cursor syscall.Handle, err error) {
- r0, _, e1 := syscall.Syscall(procLoadCursorW.Addr(), 2, uintptr(instance), uintptr(unsafe.Pointer(cursorname)), 0)
- cursor = syscall.Handle(r0)
- if cursor == 0 {
- if e1 != 0 {
- err = error(e1)
- } else {
- err = syscall.EINVAL
- }
- }
- return
-}
-
-func SetCursor(cursor syscall.Handle) (precursor syscall.Handle, err error) {
- r0, _, e1 := syscall.Syscall(procSetCursor.Addr(), 1, uintptr(cursor), 0, 0)
- precursor = syscall.Handle(r0)
- if precursor == 0 {
- if e1 != 0 {
- err = error(e1)
- } else {
- err = syscall.EINVAL
- }
- }
- return
-}
-
-func SendMessage(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (lresult uintptr) {
- r0, _, _ := syscall.Syscall6(procSendMessageW.Addr(), 4, uintptr(hwnd), uintptr(msg), uintptr(wparam), uintptr(lparam), 0, 0)
- lresult = uintptr(r0)
- return
-}
-
-func PostMessage(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (err error) {
- r1, _, e1 := syscall.Syscall6(procPostMessageW.Addr(), 4, uintptr(hwnd), uintptr(msg), uintptr(wparam), uintptr(lparam), 0, 0)
- if int(r1) == 0 {
- if e1 != 0 {
- err = error(e1)
- } else {
- err = syscall.EINVAL
- }
- }
- return
-}
diff --git a/libgo/go/expvar/expvar.go b/libgo/go/expvar/expvar.go
index 1919296ea8f..b06599505fc 100644
--- a/libgo/go/expvar/expvar.go
+++ b/libgo/go/expvar/expvar.go
@@ -41,10 +41,14 @@ type Var interface {
// Int is a 64-bit integer variable that satisfies the Var interface.
type Int struct {
i int64
- mu sync.Mutex
+ mu sync.RWMutex
}
-func (v *Int) String() string { return strconv.FormatInt(v.i, 10) }
+func (v *Int) String() string {
+ v.mu.RLock()
+ defer v.mu.RUnlock()
+ return strconv.FormatInt(v.i, 10)
+}
func (v *Int) Add(delta int64) {
v.mu.Lock()
@@ -61,10 +65,14 @@ func (v *Int) Set(value int64) {
// Float is a 64-bit float variable that satisfies the Var interface.
type Float struct {
f float64
- mu sync.Mutex
+ mu sync.RWMutex
}
-func (v *Float) String() string { return strconv.FormatFloat(v.f, 'g', -1, 64) }
+func (v *Float) String() string {
+ v.mu.RLock()
+ defer v.mu.RUnlock()
+ return strconv.FormatFloat(v.f, 'g', -1, 64)
+}
// Add adds delta to v.
func (v *Float) Add(delta float64) {
@@ -95,17 +103,17 @@ type KeyValue struct {
func (v *Map) String() string {
v.mu.RLock()
defer v.mu.RUnlock()
- b := new(bytes.Buffer)
- fmt.Fprintf(b, "{")
+ var b bytes.Buffer
+ fmt.Fprintf(&b, "{")
first := true
for key, val := range v.m {
if !first {
- fmt.Fprintf(b, ", ")
+ fmt.Fprintf(&b, ", ")
}
- fmt.Fprintf(b, "\"%s\": %v", key, val)
+ fmt.Fprintf(&b, "\"%s\": %v", key, val)
first = false
}
- fmt.Fprintf(b, "}")
+ fmt.Fprintf(&b, "}")
return b.String()
}
@@ -180,12 +188,21 @@ func (v *Map) Do(f func(KeyValue)) {
// String is a string variable, and satisfies the Var interface.
type String struct {
- s string
+ s string
+ mu sync.RWMutex
}
-func (v *String) String() string { return strconv.Quote(v.s) }
+func (v *String) String() string {
+ v.mu.RLock()
+ defer v.mu.RUnlock()
+ return strconv.Quote(v.s)
+}
-func (v *String) Set(value string) { v.s = value }
+func (v *String) Set(value string) {
+ v.mu.Lock()
+ defer v.mu.Unlock()
+ v.s = value
+}
// Func implements Var by calling the function
// and formatting the returned value using JSON.
diff --git a/libgo/go/flag/example_test.go b/libgo/go/flag/example_test.go
new file mode 100644
index 00000000000..04a0d20ee4e
--- /dev/null
+++ b/libgo/go/flag/example_test.go
@@ -0,0 +1,83 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// These examples demonstrate more intricate uses of the flag package.
+package flag_test
+
+import (
+ "errors"
+ "flag"
+ "fmt"
+ "strings"
+ "time"
+)
+
+// Example 1: A single string flag called "species" with default value "gopher".
+var species = flag.String("species", "gopher", "the species we are studying")
+
+// Example 2: Two flags sharing a variable, so we can have a shorthand.
+// The order of initialization is undefined, so make sure both use the
+// same default value. They must be set up with an init function.
+var gopherType string
+
+func init() {
+ const (
+ defaultGopher = "pocket"
+ usage = "the variety of gopher"
+ )
+ flag.StringVar(&gopherType, "gopher_type", defaultGopher, usage)
+ flag.StringVar(&gopherType, "g", defaultGopher, usage+" (shorthand)")
+}
+
+// Example 3: A user-defined flag type, a slice of durations.
+type interval []time.Duration
+
+// String is the method to format the flag's value, part of the flag.Value interface.
+// The String method's output will be used in diagnostics.
+func (i *interval) String() string {
+ return fmt.Sprint(*i)
+}
+
+// Set is the method to set the flag value, part of the flag.Value interface.
+// Set's argument is a string to be parsed to set the flag.
+// It's a comma-separated list, so we split it.
+func (i *interval) Set(value string) error {
+ // If we wanted to allow the flag to be set multiple times,
+ // accumulating values, we would delete this if statement.
+ // That would permit usages such as
+ // -deltaT 10s -deltaT 15s
+ // and other combinations.
+ if len(*i) > 0 {
+ return errors.New("interval flag already set")
+ }
+ for _, dt := range strings.Split(value, ",") {
+ duration, err := time.ParseDuration(dt)
+ if err != nil {
+ return err
+ }
+ *i = append(*i, duration)
+ }
+ return nil
+}
+
+// Define a flag to accumulate durations. Because it has a special type,
+// we need to use the Var function and therefore create the flag during
+// init.
+
+var intervalFlag interval
+
+func init() {
+ // Tie the command-line flag to the intervalFlag variable and
+ // set a usage message.
+ flag.Var(&intervalFlag, "deltaT", "comma-separated list of intervals to use between events")
+}
+
+func Example() {
+ // All the interesting pieces are with the variables declared above, but
+ // to enable the flag package to see the flags defined there, one must
+ // execute, typically at the start of main (not init!):
+ // flag.Parse()
+ // We don't run it here because this is not a main function and
+ // the testing suite has already parsed the flags.
+}
diff --git a/libgo/go/fmt/doc.go b/libgo/go/fmt/doc.go
index 7d4178da768..9660370c292 100644
--- a/libgo/go/fmt/doc.go
+++ b/libgo/go/fmt/doc.go
@@ -7,7 +7,8 @@
to C's printf and scanf. The format 'verbs' are derived from C's but
are simpler.
- Printing:
+
+ Printing
The verbs:
@@ -127,7 +128,8 @@
by a single character (the verb) and end with a parenthesized
description.
- Scanning:
+
+ Scanning
An analogous set of functions scans formatted text to yield
values. Scan, Scanf and Scanln read from os.Stdin; Fscan,
diff --git a/libgo/go/fmt/export_test.go b/libgo/go/fmt/export_test.go
new file mode 100644
index 00000000000..89d57ee6ce3
--- /dev/null
+++ b/libgo/go/fmt/export_test.go
@@ -0,0 +1,7 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package fmt
+
+var IsSpace = isSpace
diff --git a/libgo/go/fmt/fmt_test.go b/libgo/go/fmt/fmt_test.go
index f34df59422f..e0c587a3525 100644
--- a/libgo/go/fmt/fmt_test.go
+++ b/libgo/go/fmt/fmt_test.go
@@ -13,6 +13,7 @@ import (
"strings"
"testing"
"time"
+ "unicode"
)
type (
@@ -830,3 +831,13 @@ func TestBadVerbRecursion(t *testing.T) {
t.Error("fail with value")
}
}
+
+func TestIsSpace(t *testing.T) {
+ // This tests the internal isSpace function.
+ // IsSpace = isSpace is defined in export_test.go.
+ for i := rune(0); i <= unicode.MaxRune; i++ {
+ if IsSpace(i) != unicode.IsSpace(i) {
+ t.Errorf("isSpace(%U) = %v, want %v", i, IsSpace(i), unicode.IsSpace(i))
+ }
+ }
+}
diff --git a/libgo/go/fmt/format.go b/libgo/go/fmt/format.go
index 78d9e998b1f..2186f334b91 100644
--- a/libgo/go/fmt/format.go
+++ b/libgo/go/fmt/format.go
@@ -5,9 +5,7 @@
package fmt
import (
- "bytes"
"strconv"
- "unicode"
"unicode/utf8"
)
@@ -36,10 +34,10 @@ func init() {
}
// A fmt is the raw formatter used by Printf etc.
-// It prints into a bytes.Buffer that must be set up externally.
+// It prints into a buffer that must be set up separately.
type fmt struct {
intbuf [nByte]byte
- buf *bytes.Buffer
+ buf *buffer
// width, precision
wid int
prec int
@@ -69,7 +67,7 @@ func (f *fmt) clearflags() {
f.zero = false
}
-func (f *fmt) init(buf *bytes.Buffer) {
+func (f *fmt) init(buf *buffer) {
f.buf = buf
f.clearflags()
}
@@ -247,7 +245,7 @@ func (f *fmt) integer(a int64, base uint64, signedness bool, digits string) {
}
// If we want a quoted char for %#U, move the data up to make room.
- if f.unicode && f.uniQuote && a >= 0 && a <= unicode.MaxRune && unicode.IsPrint(rune(a)) {
+ if f.unicode && f.uniQuote && a >= 0 && a <= utf8.MaxRune && strconv.IsPrint(rune(a)) {
runeWidth := utf8.RuneLen(rune(a))
width := 1 + 1 + runeWidth + 1 // space, quote, rune, quote
copy(buf[i-width:], buf[i:]) // guaranteed to have enough room.
@@ -290,16 +288,15 @@ func (f *fmt) fmt_s(s string) {
// fmt_sx formats a string as a hexadecimal encoding of its bytes.
func (f *fmt) fmt_sx(s, digits string) {
// TODO: Avoid buffer by pre-padding.
- var b bytes.Buffer
+ var b []byte
for i := 0; i < len(s); i++ {
if i > 0 && f.space {
- b.WriteByte(' ')
+ b = append(b, ' ')
}
v := s[i]
- b.WriteByte(digits[v>>4])
- b.WriteByte(digits[v&0xF])
+ b = append(b, digits[v>>4], digits[v&0xF])
}
- f.pad(b.Bytes())
+ f.pad(b)
}
// fmt_q formats a string as a double-quoted, escaped Go string constant.
diff --git a/libgo/go/fmt/print.go b/libgo/go/fmt/print.go
index c3ba2f339e5..13438243cdd 100644
--- a/libgo/go/fmt/print.go
+++ b/libgo/go/fmt/print.go
@@ -5,13 +5,11 @@
package fmt
import (
- "bytes"
"errors"
"io"
"os"
"reflect"
"sync"
- "unicode"
"unicode/utf8"
)
@@ -71,11 +69,45 @@ type GoStringer interface {
GoString() string
}
+// Use simple []byte instead of bytes.Buffer to avoid large dependency.
+type buffer []byte
+
+func (b *buffer) Write(p []byte) (n int, err error) {
+ *b = append(*b, p...)
+ return len(p), nil
+}
+
+func (b *buffer) WriteString(s string) (n int, err error) {
+ *b = append(*b, s...)
+ return len(s), nil
+}
+
+func (b *buffer) WriteByte(c byte) error {
+ *b = append(*b, c)
+ return nil
+}
+
+func (bp *buffer) WriteRune(r rune) error {
+ if r < utf8.RuneSelf {
+ *bp = append(*bp, byte(r))
+ return nil
+ }
+
+ b := *bp
+ n := len(b)
+ for n+utf8.UTFMax > cap(b) {
+ b = append(b, 0)
+ }
+ w := utf8.EncodeRune(b[n:n+utf8.UTFMax], r)
+ *bp = b[:n+w]
+ return nil
+}
+
type pp struct {
n int
panicking bool
erroring bool // printing an error condition
- buf bytes.Buffer
+ buf buffer
// field holds the current item, as an interface{}.
field interface{}
// value holds the current item, as a reflect.Value, and will be
@@ -133,10 +165,10 @@ func newPrinter() *pp {
// Save used pp structs in ppFree; avoids an allocation per invocation.
func (p *pp) free() {
// Don't hold on to pp structs with large buffers.
- if cap(p.buf.Bytes()) > 1024 {
+ if cap(p.buf) > 1024 {
return
}
- p.buf.Reset()
+ p.buf = p.buf[:0]
p.field = nil
p.value = reflect.Value{}
ppFree.put(p)
@@ -179,7 +211,7 @@ func (p *pp) Write(b []byte) (ret int, err error) {
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
p := newPrinter()
p.doPrintf(format, a)
- n64, err := p.buf.WriteTo(w)
+ n64, err := w.Write(p.buf)
p.free()
return int(n64), err
}
@@ -194,7 +226,7 @@ func Printf(format string, a ...interface{}) (n int, err error) {
func Sprintf(format string, a ...interface{}) string {
p := newPrinter()
p.doPrintf(format, a)
- s := p.buf.String()
+ s := string(p.buf)
p.free()
return s
}
@@ -213,7 +245,7 @@ func Errorf(format string, a ...interface{}) error {
func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
p := newPrinter()
p.doPrint(a, false, false)
- n64, err := p.buf.WriteTo(w)
+ n64, err := w.Write(p.buf)
p.free()
return int(n64), err
}
@@ -230,7 +262,7 @@ func Print(a ...interface{}) (n int, err error) {
func Sprint(a ...interface{}) string {
p := newPrinter()
p.doPrint(a, false, false)
- s := p.buf.String()
+ s := string(p.buf)
p.free()
return s
}
@@ -245,7 +277,7 @@ func Sprint(a ...interface{}) string {
func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
p := newPrinter()
p.doPrint(a, true, true)
- n64, err := p.buf.WriteTo(w)
+ n64, err := w.Write(p.buf)
p.free()
return int(n64), err
}
@@ -262,7 +294,7 @@ func Println(a ...interface{}) (n int, err error) {
func Sprintln(a ...interface{}) string {
p := newPrinter()
p.doPrint(a, true, true)
- s := p.buf.String()
+ s := string(p.buf)
p.free()
return s
}
@@ -352,7 +384,7 @@ func (p *pp) fmtInt64(v int64, verb rune) {
case 'o':
p.fmt.integer(v, 8, signed, ldigits)
case 'q':
- if 0 <= v && v <= unicode.MaxRune {
+ if 0 <= v && v <= utf8.MaxRune {
p.fmt.fmt_qc(v)
} else {
p.badVerb(verb)
@@ -416,7 +448,7 @@ func (p *pp) fmtUint64(v uint64, verb rune, goSyntax bool) {
case 'o':
p.fmt.integer(int64(v), 8, unsigned, ldigits)
case 'q':
- if 0 <= v && v <= unicode.MaxRune {
+ if 0 <= v && v <= utf8.MaxRune {
p.fmt.fmt_qc(int64(v))
} else {
p.badVerb(verb)
diff --git a/libgo/go/fmt/scan.go b/libgo/go/fmt/scan.go
index fa9a5584a88..0b3e04069a0 100644
--- a/libgo/go/fmt/scan.go
+++ b/libgo/go/fmt/scan.go
@@ -5,15 +5,12 @@
package fmt
import (
- "bytes"
"errors"
"io"
"math"
"os"
"reflect"
"strconv"
- "strings"
- "unicode"
"unicode/utf8"
)
@@ -87,25 +84,36 @@ func Scanf(format string, a ...interface{}) (n int, err error) {
return Fscanf(os.Stdin, format, a...)
}
+type stringReader string
+
+func (r *stringReader) Read(b []byte) (n int, err error) {
+ n = copy(b, *r)
+ *r = (*r)[n:]
+ if n == 0 {
+ err = io.EOF
+ }
+ return
+}
+
// Sscan scans the argument string, storing successive space-separated
// values into successive arguments. Newlines count as space. It
// returns the number of items successfully scanned. If that is less
// than the number of arguments, err will report why.
func Sscan(str string, a ...interface{}) (n int, err error) {
- return Fscan(strings.NewReader(str), a...)
+ return Fscan((*stringReader)(&str), a...)
}
// Sscanln is similar to Sscan, but stops scanning at a newline and
// after the final item there must be a newline or EOF.
func Sscanln(str string, a ...interface{}) (n int, err error) {
- return Fscanln(strings.NewReader(str), a...)
+ return Fscanln((*stringReader)(&str), a...)
}
// Sscanf scans the argument string, storing successive space-separated
// values into successive arguments as determined by the format. It
// returns the number of items successfully parsed.
func Sscanf(str string, format string, a ...interface{}) (n int, err error) {
- return Fscanf(strings.NewReader(str), format, a...)
+ return Fscanf((*stringReader)(&str), format, a...)
}
// Fscan scans text read from r, storing successive space-separated
@@ -149,7 +157,7 @@ const eof = -1
// ss is the internal implementation of ScanState.
type ss struct {
rr io.RuneReader // where to read input
- buf bytes.Buffer // token accumulator
+ buf buffer // token accumulator
peekRune rune // one-rune lookahead
prevRune rune // last rune returned by ReadRune
count int // runes consumed so far.
@@ -262,14 +270,46 @@ func (s *ss) Token(skipSpace bool, f func(rune) bool) (tok []byte, err error) {
if f == nil {
f = notSpace
}
- s.buf.Reset()
+ s.buf = s.buf[:0]
tok = s.token(skipSpace, f)
return
}
+// space is a copy of the unicode.White_Space ranges,
+// to avoid depending on package unicode.
+var space = [][2]uint16{
+ {0x0009, 0x000d},
+ {0x0020, 0x0020},
+ {0x0085, 0x0085},
+ {0x00a0, 0x00a0},
+ {0x1680, 0x1680},
+ {0x180e, 0x180e},
+ {0x2000, 0x200a},
+ {0x2028, 0x2029},
+ {0x202f, 0x202f},
+ {0x205f, 0x205f},
+ {0x3000, 0x3000},
+}
+
+func isSpace(r rune) bool {
+ if r >= 1<<16 {
+ return false
+ }
+ rx := uint16(r)
+ for _, rng := range space {
+ if rx < rng[0] {
+ return false
+ }
+ if rx <= rng[1] {
+ return true
+ }
+ }
+ return false
+}
+
// notSpace is the default scanning function used in Token.
func notSpace(r rune) bool {
- return !unicode.IsSpace(r)
+ return !isSpace(r)
}
// skipSpace provides Scan() methods the ability to skip space and newline characters
@@ -378,10 +418,10 @@ func (s *ss) free(old ssave) {
return
}
// Don't hold on to ss structs with large buffers.
- if cap(s.buf.Bytes()) > 1024 {
+ if cap(s.buf) > 1024 {
return
}
- s.buf.Reset()
+ s.buf = s.buf[:0]
s.rr = nil
ssFree.put(s)
}
@@ -403,7 +443,7 @@ func (s *ss) skipSpace(stopAtNewline bool) {
s.errorString("unexpected newline")
return
}
- if !unicode.IsSpace(r) {
+ if !isSpace(r) {
s.UnreadRune()
break
}
@@ -429,7 +469,7 @@ func (s *ss) token(skipSpace bool, f func(rune) bool) []byte {
}
s.buf.WriteRune(r)
}
- return s.buf.Bytes()
+ return s.buf
}
// typeError indicates that the type of the operand did not match the format
@@ -440,6 +480,15 @@ func (s *ss) typeError(field interface{}, expected string) {
var complexError = errors.New("syntax error scanning complex number")
var boolError = errors.New("syntax error scanning boolean")
+func indexRune(s string, r rune) int {
+ for i, c := range s {
+ if c == r {
+ return i
+ }
+ }
+ return -1
+}
+
// consume reads the next rune in the input and reports whether it is in the ok string.
// If accept is true, it puts the character into the input token.
func (s *ss) consume(ok string, accept bool) bool {
@@ -447,7 +496,7 @@ func (s *ss) consume(ok string, accept bool) bool {
if r == eof {
return false
}
- if strings.IndexRune(ok, r) >= 0 {
+ if indexRune(ok, r) >= 0 {
if accept {
s.buf.WriteRune(r)
}
@@ -465,7 +514,7 @@ func (s *ss) peek(ok string) bool {
if r != eof {
s.UnreadRune()
}
- return strings.IndexRune(ok, r) >= 0
+ return indexRune(ok, r) >= 0
}
func (s *ss) notEOF() {
@@ -560,7 +609,7 @@ func (s *ss) scanNumber(digits string, haveDigits bool) string {
}
for s.accept(digits) {
}
- return s.buf.String()
+ return string(s.buf)
}
// scanRune returns the next rune value in the input.
@@ -660,16 +709,16 @@ func (s *ss) scanUint(verb rune, bitSize int) uint64 {
// if the width is specified. It's not rigorous about syntax because it doesn't check that
// we have at least some digits, but Atof will do that.
func (s *ss) floatToken() string {
- s.buf.Reset()
+ s.buf = s.buf[:0]
// NaN?
if s.accept("nN") && s.accept("aA") && s.accept("nN") {
- return s.buf.String()
+ return string(s.buf)
}
// leading sign?
s.accept(sign)
// Inf?
if s.accept("iI") && s.accept("nN") && s.accept("fF") {
- return s.buf.String()
+ return string(s.buf)
}
// digits?
for s.accept(decimalDigits) {
@@ -688,7 +737,7 @@ func (s *ss) floatToken() string {
for s.accept(decimalDigits) {
}
}
- return s.buf.String()
+ return string(s.buf)
}
// complexTokens returns the real and imaginary parts of the complex number starting here.
@@ -698,13 +747,13 @@ func (s *ss) complexTokens() (real, imag string) {
// TODO: accept N and Ni independently?
parens := s.accept("(")
real = s.floatToken()
- s.buf.Reset()
+ s.buf = s.buf[:0]
// Must now have a sign.
if !s.accept("+-") {
s.error(complexError)
}
// Sign is now in buffer
- imagSign := s.buf.String()
+ imagSign := string(s.buf)
imag = s.floatToken()
if !s.accept("i") {
s.error(complexError)
@@ -717,7 +766,7 @@ func (s *ss) complexTokens() (real, imag string) {
// convertFloat converts the string to a float64value.
func (s *ss) convertFloat(str string, n int) float64 {
- if p := strings.Index(str, "p"); p >= 0 {
+ if p := indexRune(str, 'p'); p >= 0 {
// Atof doesn't handle power-of-2 exponents,
// but they're easy to evaluate.
f, err := strconv.ParseFloat(str[:p], n)
@@ -794,7 +843,7 @@ func (s *ss) quotedString() string {
}
s.buf.WriteRune(r)
}
- return s.buf.String()
+ return string(s.buf)
case '"':
// Double-quoted: Include the quotes and let strconv.Unquote do the backslash escapes.
s.buf.WriteRune(quote)
@@ -811,7 +860,7 @@ func (s *ss) quotedString() string {
break
}
}
- result, err := strconv.Unquote(s.buf.String())
+ result, err := strconv.Unquote(string(s.buf))
if err != nil {
s.error(err)
}
@@ -844,7 +893,7 @@ func (s *ss) hexByte() (b byte, ok bool) {
if rune1 == eof {
return
}
- if unicode.IsSpace(rune1) {
+ if isSpace(rune1) {
s.UnreadRune()
return
}
@@ -862,11 +911,11 @@ func (s *ss) hexString() string {
}
s.buf.WriteByte(b)
}
- if s.buf.Len() == 0 {
+ if len(s.buf) == 0 {
s.errorString("Scan: no hex data for %x string")
return ""
}
- return s.buf.String()
+ return string(s.buf)
}
const floatVerbs = "beEfFgGv"
@@ -875,7 +924,7 @@ const hugeWid = 1 << 30
// scanOne scans a single value, deriving the scanner from the type of the argument.
func (s *ss) scanOne(verb rune, field interface{}) {
- s.buf.Reset()
+ s.buf = s.buf[:0]
var err error
// If the parameter has its own Scan method, use that.
if v, ok := field.(Scanner); ok {
@@ -1004,7 +1053,7 @@ func (s *ss) doScan(a []interface{}) (numProcessed int, err error) {
if r == '\n' || r == eof {
break
}
- if !unicode.IsSpace(r) {
+ if !isSpace(r) {
s.errorString("Scan: expected newline")
break
}
@@ -1032,7 +1081,7 @@ func (s *ss) advance(format string) (i int) {
i += w // skip the first %
}
sawSpace := false
- for unicode.IsSpace(fmtc) && i < len(format) {
+ for isSpace(fmtc) && i < len(format) {
sawSpace = true
i += w
fmtc, w = utf8.DecodeRuneInString(format[i:])
@@ -1044,7 +1093,7 @@ func (s *ss) advance(format string) (i int) {
if inputc == eof {
return
}
- if !unicode.IsSpace(inputc) {
+ if !isSpace(inputc) {
// Space in format but not in input: error
s.errorString("expected space in input to match format")
}
diff --git a/libgo/go/fmt/scan_test.go b/libgo/go/fmt/scan_test.go
index 61b48f9cc6d..320857b73e2 100644
--- a/libgo/go/fmt/scan_test.go
+++ b/libgo/go/fmt/scan_test.go
@@ -810,7 +810,7 @@ func TestMultiLine(t *testing.T) {
}
}
-// RecursiveInt accepts an string matching %d.%d.%d....
+// RecursiveInt accepts a string matching %d.%d.%d....
// and parses it into a linked list.
// It allows us to benchmark recursive descent style scanners.
type RecursiveInt struct {
@@ -826,7 +826,7 @@ func (r *RecursiveInt) Scan(state ScanState, verb rune) (err error) {
next := new(RecursiveInt)
_, err = Fscanf(state, ".%v", next)
if err != nil {
- if err == errors.New("input does not match format") || err == io.ErrUnexpectedEOF {
+ if err == io.ErrUnexpectedEOF {
err = nil
}
return
diff --git a/libgo/go/go/build/build.go b/libgo/go/go/build/build.go
index eece7610562..d749aef1513 100644
--- a/libgo/go/go/build/build.go
+++ b/libgo/go/go/build/build.go
@@ -34,7 +34,7 @@ type Context struct {
CgoEnabled bool // whether cgo can be used
BuildTags []string // additional tags to recognize in +build lines
UseAllFiles bool // use files regardless of +build lines, file names
- Gccgo bool // assume use of gccgo when computing object paths
+ Compiler string // compiler to assume when computing target paths
// By default, Import uses the operating system's file system calls
// to read directories and files. To read from other sources,
@@ -228,6 +228,7 @@ func defaultContext() Context {
c.GOOS = envOr("GOOS", runtime.GOOS)
c.GOROOT = runtime.GOROOT()
c.GOPATH = envOr("GOPATH", "")
+ c.Compiler = runtime.Compiler
switch os.Getenv("CGO_ENABLED") {
case "1":
@@ -277,11 +278,12 @@ type Package struct {
PkgObj string // installed .a file
// Source files
- GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
- CgoFiles []string // .go source files that import "C"
- CFiles []string // .c source files
- HFiles []string // .h source files
- SFiles []string // .s source files
+ GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
+ CgoFiles []string // .go source files that import "C"
+ CFiles []string // .c source files
+ HFiles []string // .h source files
+ SFiles []string // .s source files
+ SysoFiles []string // .syso system object files to add to archive
// Cgo directives
CgoPkgConfig []string // Cgo pkg-config directives
@@ -314,42 +316,58 @@ func (ctxt *Context) ImportDir(dir string, mode ImportMode) (*Package, error) {
return ctxt.Import(".", dir, mode)
}
+// NoGoError is the error used by Import to describe a directory
+// containing no Go source files.
+type NoGoError struct {
+ Dir string
+}
+
+func (e *NoGoError) Error() string {
+ return "no Go source files in " + e.Dir
+}
+
// Import returns details about the Go package named by the import path,
-// interpreting local import paths relative to the src directory. If the path
-// is a local import path naming a package that can be imported using a
-// standard import path, the returned package will set p.ImportPath to
-// that path.
+// interpreting local import paths relative to the srcDir directory.
+// If the path is a local import path naming a package that can be imported
+// using a standard import path, the returned package will set p.ImportPath
+// to that path.
//
// In the directory containing the package, .go, .c, .h, and .s files are
// considered part of the package except for:
//
// - .go files in package documentation
-// - files starting with _ or .
+// - files starting with _ or . (likely editor temporary files)
// - files with build constraints not satisfied by the context
//
// If an error occurs, Import returns a non-nil error also returns a non-nil
// *Package containing partial information.
//
-func (ctxt *Context) Import(path string, src string, mode ImportMode) (*Package, error) {
+func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Package, error) {
p := &Package{
ImportPath: path,
}
var pkga string
- if ctxt.Gccgo {
+ var pkgerr error
+ switch ctxt.Compiler {
+ case "gccgo":
dir, elem := pathpkg.Split(p.ImportPath)
pkga = "pkg/gccgo/" + dir + "lib" + elem + ".a"
- } else {
+ case "gc":
pkga = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + "/" + p.ImportPath + ".a"
+ default:
+ // Save error for end of function.
+ pkgerr = fmt.Errorf("import %q: unknown compiler %q", path, ctxt.Compiler)
}
binaryOnly := false
if IsLocalImport(path) {
- if src == "" {
+ pkga = "" // local imports have no installed path
+ if srcDir == "" {
return p, fmt.Errorf("import %q: import relative to unknown directory", path)
}
if !ctxt.isAbsPath(path) {
- p.Dir = ctxt.joinPath(src, path)
+ p.Dir = ctxt.joinPath(srcDir, path)
}
// Determine canonical import path, if any.
if ctxt.GOROOT != "" {
@@ -369,7 +387,7 @@ func (ctxt *Context) Import(path string, src string, mode ImportMode) (*Package,
// but check that using it wouldn't find something
// else first.
if ctxt.GOROOT != "" {
- if dir := ctxt.joinPath(ctxt.GOROOT, "src", sub); ctxt.isDir(dir) {
+ if dir := ctxt.joinPath(ctxt.GOROOT, "src", "pkg", sub); ctxt.isDir(dir) {
goto Found
}
}
@@ -396,7 +414,7 @@ func (ctxt *Context) Import(path string, src string, mode ImportMode) (*Package,
if ctxt.GOROOT != "" {
dir := ctxt.joinPath(ctxt.GOROOT, "src", "pkg", path)
isDir := ctxt.isDir(dir)
- binaryOnly = !isDir && mode&AllowBinary != 0 && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga))
+ binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga))
if isDir || binaryOnly {
p.Dir = dir
p.Goroot = true
@@ -407,7 +425,7 @@ func (ctxt *Context) Import(path string, src string, mode ImportMode) (*Package,
for _, root := range ctxt.gopath() {
dir := ctxt.joinPath(root, "src", path)
isDir := ctxt.isDir(dir)
- binaryOnly = !isDir && mode&AllowBinary != 0 && ctxt.isFile(ctxt.joinPath(root, pkga))
+ binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(root, pkga))
if isDir || binaryOnly {
p.Dir = dir
p.Root = root
@@ -426,14 +444,16 @@ Found:
}
p.PkgRoot = ctxt.joinPath(p.Root, "pkg")
p.BinDir = ctxt.joinPath(p.Root, "bin")
- p.PkgObj = ctxt.joinPath(p.Root, pkga)
+ if pkga != "" {
+ p.PkgObj = ctxt.joinPath(p.Root, pkga)
+ }
}
if mode&FindOnly != 0 {
- return p, nil
+ return p, pkgerr
}
if binaryOnly && (mode&AllowBinary) != 0 {
- return p, nil
+ return p, pkgerr
}
dirs, err := ctxt.readDir(p.Dir)
@@ -467,7 +487,13 @@ Found:
ext := name[i:]
switch ext {
case ".go", ".c", ".s", ".h", ".S":
- // tentatively okay
+ // tentatively okay - read to make sure
+ case ".syso":
+ // binary objects to add to package archive
+ // Likely of the form foo_windows.syso, but
+ // the name was vetted above with goodOSArchFile.
+ p.SysoFiles = append(p.SysoFiles, name)
+ continue
default:
// skip
continue
@@ -586,7 +612,7 @@ Found:
}
}
if p.Name == "" {
- return p, fmt.Errorf("no Go source files in %s", p.Dir)
+ return p, &NoGoError{p.Dir}
}
p.Imports, p.ImportPos = cleanImports(imported)
@@ -601,7 +627,7 @@ Found:
sort.Strings(p.SFiles)
}
- return p, nil
+ return p, pkgerr
}
func cleanImports(m map[string][]token.Position) ([]string, map[string][]token.Position) {
@@ -614,8 +640,8 @@ func cleanImports(m map[string][]token.Position) ([]string, map[string][]token.P
}
// Import is shorthand for Default.Import.
-func Import(path, src string, mode ImportMode) (*Package, error) {
- return Default.Import(path, src, mode)
+func Import(path, srcDir string, mode ImportMode) (*Package, error) {
+ return Default.Import(path, srcDir, mode)
}
// ImportDir is shorthand for Default.ImportDir.
@@ -848,7 +874,7 @@ func splitQuoted(s string) (r []string, err error) {
// !cgo (if cgo is disabled)
// tag (if tag is listed in ctxt.BuildTags)
// !tag (if tag is not listed in ctxt.BuildTags)
-// a slash-separated list of any of these
+// a comma-separated list of any of these
//
func (ctxt *Context) match(name string) bool {
if name == "" {
@@ -862,11 +888,11 @@ func (ctxt *Context) match(name string) bool {
return false
}
if strings.HasPrefix(name, "!") { // negation
- return !ctxt.match(name[1:])
+ return len(name) > 1 && !ctxt.match(name[1:])
}
// Tags must be letters, digits, underscores.
- // Unlike in Go identifiers, all digits is fine (e.g., "386").
+ // Unlike in Go identifiers, all digits are fine (e.g., "386").
for _, c := range name {
if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' {
return false
diff --git a/libgo/go/go/build/build_test.go b/libgo/go/go/build/build_test.go
index 06b8b0e94f8..560ebad5c97 100644
--- a/libgo/go/go/build/build_test.go
+++ b/libgo/go/go/build/build_test.go
@@ -36,6 +36,7 @@ func TestMatch(t *testing.T) {
nomatch(runtime.GOOS + "," + runtime.GOARCH + ",!foo")
match(runtime.GOOS + "," + runtime.GOARCH + ",!bar")
nomatch(runtime.GOOS + "," + runtime.GOARCH + ",bar")
+ nomatch("!")
}
func TestDotSlashImport(t *testing.T) {
diff --git a/libgo/go/go/build/deps_test.go b/libgo/go/go/build/deps_test.go
new file mode 100644
index 00000000000..4e9f32a036f
--- /dev/null
+++ b/libgo/go/go/build/deps_test.go
@@ -0,0 +1,424 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file exercises the import parser but also checks that
+// some low-level packages do not have new dependencies added.
+
+package build_test
+
+import (
+ "go/build"
+ "sort"
+ "testing"
+)
+
+// pkgDeps defines the expected dependencies between packages in
+// the Go source tree. It is a statement of policy.
+// Changes should not be made to this map without prior discussion.
+//
+// The map contains two kinds of entries:
+// 1) Lower-case keys are standard import paths and list the
+// allowed imports in that package.
+// 2) Upper-case keys define aliases for package sets, which can then
+// be used as dependencies by other rules.
+//
+// DO NOT CHANGE THIS DATA TO FIX BUILDS.
+//
+var pkgDeps = map[string][]string{
+ // L0 is the lowest level, core, nearly unavoidable packages.
+ "errors": {},
+ "io": {"errors", "sync"},
+ "runtime": {"unsafe"},
+ "sync": {"sync/atomic"},
+ "sync/atomic": {"unsafe"},
+ "unsafe": {},
+
+ "L0": {
+ "errors",
+ "io",
+ "runtime",
+ "sync",
+ "sync/atomic",
+ "unsafe",
+ },
+
+ // L1 adds simple functions and strings processing,
+ // but not Unicode tables.
+ "math": {"unsafe"},
+ "math/cmplx": {"math"},
+ "math/rand": {"L0", "math"},
+ "sort": {"math"},
+ "strconv": {"L0", "unicode/utf8", "math"},
+ "unicode/utf16": {},
+ "unicode/utf8": {},
+
+ "L1": {
+ "L0",
+ "math",
+ "math/cmplx",
+ "math/rand",
+ "sort",
+ "strconv",
+ "unicode/utf16",
+ "unicode/utf8",
+ },
+
+ // L2 adds Unicode and strings processing.
+ "bufio": {"L0", "unicode/utf8", "bytes"},
+ "bytes": {"L0", "unicode", "unicode/utf8"},
+ "path": {"L0", "unicode/utf8", "strings"},
+ "strings": {"L0", "unicode", "unicode/utf8"},
+ "unicode": {},
+
+ "L2": {
+ "L1",
+ "bufio",
+ "bytes",
+ "path",
+ "strings",
+ "unicode",
+ },
+
+ // L3 adds reflection and some basic utility packages
+ // and interface definitions, but nothing that makes
+ // system calls.
+ "crypto": {"L2", "hash"}, // interfaces
+ "crypto/cipher": {"L2"}, // interfaces
+ "encoding/base32": {"L2"},
+ "encoding/base64": {"L2"},
+ "encoding/binary": {"L2", "reflect"},
+ "hash": {"L2"}, // interfaces
+ "hash/adler32": {"L2", "hash"},
+ "hash/crc32": {"L2", "hash"},
+ "hash/crc64": {"L2", "hash"},
+ "hash/fnv": {"L2", "hash"},
+ "image": {"L2", "image/color"}, // interfaces
+ "image/color": {"L2"}, // interfaces
+ "reflect": {"L2"},
+
+ "L3": {
+ "L2",
+ "crypto",
+ "crypto/cipher",
+ "encoding/base32",
+ "encoding/base64",
+ "encoding/binary",
+ "hash",
+ "hash/adler32",
+ "hash/crc32",
+ "hash/crc64",
+ "hash/fnv",
+ "image",
+ "image/color",
+ "reflect",
+ },
+
+ // End of linear dependency definitions.
+
+ // Operating system access.
+ "syscall": {"L0", "unicode/utf16"},
+ "time": {"L0", "syscall"},
+ "os": {"L1", "os", "syscall", "time"},
+ "path/filepath": {"L2", "os", "syscall"},
+ "io/ioutil": {"L2", "os", "path/filepath", "time"},
+ "os/exec": {"L2", "os", "syscall"},
+ "os/signal": {"L2", "os", "syscall"},
+
+ // OS enables basic operating system functionality,
+ // but not direct use of package syscall, nor os/signal.
+ "OS": {
+ "io/ioutil",
+ "os",
+ "os/exec",
+ "path/filepath",
+ "time",
+ },
+
+ // Formatted I/O: few dependencies (L1) but we must add reflect.
+ "fmt": {"L1", "os", "reflect"},
+ "log": {"L1", "os", "fmt", "time"},
+
+ // Packages used by testing must be low-level (L2+fmt).
+ "regexp": {"L2", "regexp/syntax"},
+ "regexp/syntax": {"L2"},
+ "runtime/debug": {"L2", "fmt", "io/ioutil", "os"},
+ "runtime/pprof": {"L2", "fmt", "text/tabwriter"},
+ "text/tabwriter": {"L2"},
+
+ "testing": {"L2", "flag", "fmt", "os", "runtime/pprof", "time"},
+ "testing/iotest": {"L2", "log"},
+ "testing/quick": {"L2", "flag", "fmt", "reflect"},
+
+ // L4 is defined as L3+fmt+log+time, because in general once
+ // you're using L3 packages, use of fmt, log, or time is not a big deal.
+ "L4": {
+ "L3",
+ "fmt",
+ "log",
+ "time",
+ },
+
+ // Go parser.
+ "go/ast": {"L4", "OS", "go/scanner", "go/token"},
+ "go/doc": {"L4", "go/ast", "go/token", "regexp", "text/template"},
+ "go/parser": {"L4", "OS", "go/ast", "go/scanner", "go/token"},
+ "go/printer": {"L4", "OS", "go/ast", "go/scanner", "go/token", "text/tabwriter"},
+ "go/scanner": {"L4", "OS", "go/token"},
+ "go/token": {"L4"},
+
+ "GOPARSER": {
+ "go/ast",
+ "go/doc",
+ "go/parser",
+ "go/printer",
+ "go/scanner",
+ "go/token",
+ },
+
+ // One of a kind.
+ "archive/tar": {"L4", "OS"},
+ "archive/zip": {"L4", "OS", "compress/flate"},
+ "compress/bzip2": {"L4"},
+ "compress/flate": {"L4"},
+ "compress/gzip": {"L4", "compress/flate"},
+ "compress/lzw": {"L4"},
+ "compress/zlib": {"L4", "compress/flate"},
+ "database/sql": {"L4", "database/sql/driver"},
+ "database/sql/driver": {"L4", "time"},
+ "debug/dwarf": {"L4"},
+ "debug/elf": {"L4", "OS", "debug/dwarf"},
+ "debug/gosym": {"L4"},
+ "debug/macho": {"L4", "OS", "debug/dwarf"},
+ "debug/pe": {"L4", "OS", "debug/dwarf"},
+ "encoding/ascii85": {"L4"},
+ "encoding/asn1": {"L4", "math/big"},
+ "encoding/csv": {"L4"},
+ "encoding/gob": {"L4", "OS"},
+ "encoding/hex": {"L4"},
+ "encoding/json": {"L4"},
+ "encoding/pem": {"L4"},
+ "encoding/xml": {"L4"},
+ "flag": {"L4", "OS"},
+ "go/build": {"L4", "OS", "GOPARSER"},
+ "html": {"L4"},
+ "image/draw": {"L4"},
+ "image/gif": {"L4", "compress/lzw"},
+ "image/jpeg": {"L4"},
+ "image/png": {"L4", "compress/zlib"},
+ "index/suffixarray": {"L4", "regexp"},
+ "math/big": {"L4"},
+ "mime": {"L4", "OS", "syscall"},
+ "net/url": {"L4"},
+ "text/scanner": {"L4", "OS"},
+ "text/template/parse": {"L4"},
+
+ "html/template": {
+ "L4", "OS", "encoding/json", "html", "text/template",
+ "text/template/parse",
+ },
+ "text/template": {
+ "L4", "OS", "net/url", "text/template/parse",
+ },
+
+ // Cgo.
+ "runtime/cgo": {"L0", "C"},
+ "CGO": {"C", "runtime/cgo"},
+
+ // Fake entry to satisfy the pseudo-import "C"
+ // that shows up in programs that use cgo.
+ "C": {},
+
+ "os/user": {"L4", "CGO", "syscall"},
+
+ // Basic networking.
+ // Because net must be used by any package that wants to
+ // do networking portably, it must have a small dependency set: just L1+basic os.
+ "net": {"L1", "CGO", "os", "syscall", "time"},
+
+ // NET enables use of basic network-related packages.
+ "NET": {
+ "net",
+ "mime",
+ "net/textproto",
+ "net/url",
+ },
+
+ // Uses of networking.
+ "log/syslog": {"L4", "OS", "net"},
+ "net/mail": {"L4", "NET", "OS"},
+ "net/textproto": {"L4", "OS", "net"},
+
+ // Core crypto.
+ "crypto/aes": {"L3"},
+ "crypto/des": {"L3"},
+ "crypto/hmac": {"L3"},
+ "crypto/md5": {"L3"},
+ "crypto/rc4": {"L3"},
+ "crypto/sha1": {"L3"},
+ "crypto/sha256": {"L3"},
+ "crypto/sha512": {"L3"},
+ "crypto/subtle": {"L3"},
+
+ "CRYPTO": {
+ "crypto/aes",
+ "crypto/des",
+ "crypto/hmac",
+ "crypto/md5",
+ "crypto/rc4",
+ "crypto/sha1",
+ "crypto/sha256",
+ "crypto/sha512",
+ "crypto/subtle",
+ },
+
+ // Random byte, number generation.
+ // This would be part of core crypto except that it imports
+ // math/big, which imports fmt.
+ "crypto/rand": {"L4", "CRYPTO", "OS", "math/big", "syscall"},
+
+ // Mathematical crypto: dependencies on fmt (L4) and math/big.
+ // We could avoid some of the fmt, but math/big imports fmt anyway.
+ "crypto/dsa": {"L4", "CRYPTO", "math/big"},
+ "crypto/ecdsa": {"L4", "CRYPTO", "crypto/elliptic", "math/big"},
+ "crypto/elliptic": {"L4", "CRYPTO", "math/big"},
+ "crypto/rsa": {"L4", "CRYPTO", "crypto/rand", "math/big"},
+
+ "CRYPTO-MATH": {
+ "CRYPTO",
+ "crypto/dsa",
+ "crypto/ecdsa",
+ "crypto/elliptic",
+ "crypto/rand",
+ "crypto/rsa",
+ "encoding/asn1",
+ "math/big",
+ },
+
+ // SSL/TLS.
+ "crypto/tls": {
+ "L4", "CRYPTO-MATH", "CGO", "OS",
+ "crypto/x509", "encoding/pem", "net", "syscall",
+ },
+ "crypto/x509": {"L4", "CRYPTO-MATH", "OS", "CGO", "crypto/x509/pkix", "encoding/pem", "syscall"},
+ "crypto/x509/pkix": {"L4", "CRYPTO-MATH"},
+
+ // Simple net+crypto-aware packages.
+ "mime/multipart": {"L4", "OS", "mime", "crypto/rand", "net/textproto"},
+ "net/smtp": {"L4", "CRYPTO", "NET", "crypto/tls"},
+
+ // HTTP, kingpin of dependencies.
+ "net/http": {
+ "L4", "NET", "OS",
+ "compress/gzip", "crypto/tls", "mime/multipart", "runtime/debug",
+ },
+
+ // HTTP-using packages.
+ "expvar": {"L4", "OS", "encoding/json", "net/http"},
+ "net/http/cgi": {"L4", "NET", "OS", "crypto/tls", "net/http", "regexp"},
+ "net/http/fcgi": {"L4", "NET", "OS", "net/http", "net/http/cgi"},
+ "net/http/httptest": {"L4", "NET", "OS", "crypto/tls", "flag", "net/http"},
+ "net/http/httputil": {"L4", "NET", "OS", "net/http"},
+ "net/http/pprof": {"L4", "OS", "html/template", "net/http", "runtime/pprof"},
+ "net/rpc": {"L4", "NET", "encoding/gob", "net/http", "text/template"},
+ "net/rpc/jsonrpc": {"L4", "NET", "encoding/json", "net/rpc"},
+}
+
+// isMacro reports whether p is a package dependency macro
+// (uppercase name).
+func isMacro(p string) bool {
+ return 'A' <= p[0] && p[0] <= 'Z'
+}
+
+func allowed(pkg string) map[string]bool {
+ m := map[string]bool{}
+ var allow func(string)
+ allow = func(p string) {
+ if m[p] {
+ return
+ }
+ m[p] = true // set even for macros, to avoid loop on cycle
+
+ // Upper-case names are macro-expanded.
+ if isMacro(p) {
+ for _, pp := range pkgDeps[p] {
+ allow(pp)
+ }
+ }
+ }
+ for _, pp := range pkgDeps[pkg] {
+ allow(pp)
+ }
+ return m
+}
+
+var bools = []bool{false, true}
+var geese = []string{"darwin", "freebsd", "linux", "netbsd", "openbsd", "plan9", "windows"}
+var goarches = []string{"386", "amd64", "arm"}
+
+type osPkg struct {
+ goos, pkg string
+}
+
+// allowedErrors are the operating systems and packages known to contain errors
+// (currently just "no Go source files")
+var allowedErrors = map[osPkg]bool{
+ osPkg{"windows", "log/syslog"}: true,
+ osPkg{"plan9", "log/syslog"}: true,
+}
+
+func TestDependencies(t *testing.T) {
+ var all []string
+
+ for k := range pkgDeps {
+ all = append(all, k)
+ }
+ sort.Strings(all)
+
+ ctxt := build.Default
+ test := func(mustImport bool) {
+ for _, pkg := range all {
+ if isMacro(pkg) {
+ continue
+ }
+ p, err := ctxt.Import(pkg, "", 0)
+ if err != nil {
+ if allowedErrors[osPkg{ctxt.GOOS, pkg}] {
+ continue
+ }
+ // Some of the combinations we try might not
+ // be reasonable (like arm,plan9,cgo), so ignore
+ // errors for the auto-generated combinations.
+ if !mustImport {
+ continue
+ }
+ t.Errorf("%s/%s/cgo=%v %v", ctxt.GOOS, ctxt.GOARCH, ctxt.CgoEnabled, err)
+ continue
+ }
+ ok := allowed(pkg)
+ var bad []string
+ for _, imp := range p.Imports {
+ if !ok[imp] {
+ bad = append(bad, imp)
+ }
+ }
+ if bad != nil {
+ t.Errorf("%s/%s/cgo=%v unexpected dependency: %s imports %v", ctxt.GOOS, ctxt.GOARCH, ctxt.CgoEnabled, pkg, bad)
+ }
+ }
+ }
+ test(true)
+
+ if testing.Short() {
+ t.Logf("skipping other systems")
+ return
+ }
+
+ for _, ctxt.GOOS = range geese {
+ for _, ctxt.GOARCH = range goarches {
+ for _, ctxt.CgoEnabled = range bools {
+ test(false)
+ }
+ }
+ }
+}
diff --git a/libgo/go/go/parser/error_test.go b/libgo/go/go/parser/error_test.go
new file mode 100644
index 00000000000..377c8b80cba
--- /dev/null
+++ b/libgo/go/go/parser/error_test.go
@@ -0,0 +1,166 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements a parser test harness. The files in the testdata
+// directory are parsed and the errors reported are compared against the
+// error messages expected in the test files. The test files must end in
+// .src rather than .go so that they are not disturbed by gofmt runs.
+//
+// Expected errors are indicated in the test files by putting a comment
+// of the form /* ERROR "rx" */ immediately following an offending token.
+// The harness will verify that an error matching the regular expression
+// rx is reported at that source position.
+//
+// For instance, the following test file indicates that a "not declared"
+// error should be reported for the undeclared variable x:
+//
+// package p
+// func f() {
+// _ = x /* ERROR "not declared" */ + 1
+// }
+
+package parser
+
+import (
+ "go/scanner"
+ "go/token"
+ "io/ioutil"
+ "path/filepath"
+ "regexp"
+ "strings"
+ "testing"
+)
+
+const testdata = "testdata"
+
+// getFile assumes that each filename occurs at most once
+func getFile(filename string) (file *token.File) {
+ fset.Iterate(func(f *token.File) bool {
+ if f.Name() == filename {
+ if file != nil {
+ panic(filename + " used multiple times")
+ }
+ file = f
+ }
+ return true
+ })
+ return file
+}
+
+func getPos(filename string, offset int) token.Pos {
+ if f := getFile(filename); f != nil {
+ return f.Pos(offset)
+ }
+ return token.NoPos
+}
+
+// ERROR comments must be of the form /* ERROR "rx" */ and rx is
+// a regular expression that matches the expected error message.
+//
+var errRx = regexp.MustCompile(`^/\* *ERROR *"([^"]*)" *\*/$`)
+
+// expectedErrors collects the regular expressions of ERROR comments found
+// in files and returns them as a map of error positions to error messages.
+//
+func expectedErrors(t *testing.T, filename string, src []byte) map[token.Pos]string {
+ errors := make(map[token.Pos]string)
+
+ var s scanner.Scanner
+ // file was parsed already - do not add it again to the file
+ // set otherwise the position information returned here will
+ // not match the position information collected by the parser
+ s.Init(getFile(filename), src, nil, scanner.ScanComments)
+ var prev token.Pos // position of last non-comment, non-semicolon token
+
+ for {
+ pos, tok, lit := s.Scan()
+ switch tok {
+ case token.EOF:
+ return errors
+ case token.COMMENT:
+ s := errRx.FindStringSubmatch(lit)
+ if len(s) == 2 {
+ errors[prev] = string(s[1])
+ }
+ default:
+ prev = pos
+ }
+ }
+
+ panic("unreachable")
+}
+
+// compareErrors compares the map of expected error messages with the list
+// of found errors and reports discrepancies.
+//
+func compareErrors(t *testing.T, expected map[token.Pos]string, found scanner.ErrorList) {
+ for _, error := range found {
+ // error.Pos is a token.Position, but we want
+ // a token.Pos so we can do a map lookup
+ pos := getPos(error.Pos.Filename, error.Pos.Offset)
+ if msg, found := expected[pos]; found {
+ // we expect a message at pos; check if it matches
+ rx, err := regexp.Compile(msg)
+ if err != nil {
+ t.Errorf("%s: %v", error.Pos, err)
+ continue
+ }
+ if match := rx.MatchString(error.Msg); !match {
+ t.Errorf("%s: %q does not match %q", error.Pos, error.Msg, msg)
+ continue
+ }
+ // we have a match - eliminate this error
+ delete(expected, pos)
+ } else {
+ // To keep in mind when analyzing failed test output:
+ // If the same error position occurs multiple times in errors,
+ // this message will be triggered (because the first error at
+ // the position removes this position from the expected errors).
+ t.Errorf("%s: unexpected error: %s", error.Pos, error.Msg)
+ }
+ }
+
+ // there should be no expected errors left
+ if len(expected) > 0 {
+ t.Errorf("%d errors not reported:", len(expected))
+ for pos, msg := range expected {
+ t.Errorf("%s: %s\n", fset.Position(pos), msg)
+ }
+ }
+}
+
+func checkErrors(t *testing.T, filename string, input interface{}) {
+ src, err := readSource(filename, input)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ _, err = ParseFile(fset, filename, src, DeclarationErrors)
+ found, ok := err.(scanner.ErrorList)
+ if err != nil && !ok {
+ t.Error(err)
+ return
+ }
+
+ // we are expecting the following errors
+ // (collect these after parsing a file so that it is found in the file set)
+ expected := expectedErrors(t, filename, src)
+
+ // verify errors returned by the parser
+ compareErrors(t, expected, found)
+}
+
+func TestErrors(t *testing.T) {
+ list, err := ioutil.ReadDir(testdata)
+ if err != nil {
+ t.Fatal(err)
+ }
+ for _, fi := range list {
+ name := fi.Name()
+ if !fi.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".src") {
+ checkErrors(t, filepath.Join(testdata, name), nil)
+ }
+ }
+}
diff --git a/libgo/go/go/parser/parser.go b/libgo/go/go/parser/parser.go
index a122baf0879..e362e13a7b6 100644
--- a/libgo/go/go/parser/parser.go
+++ b/libgo/go/go/parser/parser.go
@@ -40,6 +40,13 @@ type parser struct {
tok token.Token // one token look-ahead
lit string // token literal
+ // Error recovery
+ // (used to limit the number of calls to syncXXX functions
+ // w/o making scanning progress - avoids potential endless
+ // loops across multiple parser functions during error recovery)
+ syncPos token.Pos // last synchronization position
+ syncCnt int // number of calls to syncXXX without progress
+
// Non-syntactic parser control
exprLev int // < 0: in control clause, >= 0: in expression
@@ -362,18 +369,36 @@ func (p *parser) expect(tok token.Token) token.Pos {
// expectClosing is like expect but provides a better error message
// for the common case of a missing comma before a newline.
//
-func (p *parser) expectClosing(tok token.Token, construct string) token.Pos {
+func (p *parser) expectClosing(tok token.Token, context string) token.Pos {
if p.tok != tok && p.tok == token.SEMICOLON && p.lit == "\n" {
- p.error(p.pos, "missing ',' before newline in "+construct)
+ p.error(p.pos, "missing ',' before newline in "+context)
p.next()
}
return p.expect(tok)
}
func (p *parser) expectSemi() {
+ // semicolon is optional before a closing ')' or '}'
if p.tok != token.RPAREN && p.tok != token.RBRACE {
- p.expect(token.SEMICOLON)
+ if p.tok == token.SEMICOLON {
+ p.next()
+ } else {
+ p.errorExpected(p.pos, "';'")
+ syncStmt(p)
+ }
+ }
+}
+
+func (p *parser) atComma(context string) bool {
+ if p.tok == token.COMMA {
+ return true
+ }
+ if p.tok == token.SEMICOLON && p.lit == "\n" {
+ p.error(p.pos, "missing ',' before newline in "+context)
+ return true // "insert" the comma and continue
+
}
+ return false
}
func assert(cond bool, msg string) {
@@ -382,6 +407,68 @@ func assert(cond bool, msg string) {
}
}
+// syncStmt advances to the next statement.
+// Used for synchronization after an error.
+//
+func syncStmt(p *parser) {
+ for {
+ switch p.tok {
+ case token.BREAK, token.CONST, token.CONTINUE, token.DEFER,
+ token.FALLTHROUGH, token.FOR, token.GO, token.GOTO,
+ token.IF, token.RETURN, token.SELECT, token.SWITCH,
+ token.TYPE, token.VAR:
+ // Return only if parser made some progress since last
+ // sync or if it has not reached 10 sync calls without
+ // progress. Otherwise consume at least one token to
+ // avoid an endless parser loop (it is possible that
+ // both parseOperand and parseStmt call syncStmt and
+ // correctly do not advance, thus the need for the
+ // invocation limit p.syncCnt).
+ if p.pos == p.syncPos && p.syncCnt < 10 {
+ p.syncCnt++
+ return
+ }
+ if p.pos > p.syncPos {
+ p.syncPos = p.pos
+ p.syncCnt = 0
+ return
+ }
+ // Reaching here indicates a parser bug, likely an
+ // incorrect token list in this function, but it only
+ // leads to skipping of possibly correct code if a
+ // previous error is present, and thus is preferred
+ // over a non-terminating parse.
+ case token.EOF:
+ return
+ }
+ p.next()
+ }
+}
+
+// syncDecl advances to the next declaration.
+// Used for synchronization after an error.
+//
+func syncDecl(p *parser) {
+ for {
+ switch p.tok {
+ case token.CONST, token.TYPE, token.VAR:
+ // see comments in syncStmt
+ if p.pos == p.syncPos && p.syncCnt < 10 {
+ p.syncCnt++
+ return
+ }
+ if p.pos > p.syncPos {
+ p.syncPos = p.pos
+ p.syncCnt = 0
+ return
+ }
+ case token.EOF:
+ return
+ }
+ p.next()
+ }
+}
+
// ----------------------------------------------------------------------------
// Identifiers
@@ -522,9 +609,11 @@ func (p *parser) makeIdentList(list []ast.Expr) []*ast.Ident {
for i, x := range list {
ident, isIdent := x.(*ast.Ident)
if !isIdent {
- pos := x.Pos()
- p.errorExpected(pos, "identifier")
- ident = &ast.Ident{NamePos: pos, Name: "_"}
+ if _, isBad := x.(*ast.BadExpr); !isBad {
+ // only report error if it's a new one
+ p.errorExpected(x.Pos(), "identifier")
+ }
+ ident = &ast.Ident{NamePos: x.Pos(), Name: "_"}
}
idents[i] = ident
}
@@ -688,7 +777,7 @@ func (p *parser) parseParameterList(scope *ast.Scope, ellipsisOk bool) (params [
// Go spec: The scope of an identifier denoting a function
// parameter or result variable is the function body.
p.declare(field, nil, scope, ast.Var, idents...)
- if p.tok != token.COMMA {
+ if !p.atComma("parameter list") {
break
}
p.next()
@@ -991,19 +1080,19 @@ func (p *parser) parseOperand(lhs bool) ast.Expr {
case token.FUNC:
return p.parseFuncTypeOrLit()
+ }
- default:
- if typ := p.tryIdentOrType(true); typ != nil {
- // could be type for composite literal or conversion
- _, isIdent := typ.(*ast.Ident)
- assert(!isIdent, "type cannot be identifier")
- return typ
- }
+ if typ := p.tryIdentOrType(true); typ != nil {
+ // could be type for composite literal or conversion
+ _, isIdent := typ.(*ast.Ident)
+ assert(!isIdent, "type cannot be identifier")
+ return typ
}
+ // we have an error
pos := p.pos
p.errorExpected(pos, "operand")
- p.next() // make progress
+ syncStmt(p)
return &ast.BadExpr{From: pos, To: p.pos}
}
@@ -1078,7 +1167,7 @@ func (p *parser) parseCallOrConversion(fun ast.Expr) *ast.CallExpr {
ellipsis = p.pos
p.next()
}
- if p.tok != token.COMMA {
+ if !p.atComma("argument list") {
break
}
p.next()
@@ -1118,7 +1207,7 @@ func (p *parser) parseElementList() (list []ast.Expr) {
for p.tok != token.RBRACE && p.tok != token.EOF {
list = append(list, p.parseElement(true))
- if p.tok != token.COMMA {
+ if !p.atComma("composite literal") {
break
}
p.next()
@@ -1262,8 +1351,8 @@ L:
x = p.parseTypeAssertion(p.checkExpr(x))
default:
pos := p.pos
- p.next() // make progress
p.errorExpected(pos, "selector or type assertion")
+ p.next() // make progress
x = &ast.BadExpr{From: pos, To: p.pos}
}
case token.LBRACK:
@@ -1471,7 +1560,10 @@ func (p *parser) parseCallExpr() *ast.CallExpr {
if call, isCall := x.(*ast.CallExpr); isCall {
return call
}
- p.errorExpected(x.Pos(), "function/method call")
+ if _, isBad := x.(*ast.BadExpr); !isBad {
+ // only report error if it's a new one
+ p.errorExpected(x.Pos(), "function/method call")
+ }
return nil
}
@@ -1862,7 +1954,7 @@ func (p *parser) parseStmt() (s ast.Stmt) {
switch p.tok {
case token.CONST, token.TYPE, token.VAR:
- s = &ast.DeclStmt{Decl: p.parseDecl()}
+ s = &ast.DeclStmt{Decl: p.parseDecl(syncStmt)}
case
// tokens that may start an expression
token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING, token.FUNC, token.LPAREN, // operands
@@ -1904,7 +1996,7 @@ func (p *parser) parseStmt() (s ast.Stmt) {
// no statement found
pos := p.pos
p.errorExpected(pos, "statement")
- p.next() // make progress
+ syncStmt(p)
s = &ast.BadStmt{From: pos, To: p.pos}
}
@@ -2095,8 +2187,13 @@ func (p *parser) parseReceiver(scope *ast.Scope) *ast.FieldList {
recv := par.List[0]
base := deref(recv.Type)
if _, isIdent := base.(*ast.Ident); !isIdent {
- p.errorExpected(base.Pos(), "(unqualified) identifier")
- par.List = []*ast.Field{{Type: &ast.BadExpr{From: recv.Pos(), To: recv.End()}}}
+ if _, isBad := base.(*ast.BadExpr); !isBad {
+ // only report error if it's a new one
+ p.errorExpected(base.Pos(), "(unqualified) identifier")
+ }
+ par.List = []*ast.Field{
+ {Type: &ast.BadExpr{From: recv.Pos(), To: recv.End()}},
+ }
}
return par
@@ -2152,7 +2249,7 @@ func (p *parser) parseFuncDecl() *ast.FuncDecl {
return decl
}
-func (p *parser) parseDecl() ast.Decl {
+func (p *parser) parseDecl(sync func(*parser)) ast.Decl {
if p.trace {
defer un(trace(p, "Declaration"))
}
@@ -2174,9 +2271,8 @@ func (p *parser) parseDecl() ast.Decl {
default:
pos := p.pos
p.errorExpected(pos, "declaration")
- p.next() // make progress
- decl := &ast.BadDecl{From: pos, To: p.pos}
- return decl
+ sync(p)
+ return &ast.BadDecl{From: pos, To: p.pos}
}
return p.parseGenDecl(p.tok, f)
@@ -2215,7 +2311,7 @@ func (p *parser) parseFile() *ast.File {
if p.mode&ImportsOnly == 0 {
// rest of package body
for p.tok != token.EOF {
- decls = append(decls, p.parseDecl())
+ decls = append(decls, p.parseDecl(syncDecl))
}
}
}
diff --git a/libgo/go/go/parser/parser_test.go b/libgo/go/go/parser/parser_test.go
index 93ca3d6aa39..5e45acd007a 100644
--- a/libgo/go/go/parser/parser_test.go
+++ b/libgo/go/go/parser/parser_test.go
@@ -14,87 +14,14 @@ import (
var fset = token.NewFileSet()
-var illegalInputs = []interface{}{
- nil,
- 3.14,
- []byte(nil),
- "foo!",
- `package p; func f() { if /* should have condition */ {} };`,
- `package p; func f() { if ; /* should have condition */ {} };`,
- `package p; func f() { if f(); /* should have condition */ {} };`,
- `package p; const c; /* should have constant value */`,
- `package p; func f() { if _ = range x; true {} };`,
- `package p; func f() { switch _ = range x; true {} };`,
- `package p; func f() { for _ = range x ; ; {} };`,
- `package p; func f() { for ; ; _ = range x {} };`,
- `package p; func f() { for ; _ = range x ; {} };`,
- `package p; func f() { switch t = t.(type) {} };`,
- `package p; func f() { switch t, t = t.(type) {} };`,
- `package p; func f() { switch t = t.(type), t {} };`,
- `package p; var a = [1]int; /* illegal expression */`,
- `package p; var a = [...]int; /* illegal expression */`,
- `package p; var a = struct{} /* illegal expression */`,
- `package p; var a = func(); /* illegal expression */`,
- `package p; var a = interface{} /* illegal expression */`,
- `package p; var a = []int /* illegal expression */`,
- `package p; var a = map[int]int /* illegal expression */`,
- `package p; var a = chan int; /* illegal expression */`,
- `package p; var a = []int{[]int}; /* illegal expression */`,
- `package p; var a = ([]int); /* illegal expression */`,
- `package p; var a = a[[]int:[]int]; /* illegal expression */`,
- `package p; var a = <- chan int; /* illegal expression */`,
- `package p; func f() { select { case _ <- chan int: } };`,
-}
-
-func TestParseIllegalInputs(t *testing.T) {
- for _, src := range illegalInputs {
- _, err := ParseFile(fset, "", src, 0)
- if err == nil {
- t.Errorf("ParseFile(%v) should have failed", src)
- }
- }
-}
-
-var validPrograms = []string{
- "package p\n",
- `package p;`,
- `package p; import "fmt"; func f() { fmt.Println("Hello, World!") };`,
- `package p; func f() { if f(T{}) {} };`,
- `package p; func f() { _ = (<-chan int)(x) };`,
- `package p; func f() { _ = (<-chan <-chan int)(x) };`,
- `package p; func f(func() func() func());`,
- `package p; func f(...T);`,
- `package p; func f(float, ...int);`,
- `package p; func f(x int, a ...int) { f(0, a...); f(1, a...,) };`,
- `package p; func f(int,) {};`,
- `package p; func f(...int,) {};`,
- `package p; func f(x ...int,) {};`,
- `package p; type T []int; var a []bool; func f() { if a[T{42}[0]] {} };`,
- `package p; type T []int; func g(int) bool { return true }; func f() { if g(T{42}[0]) {} };`,
- `package p; type T []int; func f() { for _ = range []int{T{42}[0]} {} };`,
- `package p; var a = T{{1, 2}, {3, 4}}`,
- `package p; func f() { select { case <- c: case c <- d: case c <- <- d: case <-c <- d: } };`,
- `package p; func f() { select { case x := (<-c): } };`,
- `package p; func f() { if ; true {} };`,
- `package p; func f() { switch ; {} };`,
- `package p; func f() { for _ = range "foo" + "bar" {} };`,
-}
-
-func TestParseValidPrograms(t *testing.T) {
- for _, src := range validPrograms {
- _, err := ParseFile(fset, "", src, SpuriousErrors)
- if err != nil {
- t.Errorf("ParseFile(%q): %v", src, err)
- }
- }
-}
-
var validFiles = []string{
"parser.go",
"parser_test.go",
+ "error_test.go",
+ "short_test.go",
}
-func TestParse3(t *testing.T) {
+func TestParse(t *testing.T) {
for _, filename := range validFiles {
_, err := ParseFile(fset, filename, nil, DeclarationErrors)
if err != nil {
@@ -116,7 +43,7 @@ func nameFilter(filename string) bool {
func dirFilter(f os.FileInfo) bool { return nameFilter(f.Name()) }
-func TestParse4(t *testing.T) {
+func TestParseDir(t *testing.T) {
path := "."
pkgs, err := ParseDir(fset, path, dirFilter, 0)
if err != nil {
@@ -158,7 +85,7 @@ func TestParseExpr(t *testing.T) {
}
// it must not crash
- for _, src := range validPrograms {
+ for _, src := range valids {
ParseExpr(src)
}
}
diff --git a/libgo/go/go/parser/short_test.go b/libgo/go/go/parser/short_test.go
new file mode 100644
index 00000000000..238492bf3f7
--- /dev/null
+++ b/libgo/go/go/parser/short_test.go
@@ -0,0 +1,75 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains test cases for short valid and invalid programs.
+
+package parser
+
+import "testing"
+
+var valids = []string{
+ "package p\n",
+ `package p;`,
+ `package p; import "fmt"; func f() { fmt.Println("Hello, World!") };`,
+ `package p; func f() { if f(T{}) {} };`,
+ `package p; func f() { _ = (<-chan int)(x) };`,
+ `package p; func f() { _ = (<-chan <-chan int)(x) };`,
+ `package p; func f(func() func() func());`,
+ `package p; func f(...T);`,
+ `package p; func f(float, ...int);`,
+ `package p; func f(x int, a ...int) { f(0, a...); f(1, a...,) };`,
+ `package p; func f(int,) {};`,
+ `package p; func f(...int,) {};`,
+ `package p; func f(x ...int,) {};`,
+ `package p; type T []int; var a []bool; func f() { if a[T{42}[0]] {} };`,
+ `package p; type T []int; func g(int) bool { return true }; func f() { if g(T{42}[0]) {} };`,
+ `package p; type T []int; func f() { for _ = range []int{T{42}[0]} {} };`,
+ `package p; var a = T{{1, 2}, {3, 4}}`,
+ `package p; func f() { select { case <- c: case c <- d: case c <- <- d: case <-c <- d: } };`,
+ `package p; func f() { select { case x := (<-c): } };`,
+ `package p; func f() { if ; true {} };`,
+ `package p; func f() { switch ; {} };`,
+ `package p; func f() { for _ = range "foo" + "bar" {} };`,
+}
+
+func TestValid(t *testing.T) {
+ for _, src := range valids {
+ checkErrors(t, src, src)
+ }
+}
+
+var invalids = []string{
+ `foo /* ERROR "expected 'package'" */ !`,
+ `package p; func f() { if { /* ERROR "expected operand" */ } };`,
+ `package p; func f() { if ; { /* ERROR "expected operand" */ } };`,
+ `package p; func f() { if f(); { /* ERROR "expected operand" */ } };`,
+ `package p; const c; /* ERROR "expected '='" */`,
+ `package p; func f() { if _ /* ERROR "expected condition" */ = range x; true {} };`,
+ `package p; func f() { switch _ /* ERROR "expected condition" */ = range x; true {} };`,
+ `package p; func f() { for _ = range x ; /* ERROR "expected '{'" */ ; {} };`,
+ `package p; func f() { for ; ; _ = range /* ERROR "expected operand" */ x {} };`,
+ `package p; func f() { for ; _ /* ERROR "expected condition" */ = range x ; {} };`,
+ `package p; func f() { switch t /* ERROR "expected condition" */ = t.(type) {} };`,
+ `package p; func f() { switch t /* ERROR "expected condition" */ , t = t.(type) {} };`,
+ `package p; func f() { switch t /* ERROR "expected condition" */ = t.(type), t {} };`,
+ `package p; var a = [ /* ERROR "expected expression" */ 1]int;`,
+ `package p; var a = [ /* ERROR "expected expression" */ ...]int;`,
+ `package p; var a = struct /* ERROR "expected expression" */ {}`,
+ `package p; var a = func /* ERROR "expected expression" */ ();`,
+ `package p; var a = interface /* ERROR "expected expression" */ {}`,
+ `package p; var a = [ /* ERROR "expected expression" */ ]int`,
+ `package p; var a = map /* ERROR "expected expression" */ [int]int`,
+ `package p; var a = chan /* ERROR "expected expression" */ int;`,
+ `package p; var a = []int{[ /* ERROR "expected expression" */ ]int};`,
+ `package p; var a = ( /* ERROR "expected expression" */ []int);`,
+ `package p; var a = a[[ /* ERROR "expected expression" */ ]int:[]int];`,
+ `package p; var a = <- /* ERROR "expected expression" */ chan int;`,
+ `package p; func f() { select { case _ <- chan /* ERROR "expected expression" */ int: } };`,
+}
+
+func TestInvalid(t *testing.T) {
+ for _, src := range invalids {
+ checkErrors(t, src, src)
+ }
+}
diff --git a/libgo/go/go/parser/testdata/commas.src b/libgo/go/go/parser/testdata/commas.src
new file mode 100644
index 00000000000..af6e7064506
--- /dev/null
+++ b/libgo/go/go/parser/testdata/commas.src
@@ -0,0 +1,19 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test case for error messages/parser synchronization
+// after missing commas.
+
+package p
+
+var _ = []int{
+ 0 /* ERROR "missing ','" */
+}
+
+var _ = []int{
+ 0,
+ 1,
+ 2,
+ 3 /* ERROR "missing ','" */
+}
diff --git a/libgo/go/go/parser/testdata/issue3106.src b/libgo/go/go/parser/testdata/issue3106.src
new file mode 100644
index 00000000000..82796c8ceb6
--- /dev/null
+++ b/libgo/go/go/parser/testdata/issue3106.src
@@ -0,0 +1,46 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test case for issue 3106: Better synchronization of
+// parser after certain syntax errors.
+
+package main
+
+func f() {
+ var m Mutex
+ c := MakeCond(&m)
+ percent := 0
+ const step = 10
+ for i := 0; i < 5; i++ {
+ go func() {
+ for {
+ // Emulates some useful work.
+ time.Sleep(1e8)
+ m.Lock()
+ defer
+ if /* ERROR "expected operand, found 'if'" */ percent == 100 {
+ m.Unlock()
+ break
+ }
+ percent++
+ if percent % step == 0 {
+ //c.Signal()
+ }
+ m.Unlock()
+ }
+ }()
+ }
+ for {
+ m.Lock()
+ if percent == 0 || percent % step != 0 {
+ c.Wait()
+ }
+ fmt.Print(",")
+ if percent == 100 {
+ m.Unlock()
+ break
+ }
+ m.Unlock()
+ }
+}
diff --git a/libgo/go/go/printer/nodes.go b/libgo/go/go/printer/nodes.go
index 05b4ef59a2d..727d2a37147 100644
--- a/libgo/go/go/printer/nodes.go
+++ b/libgo/go/go/printer/nodes.go
@@ -15,7 +15,7 @@ import (
"unicode/utf8"
)
-// Other formatting issues:
+// Formatting issues:
// - better comment formatting for /*-style comments at the end of a line (e.g. a declaration)
// when the comment spans multiple lines; if such a comment is just two lines, formatting is
// not idempotent
@@ -365,7 +365,7 @@ func (p *printer) setLineComment(text string) {
}
func (p *printer) isMultiLine(n ast.Node) bool {
- return p.lineFor(n.End())-p.lineFor(n.Pos()) > 1
+ return p.lineFor(n.End())-p.lineFor(n.Pos()) > 0
}
func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool) {
@@ -964,6 +964,41 @@ func (p *printer) controlClause(isForStmt bool, init ast.Stmt, expr ast.Expr, po
}
}
+// indentList reports whether an expression list would look better if it
+// were indented wholesale (starting with the very first element, rather
+// than starting at the first line break).
+//
+func (p *printer) indentList(list []ast.Expr) bool {
+ // Heuristic: indentList returns true if there are more than one multi-
+ // line element in the list, or if there is any element that is not
+ // starting on the same line as the previous one ends.
+ if len(list) >= 2 {
+ var b = p.lineFor(list[0].Pos())
+ var e = p.lineFor(list[len(list)-1].End())
+ if 0 < b && b < e {
+ // list spans multiple lines
+ n := 0 // multi-line element count
+ line := b
+ for _, x := range list {
+ xb := p.lineFor(x.Pos())
+ xe := p.lineFor(x.End())
+ if line < xb {
+ // x is not starting on the same
+ // line as the previous one ended
+ return true
+ }
+ if xb < xe {
+ // x is a multi-line element
+ n++
+ }
+ line = xe
+ }
+ return n > 1
+ }
+ }
+ return false
+}
+
func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool) {
p.print(stmt.Pos())
@@ -1030,7 +1065,18 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool) {
p.print(token.RETURN)
if s.Results != nil {
p.print(blank)
- p.exprList(s.Pos(), s.Results, 1, 0, token.NoPos)
+ // Use indentList heuristic to make corner cases look
+ // better (issue 1207). A more systematic approach would
+ // always indent, but this would cause significant
+ // reformatting of the code base and not necessarily
+ // lead to more nicely formatted code in general.
+ if p.indentList(s.Results) {
+ p.print(indent)
+ p.exprList(s.Pos(), s.Results, 1, noIndent, token.NoPos)
+ p.print(unindent)
+ } else {
+ p.exprList(s.Pos(), s.Results, 1, 0, token.NoPos)
+ }
}
case *ast.BranchStmt:
@@ -1200,9 +1246,9 @@ func keepTypeColumn(specs []ast.Spec) []bool {
return m
}
-func (p *printer) valueSpec(s *ast.ValueSpec, keepType, doIndent bool) {
+func (p *printer) valueSpec(s *ast.ValueSpec, keepType bool) {
p.setComment(s.Doc)
- p.identList(s.Names, doIndent) // always present
+ p.identList(s.Names, false) // always present
extraTabs := 3
if s.Type != nil || keepType {
p.print(vtab)
@@ -1290,7 +1336,7 @@ func (p *printer) genDecl(d *ast.GenDecl) {
if i > 0 {
p.linebreak(p.lineFor(s.Pos()), 1, ignore, newSection)
}
- p.valueSpec(s.(*ast.ValueSpec), keepType[i], false)
+ p.valueSpec(s.(*ast.ValueSpec), keepType[i])
newSection = p.isMultiLine(s)
}
} else {
diff --git a/libgo/go/go/printer/testdata/declarations.golden b/libgo/go/go/printer/testdata/declarations.golden
index 7ed7cb61ae5..71ed32ed145 100644
--- a/libgo/go/go/printer/testdata/declarations.golden
+++ b/libgo/go/go/printer/testdata/declarations.golden
@@ -500,7 +500,7 @@ type _ struct {
type _ struct {
a, b,
- c, d int // this line should be indented
+ c, d int // this line should be indented
u, v, w, x float // this line should be indented
p, q,
r, s float // this line should be indented
@@ -562,10 +562,21 @@ var a2, b2,
var (
a3, b3,
- c3, d3 int // this line should be indented
+ c3, d3 int // this line should be indented
a4, b4, c4 int // this line should be indented
)
+// Test case from issue 3304: multi-line declarations must end
+// a formatting section and not influence indentation of the
+// next line.
+var (
+ minRefreshTimeSec = flag.Int64("min_refresh_time_sec", 604800,
+ "minimum time window between two refreshes for a given user.")
+ x = flag.Int64("refresh_user_rollout_percent", 100,
+ "temporary flag to ramp up the refresh user rpc")
+ aVeryLongVariableName = stats.GetVarInt("refresh-user-count")
+)
+
func _() {
var privateKey2 = &Block{Type: "RSA PRIVATE KEY",
Headers: map[string]string{},
diff --git a/libgo/go/go/printer/testdata/declarations.input b/libgo/go/go/printer/testdata/declarations.input
index df8c2b167e1..d74cff25d1f 100644
--- a/libgo/go/go/printer/testdata/declarations.input
+++ b/libgo/go/go/printer/testdata/declarations.input
@@ -577,6 +577,16 @@ c3, d3 int // this line should be indented
a4, b4, c4 int // this line should be indented
)
+// Test case from issue 3304: multi-line declarations must end
+// a formatting section and not influence indentation of the
+// next line.
+var (
+ minRefreshTimeSec = flag.Int64("min_refresh_time_sec", 604800,
+ "minimum time window between two refreshes for a given user.")
+ x = flag.Int64("refresh_user_rollout_percent", 100,
+ "temporary flag to ramp up the refresh user rpc")
+ aVeryLongVariableName = stats.GetVarInt("refresh-user-count")
+)
func _() {
var privateKey2 = &Block{Type: "RSA PRIVATE KEY",
diff --git a/libgo/go/go/printer/testdata/statements.golden b/libgo/go/go/printer/testdata/statements.golden
index ffca21edba9..4d70617bf13 100644
--- a/libgo/go/go/printer/testdata/statements.golden
+++ b/libgo/go/go/printer/testdata/statements.golden
@@ -55,12 +55,24 @@ func _f() {
return T{
1,
2,
- },
+ }, nil
+ return T{
+ 1,
+ 2,
+ },
+ T{
+ x: 3,
+ y: 4,
+ }, nil
+ return T{
+ 1,
+ 2,
+ },
nil
return T{
- 1,
- 2,
- },
+ 1,
+ 2,
+ },
T{
x: 3,
y: 4,
@@ -70,10 +82,10 @@ func _f() {
z
return func() {}
return func() {
- _ = 0
- }, T{
- 1, 2,
- }
+ _ = 0
+ }, T{
+ 1, 2,
+ }
return func() {
_ = 0
}
@@ -84,6 +96,37 @@ func _f() {
}
}
+// Formatting of multi-line returns: test cases from issue 1207.
+func F() (*T, os.Error) {
+ return &T{
+ X: 1,
+ Y: 2,
+ },
+ nil
+}
+
+func G() (*T, *T, os.Error) {
+ return &T{
+ X: 1,
+ Y: 2,
+ },
+ &T{
+ X: 3,
+ Y: 4,
+ },
+ nil
+}
+
+func _() interface{} {
+ return &fileStat{
+ name: basename(file.name),
+ size: mkSize(d.FileSizeHigh, d.FileSizeLow),
+ modTime: mkModTime(d.LastWriteTime),
+ mode: mkMode(d.FileAttributes),
+ sys: mkSysFromFI(&d),
+ }, nil
+}
+
// Formatting of if-statement headers.
func _() {
if true {
diff --git a/libgo/go/go/printer/testdata/statements.input b/libgo/go/go/printer/testdata/statements.input
index 99945e9551a..bd03bc98b77 100644
--- a/libgo/go/go/printer/testdata/statements.input
+++ b/libgo/go/go/printer/testdata/statements.input
@@ -55,6 +55,18 @@ func _f() {
return T{
1,
2,
+ }, nil
+ return T{
+ 1,
+ 2,
+ },
+ T{
+ x: 3,
+ y: 4,
+ }, nil
+ return T{
+ 1,
+ 2,
},
nil
return T{
@@ -84,6 +96,37 @@ func _f() {
}
}
+// Formatting of multi-line returns: test cases from issue 1207.
+func F() (*T, os.Error) {
+ return &T{
+ X: 1,
+ Y: 2,
+ },
+ nil
+}
+
+func G() (*T, *T, os.Error) {
+ return &T{
+ X: 1,
+ Y: 2,
+ },
+ &T{
+ X: 3,
+ Y: 4,
+ },
+ nil
+}
+
+func _() interface{} {
+ return &fileStat{
+ name: basename(file.name),
+ size: mkSize(d.FileSizeHigh, d.FileSizeLow),
+ modTime: mkModTime(d.LastWriteTime),
+ mode: mkMode(d.FileAttributes),
+ sys: mkSysFromFI(&d),
+ }, nil
+}
+
// Formatting of if-statement headers.
func _() {
if true {}
diff --git a/libgo/go/go/scanner/scanner.go b/libgo/go/go/scanner/scanner.go
index 2395363b0ec..da508747a6d 100644
--- a/libgo/go/go/scanner/scanner.go
+++ b/libgo/go/go/scanner/scanner.go
@@ -109,7 +109,7 @@ const (
func (s *Scanner) Init(file *token.File, src []byte, err ErrorHandler, mode Mode) {
// Explicitly initialize all fields since a scanner may be reused.
if file.Size() != len(src) {
- panic("file size does not match src len")
+ panic(fmt.Sprintf("file size (%d) does not match src len (%d)", file.Size(), len(src)))
}
s.file = file
s.dir, _ = filepath.Split(file.Name())
diff --git a/libgo/go/html/template/clone_test.go b/libgo/go/html/template/clone_test.go
index c612775d4f0..2663cddc24b 100644
--- a/libgo/go/html/template/clone_test.go
+++ b/libgo/go/html/template/clone_test.go
@@ -113,3 +113,36 @@ func TestClone(t *testing.T) {
t.Errorf("t3: got %q want %q", got, want)
}
}
+
+func TestTemplates(t *testing.T) {
+ names := []string{"t0", "a", "lhs", "rhs"}
+ // Some template definitions borrowed from TestClone.
+ const tmpl = `
+ {{define "a"}}{{template "lhs"}}{{.}}{{template "rhs"}}{{end}}
+ {{define "lhs"}} <a href=" {{end}}
+ {{define "rhs"}} "></a> {{end}}`
+ t0 := Must(New("t0").Parse(tmpl))
+ templates := t0.Templates()
+ if len(templates) != len(names) {
+ t.Errorf("expected %d templates; got %d", len(names), len(templates))
+ }
+ for _, name := range names {
+ found := false
+ for _, tmpl := range templates {
+ if name == tmpl.text.Name() {
+ found = true
+ break
+ }
+ }
+ if !found {
+ t.Error("could not find template", name)
+ }
+ }
+}
+
+// This used to crash; http://golang.org/issue/3281
+func TestCloneCrash(t *testing.T) {
+ t1 := New("all")
+ Must(t1.New("t1").Parse(`{{define "foo"}}foo{{end}}`))
+ t1.Clone()
+}
diff --git a/libgo/go/html/template/content.go b/libgo/go/html/template/content.go
index 539664f9729..c1bd2e4949b 100644
--- a/libgo/go/html/template/content.go
+++ b/libgo/go/html/template/content.go
@@ -26,10 +26,10 @@ type (
HTML string
// HTMLAttr encapsulates an HTML attribute from a trusted source,
- // for example: ` dir="ltr"`.
+ // for example, ` dir="ltr"`.
HTMLAttr string
- // JS encapsulates a known safe EcmaScript5 Expression, or example,
+ // JS encapsulates a known safe EcmaScript5 Expression, for example,
// `(x + y * z())`.
// Template authors are responsible for ensuring that typed expressions
// do not break the intended precedence and that there is no
diff --git a/libgo/go/html/template/doc.go b/libgo/go/html/template/doc.go
index 3699ea1a91c..f470facfd0c 100644
--- a/libgo/go/html/template/doc.go
+++ b/libgo/go/html/template/doc.go
@@ -29,7 +29,7 @@ can be safely embedded in an HTML document. The escaping is contextual, so
actions can appear within JavaScript, CSS, and URI contexts.
The security model used by this package assumes that template authors are
-trusted, while text/template Execute's data parameter is not. More details are
+trusted, while Execute's data parameter is not. More details are
provided below.
Example
diff --git a/libgo/go/html/template/escape.go b/libgo/go/html/template/escape.go
index a058e20d7b3..5f0e28e8c1c 100644
--- a/libgo/go/html/template/escape.go
+++ b/libgo/go/html/template/escape.go
@@ -8,6 +8,7 @@ import (
"bytes"
"fmt"
"html"
+ "io"
"text/template"
"text/template/parse"
)
@@ -751,3 +752,44 @@ func (e *escaper) template(name string) *template.Template {
}
return t
}
+
+// Forwarding functions so that clients need only import this package
+// to reach the general escaping functions of text/template.
+
+// HTMLEscape writes to w the escaped HTML equivalent of the plain text data b.
+func HTMLEscape(w io.Writer, b []byte) {
+ template.HTMLEscape(w, b)
+}
+
+// HTMLEscapeString returns the escaped HTML equivalent of the plain text data s.
+func HTMLEscapeString(s string) string {
+ return template.HTMLEscapeString(s)
+}
+
+// HTMLEscaper returns the escaped HTML equivalent of the textual
+// representation of its arguments.
+func HTMLEscaper(args ...interface{}) string {
+ return template.HTMLEscaper(args...)
+}
+
+// JSEscape writes to w the escaped JavaScript equivalent of the plain text data b.
+func JSEscape(w io.Writer, b []byte) {
+ template.JSEscape(w, b)
+}
+
+// JSEscapeString returns the escaped JavaScript equivalent of the plain text data s.
+func JSEscapeString(s string) string {
+ return template.JSEscapeString(s)
+}
+
+// JSEscaper returns the escaped JavaScript equivalent of the textual
+// representation of its arguments.
+func JSEscaper(args ...interface{}) string {
+ return template.JSEscaper(args...)
+}
+
+// URLQueryEscaper returns the escaped value of the textual representation of
+// its arguments in a form suitable for embedding in a URL query.
+func URLQueryEscaper(args ...interface{}) string {
+ return template.URLQueryEscaper(args...)
+}
diff --git a/libgo/go/html/template/escape_test.go b/libgo/go/html/template/escape_test.go
index 2bbb1b1bc94..ce12c1795c2 100644
--- a/libgo/go/html/template/escape_test.go
+++ b/libgo/go/html/template/escape_test.go
@@ -8,6 +8,7 @@ import (
"bytes"
"encoding/json"
"fmt"
+ "os"
"strings"
"testing"
"text/template"
@@ -1637,6 +1638,14 @@ func TestIndirectPrint(t *testing.T) {
}
}
+// This is a test for issue 3272.
+func TestEmptyTemplate(t *testing.T) {
+ page := Must(New("page").ParseFiles(os.DevNull))
+ if err := page.ExecuteTemplate(os.Stdout, "page", "nothing"); err == nil {
+ t.Fatal("expected error")
+ }
+}
+
func BenchmarkEscapedExecute(b *testing.B) {
tmpl := Must(New("t").Parse(`<a onclick="alert('{{.}}')">{{.}}</a>`))
var buf bytes.Buffer
diff --git a/libgo/go/html/template/template.go b/libgo/go/html/template/template.go
index b0bae7a54fb..edac7335cfd 100644
--- a/libgo/go/html/template/template.go
+++ b/libgo/go/html/template/template.go
@@ -31,6 +31,20 @@ type nameSpace struct {
set map[string]*Template
}
+// Templates returns a slice of the templates associated with t, including t
+// itself.
+func (t *Template) Templates() []*Template {
+ ns := t.nameSpace
+ ns.mu.Lock()
+ defer ns.mu.Unlock()
+ // Return a slice so we don't expose the map.
+ m := make([]*Template, 0, len(ns.set))
+ for _, v := range ns.set {
+ m = append(m, v)
+ }
+ return m
+}
+
// Execute applies a parsed template to the specified data object,
// writing the output to wr.
func (t *Template) Execute(wr io.Writer, data interface{}) (err error) {
@@ -64,7 +78,13 @@ func (t *Template) lookupAndEscapeTemplate(name string) (tmpl *Template, err err
t.nameSpace.mu.Lock()
defer t.nameSpace.mu.Unlock()
tmpl = t.set[name]
- if (tmpl == nil) != (t.text.Lookup(name) == nil) {
+ if tmpl == nil {
+ return nil, fmt.Errorf("html/template: %q is undefined", name)
+ }
+ if tmpl.text.Tree == nil || tmpl.text.Root == nil {
+ return nil, fmt.Errorf("html/template: %q is an incomplete template", name)
+ }
+ if t.text.Lookup(name) == nil {
panic("html/template internal error: template escaping out of sync")
}
if tmpl != nil && !tmpl.escaped {
@@ -160,9 +180,11 @@ func (t *Template) Clone() (*Template, error) {
if src == nil || src.escaped {
return nil, fmt.Errorf("html/template: cannot Clone %q after it has executed", t.Name())
}
- x.Tree = &parse.Tree{
- Name: x.Tree.Name,
- Root: x.Tree.Root.CopyList(),
+ if x.Tree != nil {
+ x.Tree = &parse.Tree{
+ Name: x.Tree.Name,
+ Root: x.Tree.Root.CopyList(),
+ }
}
ret.set[name] = &Template{
false,
@@ -274,7 +296,7 @@ func (t *Template) ParseFiles(filenames ...string) (*Template, error) {
func parseFiles(t *Template, filenames ...string) (*Template, error) {
if len(filenames) == 0 {
// Not really a problem, but be consistent.
- return nil, fmt.Errorf("template: no files named in call to ParseFiles")
+ return nil, fmt.Errorf("html/template: no files named in call to ParseFiles")
}
for _, filename := range filenames {
b, err := ioutil.ReadFile(filename)
@@ -331,7 +353,7 @@ func parseGlob(t *Template, pattern string) (*Template, error) {
return nil, err
}
if len(filenames) == 0 {
- return nil, fmt.Errorf("template: pattern matches no files: %#q", pattern)
+ return nil, fmt.Errorf("html/template: pattern matches no files: %#q", pattern)
}
return parseFiles(t, filenames...)
}
diff --git a/libgo/go/image/draw/draw.go b/libgo/go/image/draw/draw.go
index 3b6679f7c7e..bef325c0c9d 100644
--- a/libgo/go/image/draw/draw.go
+++ b/libgo/go/image/draw/draw.go
@@ -5,7 +5,7 @@
// Package draw provides image composition functions.
//
// See "The Go image/draw package" for an introduction to this package:
-// http://blog.golang.org/2011/09/go-imagedraw-package.html
+// http://golang.org/doc/articles/image_draw.html
package draw
import (
diff --git a/libgo/go/image/image.go b/libgo/go/image/image.go
index 63bfb7d59e4..03ac6060671 100644
--- a/libgo/go/image/image.go
+++ b/libgo/go/image/image.go
@@ -18,7 +18,7 @@
// initialization side effects.
//
// See "The Go image package" for more details:
-// http://blog.golang.org/2011/09/go-image-package.html
+// http://golang.org/doc/articles/image_package.html
package image
import (
diff --git a/libgo/go/index/suffixarray/qsufsort.go b/libgo/go/index/suffixarray/qsufsort.go
index c69be43c2ac..9c36a98f82d 100644
--- a/libgo/go/index/suffixarray/qsufsort.go
+++ b/libgo/go/index/suffixarray/qsufsort.go
@@ -11,7 +11,7 @@
// Consecutive groups of suffixes in sa are labeled as sorted groups or
// unsorted groups. For a given pass of the sorter, all suffixes are ordered
// up to their first h characters, and sa is h-ordered. Suffixes in their
-// final positions and unambiguouly sorted in h-order are in a sorted group.
+// final positions and unambiguously sorted in h-order are in a sorted group.
// Consecutive groups of suffixes with identical first h characters are an
// unsorted group. In each pass of the algorithm, unsorted groups are sorted
// according to the group number of their following suffix.
@@ -78,7 +78,7 @@ func sortedByFirstByte(data []byte) []int {
for _, b := range data {
count[b]++
}
- // make count[b] equal index of first occurence of b in sorted array
+ // make count[b] equal index of first occurrence of b in sorted array
sum := 0
for b := range count {
count[b], sum = sum, count[b]+sum
diff --git a/libgo/go/io/io.go b/libgo/go/io/io.go
index 7074834d613..54bf159eb41 100644
--- a/libgo/go/io/io.go
+++ b/libgo/go/io/io.go
@@ -173,6 +173,13 @@ type ReaderAt interface {
// at offset off. It returns the number of bytes written from p (0 <= n <= len(p))
// and any error encountered that caused the write to stop early.
// WriteAt must return a non-nil error if it returns n < len(p).
+//
+// If WriteAt is writing to a destination with a seek offset,
+// WriteAt should not affect nor be affected by the underlying
+// seek offset.
+//
+// Clients of WriteAt can execute parallel WriteAt calls on the same
+// destination if the ranges do not overlap.
type WriterAt interface {
WriteAt(p []byte, off int64) (n int, err error)
}
diff --git a/libgo/go/io/ioutil/ioutil.go b/libgo/go/io/ioutil/ioutil.go
index 180afc2c221..f072b8c754a 100644
--- a/libgo/go/io/ioutil/ioutil.go
+++ b/libgo/go/io/ioutil/ioutil.go
@@ -53,10 +53,13 @@ func ReadFile(filename string) ([]byte, error) {
defer f.Close()
// It's a good but not certain bet that FileInfo will tell us exactly how much to
// read, so let's try it but be prepared for the answer to be wrong.
- fi, err := f.Stat()
var n int64
- if size := fi.Size(); err == nil && size < 2e9 { // Don't preallocate a huge buffer, just in case.
- n = size
+
+ if fi, err := f.Stat(); err == nil {
+ // Don't preallocate a huge buffer, just in case.
+ if size := fi.Size(); size < 1e9 {
+ n = size
+ }
}
// As initial capacity for readAll, use n + a little extra in case Size is zero,
// and to avoid another allocation after Read has filled the buffer. The readAll
diff --git a/libgo/go/log/log.go b/libgo/go/log/log.go
index 02a407ebc60..1d7f209d1da 100644
--- a/libgo/go/log/log.go
+++ b/libgo/go/log/log.go
@@ -13,8 +13,6 @@
package log
import (
- "bytes"
- _ "debug/elf"
"fmt"
"io"
"os"
@@ -29,7 +27,7 @@ const (
// order they appear (the order listed here) or the format they present (as
// described in the comments). A colon appears after these items:
// 2009/0123 01:23:23.123123 /a/b/c/d.go:23: message
- Ldate = 1 << iota // the date: 2009/0123
+ Ldate = 1 << iota // the date: 2009/01/23
Ltime // the time: 01:23:23
Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime.
Llongfile // full file name and line number: /a/b/c/d.go:23
@@ -42,11 +40,11 @@ const (
// the Writer's Write method. A Logger can be used simultaneously from
// multiple goroutines; it guarantees to serialize access to the Writer.
type Logger struct {
- mu sync.Mutex // ensures atomic writes; protects the following fields
- prefix string // prefix to write at beginning of each line
- flag int // properties
- out io.Writer // destination for output
- buf bytes.Buffer // for accumulating text to write
+ mu sync.Mutex // ensures atomic writes; protects the following fields
+ prefix string // prefix to write at beginning of each line
+ flag int // properties
+ out io.Writer // destination for output
+ buf []byte // for accumulating text to write
}
// New creates a new Logger. The out variable sets the
@@ -61,10 +59,10 @@ var std = New(os.Stderr, "", LstdFlags)
// Cheap integer to fixed-width decimal ASCII. Give a negative width to avoid zero-padding.
// Knows the buffer has capacity.
-func itoa(buf *bytes.Buffer, i int, wid int) {
+func itoa(buf *[]byte, i int, wid int) {
var u uint = uint(i)
if u == 0 && wid <= 1 {
- buf.WriteByte('0')
+ *buf = append(*buf, '0')
return
}
@@ -76,38 +74,33 @@ func itoa(buf *bytes.Buffer, i int, wid int) {
wid--
b[bp] = byte(u%10) + '0'
}
-
- // avoid slicing b to avoid an allocation.
- for bp < len(b) {
- buf.WriteByte(b[bp])
- bp++
- }
+ *buf = append(*buf, b[bp:]...)
}
-func (l *Logger) formatHeader(buf *bytes.Buffer, t time.Time, file string, line int) {
- buf.WriteString(l.prefix)
+func (l *Logger) formatHeader(buf *[]byte, t time.Time, file string, line int) {
+ *buf = append(*buf, l.prefix...)
if l.flag&(Ldate|Ltime|Lmicroseconds) != 0 {
if l.flag&Ldate != 0 {
year, month, day := t.Date()
itoa(buf, year, 4)
- buf.WriteByte('/')
+ *buf = append(*buf, '/')
itoa(buf, int(month), 2)
- buf.WriteByte('/')
+ *buf = append(*buf, '/')
itoa(buf, day, 2)
- buf.WriteByte(' ')
+ *buf = append(*buf, ' ')
}
if l.flag&(Ltime|Lmicroseconds) != 0 {
hour, min, sec := t.Clock()
itoa(buf, hour, 2)
- buf.WriteByte(':')
+ *buf = append(*buf, ':')
itoa(buf, min, 2)
- buf.WriteByte(':')
+ *buf = append(*buf, ':')
itoa(buf, sec, 2)
if l.flag&Lmicroseconds != 0 {
- buf.WriteByte('.')
+ *buf = append(*buf, '.')
itoa(buf, t.Nanosecond()/1e3, 6)
}
- buf.WriteByte(' ')
+ *buf = append(*buf, ' ')
}
}
if l.flag&(Lshortfile|Llongfile) != 0 {
@@ -121,10 +114,10 @@ func (l *Logger) formatHeader(buf *bytes.Buffer, t time.Time, file string, line
}
file = short
}
- buf.WriteString(file)
- buf.WriteByte(':')
+ *buf = append(*buf, file...)
+ *buf = append(*buf, ':')
itoa(buf, line, -1)
- buf.WriteString(": ")
+ *buf = append(*buf, ": "...)
}
}
@@ -151,13 +144,13 @@ func (l *Logger) Output(calldepth int, s string) error {
}
l.mu.Lock()
}
- l.buf.Reset()
+ l.buf = l.buf[:0]
l.formatHeader(&l.buf, now, file, line)
- l.buf.WriteString(s)
+ l.buf = append(l.buf, s...)
if len(s) > 0 && s[len(s)-1] != '\n' {
- l.buf.WriteByte('\n')
+ l.buf = append(l.buf, '\n')
}
- _, err := l.out.Write(l.buf.Bytes())
+ _, err := l.out.Write(l.buf)
return err
}
diff --git a/libgo/go/log/syslog/syslog_windows.go b/libgo/go/log/syslog/syslog_windows.go
new file mode 100644
index 00000000000..8d99e2e594d
--- /dev/null
+++ b/libgo/go/log/syslog/syslog_windows.go
@@ -0,0 +1,8 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package syslog provides a simple interface to the system log service.
+package syslog
+
+// BUG(brainman): This package is not implemented on Windows yet.
diff --git a/libgo/go/math/big/nat.go b/libgo/go/math/big/nat.go
index da1ac944c5c..0bc6572b962 100644
--- a/libgo/go/math/big/nat.go
+++ b/libgo/go/math/big/nat.go
@@ -826,7 +826,7 @@ func (x nat) string(charset string) string {
// iterative approach. This threshold is represented by leafSize. Benchmarking of leafSize in the
// range 2..64 shows that values of 8 and 16 work well, with a 4x speedup at medium lengths and
// ~30x for 20000 digits. Use nat_test.go's BenchmarkLeafSize tests to optimize leafSize for
-// specfic hardware.
+// specific hardware.
//
func (q nat) convertWords(s []byte, charset string, b Word, ndigits int, bb Word, table []divisor) {
// split larger blocks recursively
diff --git a/libgo/go/math/erf.go b/libgo/go/math/erf.go
index 87c70c2512f..c6f32bdbe28 100644
--- a/libgo/go/math/erf.go
+++ b/libgo/go/math/erf.go
@@ -248,7 +248,7 @@ func Erf(x float64) float64 {
R = rb0 + s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+s*rb6)))))
S = 1 + s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(sb5+s*(sb6+s*sb7))))))
}
- z := Float64frombits(Float64bits(x) & 0xffffffff00000000) // pseudo-single (20-bit) precison x
+ z := Float64frombits(Float64bits(x) & 0xffffffff00000000) // pseudo-single (20-bit) precision x
r := Exp(-z*z-0.5625) * Exp((z-x)*(z+x)+R/S)
if sign {
return r/x - 1
@@ -321,7 +321,7 @@ func Erfc(x float64) float64 {
R = rb0 + s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+s*rb6)))))
S = 1 + s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(sb5+s*(sb6+s*sb7))))))
}
- z := Float64frombits(Float64bits(x) & 0xffffffff00000000) // pseudo-single (20-bit) precison x
+ z := Float64frombits(Float64bits(x) & 0xffffffff00000000) // pseudo-single (20-bit) precision x
r := Exp(-z*z-0.5625) * Exp((z-x)*(z+x)+R/S)
if sign {
return 2 - r/x
diff --git a/libgo/go/net/dial_test.go b/libgo/go/net/dial_test.go
index 5f5aea146a6..7212087fe0c 100644
--- a/libgo/go/net/dial_test.go
+++ b/libgo/go/net/dial_test.go
@@ -6,6 +6,7 @@ package net
import (
"flag"
+ "fmt"
"regexp"
"runtime"
"testing"
@@ -32,7 +33,7 @@ func TestDialTimeout(t *testing.T) {
numConns := listenerBacklog + 10
// TODO(bradfitz): It's hard to test this in a portable
- // way. This is unforunate, but works for now.
+ // way. This is unfortunate, but works for now.
switch runtime.GOOS {
case "linux":
// The kernel will start accepting TCP connections before userspace
@@ -44,13 +45,25 @@ func TestDialTimeout(t *testing.T) {
errc <- err
}()
}
- case "darwin":
+ case "darwin", "windows":
// At least OS X 10.7 seems to accept any number of
// connections, ignoring listen's backlog, so resort
// to connecting to a hopefully-dead 127/8 address.
// Same for windows.
+ //
+ // Use an IANA reserved port (49151) instead of 80, because
+ // on our 386 builder, this Dial succeeds, connecting
+ // to an IIS web server somewhere. The data center
+ // or VM or firewall must be stealing the TCP connection.
+ //
+ // IANA Service Name and Transport Protocol Port Number Registry
+ // <http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml>
go func() {
- _, err := DialTimeout("tcp", "127.0.71.111:80", 200*time.Millisecond)
+ c, err := DialTimeout("tcp", "127.0.71.111:49151", 200*time.Millisecond)
+ if err == nil {
+ err = fmt.Errorf("unexpected: connected to %s!", c.RemoteAddr())
+ c.Close()
+ }
errc <- err
}()
default:
diff --git a/libgo/go/net/dnsclient.go b/libgo/go/net/dnsclient.go
index f4ed8b87cc1..e69cb3188bc 100644
--- a/libgo/go/net/dnsclient.go
+++ b/libgo/go/net/dnsclient.go
@@ -5,8 +5,6 @@
package net
import (
- "bytes"
- "fmt"
"math/rand"
"sort"
)
@@ -45,20 +43,22 @@ func reverseaddr(addr string) (arpa string, err error) {
return "", &DNSError{Err: "unrecognized address", Name: addr}
}
if ip.To4() != nil {
- return fmt.Sprintf("%d.%d.%d.%d.in-addr.arpa.", ip[15], ip[14], ip[13], ip[12]), nil
+ return itoa(int(ip[15])) + "." + itoa(int(ip[14])) + "." + itoa(int(ip[13])) + "." +
+ itoa(int(ip[12])) + ".in-addr.arpa.", nil
}
// Must be IPv6
- var buf bytes.Buffer
+ buf := make([]byte, 0, len(ip)*4+len("ip6.arpa."))
// Add it, in reverse, to the buffer
for i := len(ip) - 1; i >= 0; i-- {
- s := fmt.Sprintf("%02x", ip[i])
- buf.WriteByte(s[1])
- buf.WriteByte('.')
- buf.WriteByte(s[0])
- buf.WriteByte('.')
+ v := ip[i]
+ buf = append(buf, hexDigit[v&0xF])
+ buf = append(buf, '.')
+ buf = append(buf, hexDigit[v>>4])
+ buf = append(buf, '.')
}
// Append "ip6.arpa." and return (buf already has the final .)
- return buf.String() + "ip6.arpa.", nil
+ buf = append(buf, "ip6.arpa."...)
+ return string(buf), nil
}
// Find answer for name in dns message.
diff --git a/libgo/go/net/dnsmsg.go b/libgo/go/net/dnsmsg.go
index 97c5062103f..b6ebe117363 100644
--- a/libgo/go/net/dnsmsg.go
+++ b/libgo/go/net/dnsmsg.go
@@ -7,11 +7,10 @@
// This is intended to support name resolution during Dial.
// It doesn't have to be blazing fast.
//
-// Rather than write the usual handful of routines to pack and
-// unpack every message that can appear on the wire, we use
-// reflection to write a generic pack/unpack for structs and then
-// use it. Thus, if in the future we need to define new message
-// structs, no new pack/unpack/printing code needs to be written.
+// Each message structure has a Walk method that is used by
+// a generic pack/unpack routine. Thus, if in the future we need
+// to define new message structs, no new pack/unpack/printing code
+// needs to be written.
//
// The first half of this file defines the DNS message formats.
// The second half implements the conversion to and from wire format.
@@ -23,12 +22,6 @@
package net
-import (
- "fmt"
- "os"
- "reflect"
-)
-
// Packet formats
// Wire constants.
@@ -75,6 +68,20 @@ const (
dnsRcodeRefused = 5
)
+// A dnsStruct describes how to iterate over its fields to emulate
+// reflective marshalling.
+type dnsStruct interface {
+ // Walk iterates over fields of a structure and calls f
+ // with a reference to that field, the name of the field
+ // and a tag ("", "domain", "ipv4", "ipv6") specifying
+ // particular encodings. Possible concrete types
+ // for v are *uint16, *uint32, *string, or []byte, and
+ // *int, *bool in the case of dnsMsgHdr.
+ // Whenever f returns false, Walk must stop and return
+ // false, and otherwise return true.
+ Walk(f func(v interface{}, name, tag string) (ok bool)) (ok bool)
+}
+
// The wire format for the DNS packet header.
type dnsHeader struct {
Id uint16
@@ -82,6 +89,15 @@ type dnsHeader struct {
Qdcount, Ancount, Nscount, Arcount uint16
}
+func (h *dnsHeader) Walk(f func(v interface{}, name, tag string) bool) bool {
+ return f(&h.Id, "Id", "") &&
+ f(&h.Bits, "Bits", "") &&
+ f(&h.Qdcount, "Qdcount", "") &&
+ f(&h.Ancount, "Ancount", "") &&
+ f(&h.Nscount, "Nscount", "") &&
+ f(&h.Arcount, "Arcount", "")
+}
+
const (
// dnsHeader.Bits
_QR = 1 << 15 // query/response (response=1)
@@ -98,6 +114,12 @@ type dnsQuestion struct {
Qclass uint16
}
+func (q *dnsQuestion) Walk(f func(v interface{}, name, tag string) bool) bool {
+ return f(&q.Name, "Name", "domain") &&
+ f(&q.Qtype, "Qtype", "") &&
+ f(&q.Qclass, "Qclass", "")
+}
+
// DNS responses (resource records).
// There are many types of messages,
// but they all share the same header.
@@ -113,7 +135,16 @@ func (h *dnsRR_Header) Header() *dnsRR_Header {
return h
}
+func (h *dnsRR_Header) Walk(f func(v interface{}, name, tag string) bool) bool {
+ return f(&h.Name, "Name", "domain") &&
+ f(&h.Rrtype, "Rrtype", "") &&
+ f(&h.Class, "Class", "") &&
+ f(&h.Ttl, "Ttl", "") &&
+ f(&h.Rdlength, "Rdlength", "")
+}
+
type dnsRR interface {
+ dnsStruct
Header() *dnsRR_Header
}
@@ -128,6 +159,10 @@ func (rr *dnsRR_CNAME) Header() *dnsRR_Header {
return &rr.Hdr
}
+func (rr *dnsRR_CNAME) Walk(f func(v interface{}, name, tag string) bool) bool {
+ return rr.Hdr.Walk(f) && f(&rr.Cname, "Cname", "domain")
+}
+
type dnsRR_HINFO struct {
Hdr dnsRR_Header
Cpu string
@@ -138,6 +173,10 @@ func (rr *dnsRR_HINFO) Header() *dnsRR_Header {
return &rr.Hdr
}
+func (rr *dnsRR_HINFO) Walk(f func(v interface{}, name, tag string) bool) bool {
+ return rr.Hdr.Walk(f) && f(&rr.Cpu, "Cpu", "") && f(&rr.Os, "Os", "")
+}
+
type dnsRR_MB struct {
Hdr dnsRR_Header
Mb string `net:"domain-name"`
@@ -147,6 +186,10 @@ func (rr *dnsRR_MB) Header() *dnsRR_Header {
return &rr.Hdr
}
+func (rr *dnsRR_MB) Walk(f func(v interface{}, name, tag string) bool) bool {
+ return rr.Hdr.Walk(f) && f(&rr.Mb, "Mb", "domain")
+}
+
type dnsRR_MG struct {
Hdr dnsRR_Header
Mg string `net:"domain-name"`
@@ -156,6 +199,10 @@ func (rr *dnsRR_MG) Header() *dnsRR_Header {
return &rr.Hdr
}
+func (rr *dnsRR_MG) Walk(f func(v interface{}, name, tag string) bool) bool {
+ return rr.Hdr.Walk(f) && f(&rr.Mg, "Mg", "domain")
+}
+
type dnsRR_MINFO struct {
Hdr dnsRR_Header
Rmail string `net:"domain-name"`
@@ -166,6 +213,10 @@ func (rr *dnsRR_MINFO) Header() *dnsRR_Header {
return &rr.Hdr
}
+func (rr *dnsRR_MINFO) Walk(f func(v interface{}, name, tag string) bool) bool {
+ return rr.Hdr.Walk(f) && f(&rr.Rmail, "Rmail", "domain") && f(&rr.Email, "Email", "domain")
+}
+
type dnsRR_MR struct {
Hdr dnsRR_Header
Mr string `net:"domain-name"`
@@ -175,6 +226,10 @@ func (rr *dnsRR_MR) Header() *dnsRR_Header {
return &rr.Hdr
}
+func (rr *dnsRR_MR) Walk(f func(v interface{}, name, tag string) bool) bool {
+ return rr.Hdr.Walk(f) && f(&rr.Mr, "Mr", "domain")
+}
+
type dnsRR_MX struct {
Hdr dnsRR_Header
Pref uint16
@@ -185,6 +240,10 @@ func (rr *dnsRR_MX) Header() *dnsRR_Header {
return &rr.Hdr
}
+func (rr *dnsRR_MX) Walk(f func(v interface{}, name, tag string) bool) bool {
+ return rr.Hdr.Walk(f) && f(&rr.Pref, "Pref", "") && f(&rr.Mx, "Mx", "domain")
+}
+
type dnsRR_NS struct {
Hdr dnsRR_Header
Ns string `net:"domain-name"`
@@ -194,6 +253,10 @@ func (rr *dnsRR_NS) Header() *dnsRR_Header {
return &rr.Hdr
}
+func (rr *dnsRR_NS) Walk(f func(v interface{}, name, tag string) bool) bool {
+ return rr.Hdr.Walk(f) && f(&rr.Ns, "Ns", "domain")
+}
+
type dnsRR_PTR struct {
Hdr dnsRR_Header
Ptr string `net:"domain-name"`
@@ -203,6 +266,10 @@ func (rr *dnsRR_PTR) Header() *dnsRR_Header {
return &rr.Hdr
}
+func (rr *dnsRR_PTR) Walk(f func(v interface{}, name, tag string) bool) bool {
+ return rr.Hdr.Walk(f) && f(&rr.Ptr, "Ptr", "domain")
+}
+
type dnsRR_SOA struct {
Hdr dnsRR_Header
Ns string `net:"domain-name"`
@@ -218,6 +285,17 @@ func (rr *dnsRR_SOA) Header() *dnsRR_Header {
return &rr.Hdr
}
+func (rr *dnsRR_SOA) Walk(f func(v interface{}, name, tag string) bool) bool {
+ return rr.Hdr.Walk(f) &&
+ f(&rr.Ns, "Ns", "domain") &&
+ f(&rr.Mbox, "Mbox", "domain") &&
+ f(&rr.Serial, "Serial", "") &&
+ f(&rr.Refresh, "Refresh", "") &&
+ f(&rr.Retry, "Retry", "") &&
+ f(&rr.Expire, "Expire", "") &&
+ f(&rr.Minttl, "Minttl", "")
+}
+
type dnsRR_TXT struct {
Hdr dnsRR_Header
Txt string // not domain name
@@ -227,6 +305,10 @@ func (rr *dnsRR_TXT) Header() *dnsRR_Header {
return &rr.Hdr
}
+func (rr *dnsRR_TXT) Walk(f func(v interface{}, name, tag string) bool) bool {
+ return rr.Hdr.Walk(f) && f(&rr.Txt, "Txt", "")
+}
+
type dnsRR_SRV struct {
Hdr dnsRR_Header
Priority uint16
@@ -239,6 +321,14 @@ func (rr *dnsRR_SRV) Header() *dnsRR_Header {
return &rr.Hdr
}
+func (rr *dnsRR_SRV) Walk(f func(v interface{}, name, tag string) bool) bool {
+ return rr.Hdr.Walk(f) &&
+ f(&rr.Priority, "Priority", "") &&
+ f(&rr.Weight, "Weight", "") &&
+ f(&rr.Port, "Port", "") &&
+ f(&rr.Target, "Target", "domain")
+}
+
type dnsRR_A struct {
Hdr dnsRR_Header
A uint32 `net:"ipv4"`
@@ -248,6 +338,10 @@ func (rr *dnsRR_A) Header() *dnsRR_Header {
return &rr.Hdr
}
+func (rr *dnsRR_A) Walk(f func(v interface{}, name, tag string) bool) bool {
+ return rr.Hdr.Walk(f) && f(&rr.A, "A", "ipv4")
+}
+
type dnsRR_AAAA struct {
Hdr dnsRR_Header
AAAA [16]byte `net:"ipv6"`
@@ -257,6 +351,10 @@ func (rr *dnsRR_AAAA) Header() *dnsRR_Header {
return &rr.Hdr
}
+func (rr *dnsRR_AAAA) Walk(f func(v interface{}, name, tag string) bool) bool {
+ return rr.Hdr.Walk(f) && f(rr.AAAA[:], "AAAA", "ipv6")
+}
+
// Packing and unpacking.
//
// All the packers and unpackers take a (msg []byte, off int)
@@ -386,134 +484,107 @@ Loop:
return s, off1, true
}
-// TODO(rsc): Move into generic library?
-// Pack a reflect.StructValue into msg. Struct members can only be uint16, uint32, string,
-// [n]byte, and other (often anonymous) structs.
-func packStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok bool) {
- for i := 0; i < val.NumField(); i++ {
- f := val.Type().Field(i)
- switch fv := val.Field(i); fv.Kind() {
+// packStruct packs a structure into msg at specified offset off, and
+// returns off1 such that msg[off:off1] is the encoded data.
+func packStruct(any dnsStruct, msg []byte, off int) (off1 int, ok bool) {
+ ok = any.Walk(func(field interface{}, name, tag string) bool {
+ switch fv := field.(type) {
default:
- fmt.Fprintf(os.Stderr, "net: dns: unknown packing type %v", f.Type)
- return len(msg), false
- case reflect.Struct:
- off, ok = packStructValue(fv, msg, off)
- case reflect.Uint16:
+ println("net: dns: unknown packing type")
+ return false
+ case *uint16:
+ i := *fv
if off+2 > len(msg) {
- return len(msg), false
+ return false
}
- i := fv.Uint()
msg[off] = byte(i >> 8)
msg[off+1] = byte(i)
off += 2
- case reflect.Uint32:
- if off+4 > len(msg) {
- return len(msg), false
- }
- i := fv.Uint()
+ case *uint32:
+ i := *fv
msg[off] = byte(i >> 24)
msg[off+1] = byte(i >> 16)
msg[off+2] = byte(i >> 8)
msg[off+3] = byte(i)
off += 4
- case reflect.Array:
- if fv.Type().Elem().Kind() != reflect.Uint8 {
- fmt.Fprintf(os.Stderr, "net: dns: unknown packing type %v", f.Type)
- return len(msg), false
- }
- n := fv.Len()
+ case []byte:
+ n := len(fv)
if off+n > len(msg) {
- return len(msg), false
+ return false
}
- reflect.Copy(reflect.ValueOf(msg[off:off+n]), fv)
+ copy(msg[off:off+n], fv)
off += n
- case reflect.String:
- // There are multiple string encodings.
- // The tag distinguishes ordinary strings from domain names.
- s := fv.String()
- switch f.Tag {
+ case *string:
+ s := *fv
+ switch tag {
default:
- fmt.Fprintf(os.Stderr, "net: dns: unknown string tag %v", f.Tag)
- return len(msg), false
- case `net:"domain-name"`:
+ println("net: dns: unknown string tag", tag)
+ return false
+ case "domain":
off, ok = packDomainName(s, msg, off)
if !ok {
- return len(msg), false
+ return false
}
case "":
// Counted string: 1 byte length.
if len(s) > 255 || off+1+len(s) > len(msg) {
- return len(msg), false
+ return false
}
msg[off] = byte(len(s))
off++
off += copy(msg[off:], s)
}
}
+ return true
+ })
+ if !ok {
+ return len(msg), false
}
return off, true
}
-func structValue(any interface{}) reflect.Value {
- return reflect.ValueOf(any).Elem()
-}
-
-func packStruct(any interface{}, msg []byte, off int) (off1 int, ok bool) {
- off, ok = packStructValue(structValue(any), msg, off)
- return off, ok
-}
-
-// TODO(rsc): Move into generic library?
-// Unpack a reflect.StructValue from msg.
-// Same restrictions as packStructValue.
-func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok bool) {
- for i := 0; i < val.NumField(); i++ {
- f := val.Type().Field(i)
- switch fv := val.Field(i); fv.Kind() {
+// unpackStruct decodes msg[off:] into the given structure, and
+// returns off1 such that msg[off:off1] is the encoded data.
+func unpackStruct(any dnsStruct, msg []byte, off int) (off1 int, ok bool) {
+ ok = any.Walk(func(field interface{}, name, tag string) bool {
+ switch fv := field.(type) {
default:
- fmt.Fprintf(os.Stderr, "net: dns: unknown packing type %v", f.Type)
- return len(msg), false
- case reflect.Struct:
- off, ok = unpackStructValue(fv, msg, off)
- case reflect.Uint16:
+ println("net: dns: unknown packing type")
+ return false
+ case *uint16:
if off+2 > len(msg) {
- return len(msg), false
+ return false
}
- i := uint16(msg[off])<<8 | uint16(msg[off+1])
- fv.SetUint(uint64(i))
+ *fv = uint16(msg[off])<<8 | uint16(msg[off+1])
off += 2
- case reflect.Uint32:
+ case *uint32:
if off+4 > len(msg) {
- return len(msg), false
+ return false
}
- i := uint32(msg[off])<<24 | uint32(msg[off+1])<<16 | uint32(msg[off+2])<<8 | uint32(msg[off+3])
- fv.SetUint(uint64(i))
+ *fv = uint32(msg[off])<<24 | uint32(msg[off+1])<<16 |
+ uint32(msg[off+2])<<8 | uint32(msg[off+3])
off += 4
- case reflect.Array:
- if fv.Type().Elem().Kind() != reflect.Uint8 {
- fmt.Fprintf(os.Stderr, "net: dns: unknown packing type %v", f.Type)
- return len(msg), false
- }
- n := fv.Len()
+ case []byte:
+ n := len(fv)
if off+n > len(msg) {
- return len(msg), false
+ return false
}
- reflect.Copy(fv, reflect.ValueOf(msg[off:off+n]))
+ copy(fv, msg[off:off+n])
off += n
- case reflect.String:
+ case *string:
var s string
- switch f.Tag {
+ switch tag {
default:
- fmt.Fprintf(os.Stderr, "net: dns: unknown string tag %v", f.Tag)
- return len(msg), false
- case `net:"domain-name"`:
+ println("net: dns: unknown string tag", tag)
+ return false
+ case "domain":
s, off, ok = unpackDomainName(msg, off)
if !ok {
- return len(msg), false
+ return false
}
case "":
if off >= len(msg) || off+1+int(msg[off]) > len(msg) {
- return len(msg), false
+ return false
}
n := int(msg[off])
off++
@@ -524,51 +595,77 @@ func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok boo
off += n
s = string(b)
}
- fv.SetString(s)
+ *fv = s
}
+ return true
+ })
+ if !ok {
+ return len(msg), false
}
return off, true
}
-func unpackStruct(any interface{}, msg []byte, off int) (off1 int, ok bool) {
- off, ok = unpackStructValue(structValue(any), msg, off)
- return off, ok
-}
-
-// Generic struct printer.
-// Doesn't care about the string tag `net:"domain-name"`,
-// but does look for an `net:"ipv4"` tag on uint32 variables
-// and the `net:"ipv6"` tag on array variables,
-// printing them as IP addresses.
-func printStructValue(val reflect.Value) string {
+// Generic struct printer. Prints fields with tag "ipv4" or "ipv6"
+// as IP addresses.
+func printStruct(any dnsStruct) string {
s := "{"
- for i := 0; i < val.NumField(); i++ {
- if i > 0 {
+ i := 0
+ any.Walk(func(val interface{}, name, tag string) bool {
+ i++
+ if i > 1 {
s += ", "
}
- f := val.Type().Field(i)
- if !f.Anonymous {
- s += f.Name + "="
- }
- fval := val.Field(i)
- if fv := fval; fv.Kind() == reflect.Struct {
- s += printStructValue(fv)
- } else if fv := fval; (fv.Kind() == reflect.Uint || fv.Kind() == reflect.Uint8 || fv.Kind() == reflect.Uint16 || fv.Kind() == reflect.Uint32 || fv.Kind() == reflect.Uint64 || fv.Kind() == reflect.Uintptr) && f.Tag == `net:"ipv4"` {
- i := fv.Uint()
+ s += name + "="
+ switch tag {
+ case "ipv4":
+ i := val.(uint32)
s += IPv4(byte(i>>24), byte(i>>16), byte(i>>8), byte(i)).String()
- } else if fv := fval; fv.Kind() == reflect.Array && f.Tag == `net:"ipv6"` {
- i := fv.Interface().([]byte)
+ case "ipv6":
+ i := val.([]byte)
s += IP(i).String()
- } else {
- s += fmt.Sprint(fval.Interface())
+ default:
+ var i int64
+ switch v := val.(type) {
+ default:
+ // can't really happen.
+ s += "<unknown type>"
+ return true
+ case *string:
+ s += *v
+ return true
+ case []byte:
+ s += string(v)
+ return true
+ case *bool:
+ if *v {
+ s += "true"
+ } else {
+ s += "false"
+ }
+ return true
+ case *int:
+ i = int64(*v)
+ case *uint:
+ i = int64(*v)
+ case *uint8:
+ i = int64(*v)
+ case *uint16:
+ i = int64(*v)
+ case *uint32:
+ i = int64(*v)
+ case *uint64:
+ i = int64(*v)
+ case *uintptr:
+ i = int64(*v)
+ }
+ s += itoa(int(i))
}
- }
+ return true
+ })
s += "}"
return s
}
-func printStruct(any interface{}) string { return printStructValue(structValue(any)) }
-
// Resource record packer.
func packRR(rr dnsRR, msg []byte, off int) (off2 int, ok bool) {
var off1 int
@@ -627,6 +724,17 @@ type dnsMsgHdr struct {
rcode int
}
+func (h *dnsMsgHdr) Walk(f func(v interface{}, name, tag string) bool) bool {
+ return f(&h.id, "id", "") &&
+ f(&h.response, "response", "") &&
+ f(&h.opcode, "opcode", "") &&
+ f(&h.authoritative, "authoritative", "") &&
+ f(&h.truncated, "truncated", "") &&
+ f(&h.recursion_desired, "recursion_desired", "") &&
+ f(&h.recursion_available, "recursion_available", "") &&
+ f(&h.rcode, "rcode", "")
+}
+
type dnsMsg struct {
dnsMsgHdr
question []dnsQuestion
diff --git a/libgo/go/net/dnsmsg_test.go b/libgo/go/net/dnsmsg_test.go
index 06152a01a23..c39dbdb049d 100644
--- a/libgo/go/net/dnsmsg_test.go
+++ b/libgo/go/net/dnsmsg_test.go
@@ -6,6 +6,7 @@ package net
import (
"encoding/hex"
+ "reflect"
"testing"
)
@@ -19,6 +20,7 @@ func TestDNSParseSRVReply(t *testing.T) {
if !ok {
t.Fatalf("unpacking packet failed")
}
+ msg.String() // exercise this code path
if g, e := len(msg.answer), 5; g != e {
t.Errorf("len(msg.answer) = %d; want %d", g, e)
}
@@ -38,6 +40,16 @@ func TestDNSParseSRVReply(t *testing.T) {
t.Errorf("len(addrs) = %d; want %d", g, e)
t.Logf("addrs = %#v", addrs)
}
+ // repack and unpack.
+ data2, ok := msg.Pack()
+ msg2 := new(dnsMsg)
+ msg2.Unpack(data2)
+ switch {
+ case !ok:
+ t.Errorf("failed to repack message")
+ case !reflect.DeepEqual(msg, msg2):
+ t.Errorf("repacked message differs from original")
+ }
}
func TestDNSParseCorruptSRVReply(t *testing.T) {
@@ -50,6 +62,7 @@ func TestDNSParseCorruptSRVReply(t *testing.T) {
if !ok {
t.Fatalf("unpacking packet failed")
}
+ msg.String() // exercise this code path
if g, e := len(msg.answer), 5; g != e {
t.Errorf("len(msg.answer) = %d; want %d", g, e)
}
diff --git a/libgo/go/net/fd.go b/libgo/go/net/fd.go
index ae1bf2614a2..76c953b9b4e 100644
--- a/libgo/go/net/fd.go
+++ b/libgo/go/net/fd.go
@@ -623,6 +623,10 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (netfd *netFD, err e
continue
}
}
+ } else if err == syscall.ECONNABORTED {
+ // This means that a socket on the listen queue was closed
+ // before we Accept()ed it; it's a silly error, so try again.
+ continue
}
return nil, &OpError{"accept", fd.net, fd.laddr, err}
}
diff --git a/libgo/go/net/fd_linux.go b/libgo/go/net/fd_linux.go
index a1d62acc784..085e423072a 100644
--- a/libgo/go/net/fd_linux.go
+++ b/libgo/go/net/fd_linux.go
@@ -84,7 +84,8 @@ func (p *pollster) StopWaiting(fd int, bits uint) {
events, already := p.events[fd]
if !already {
- print("Epoll unexpected fd=", fd, "\n")
+ // The fd returned by the kernel may have been
+ // cancelled already; return silently.
return
}
diff --git a/libgo/go/net/file_test.go b/libgo/go/net/file_test.go
index 868388efa1c..95c0b66995e 100644
--- a/libgo/go/net/file_test.go
+++ b/libgo/go/net/file_test.go
@@ -27,7 +27,8 @@ type connFile interface {
}
func testFileListener(t *testing.T, net, laddr string) {
- if net == "tcp" {
+ switch net {
+ case "tcp", "tcp4", "tcp6":
laddr += ":0" // any available port
}
l, err := Listen(net, laddr)
@@ -55,20 +56,52 @@ func testFileListener(t *testing.T, net, laddr string) {
}
}
+var fileListenerTests = []struct {
+ net string
+ laddr string
+ ipv6 bool // test with underlying AF_INET6 socket
+ linux bool // test with abstract unix domain socket, a Linux-ism
+}{
+ {net: "tcp", laddr: ""},
+ {net: "tcp", laddr: "0.0.0.0"},
+ {net: "tcp", laddr: "[::ffff:0.0.0.0]"},
+ {net: "tcp", laddr: "[::]", ipv6: true},
+
+ {net: "tcp", laddr: "127.0.0.1"},
+ {net: "tcp", laddr: "[::ffff:127.0.0.1]"},
+ {net: "tcp", laddr: "[::1]", ipv6: true},
+
+ {net: "tcp4", laddr: ""},
+ {net: "tcp4", laddr: "0.0.0.0"},
+ {net: "tcp4", laddr: "[::ffff:0.0.0.0]"},
+
+ {net: "tcp4", laddr: "127.0.0.1"},
+ {net: "tcp4", laddr: "[::ffff:127.0.0.1]"},
+
+ {net: "tcp6", laddr: "", ipv6: true},
+ {net: "tcp6", laddr: "[::]", ipv6: true},
+
+ {net: "tcp6", laddr: "[::1]", ipv6: true},
+
+ {net: "unix", laddr: "@gotest/net", linux: true},
+ {net: "unixpacket", laddr: "@gotest/net", linux: true},
+}
+
func TestFileListener(t *testing.T) {
- if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
+ switch runtime.GOOS {
+ case "plan9", "windows":
+ t.Logf("skipping test on %q", runtime.GOOS)
return
}
- testFileListener(t, "tcp", "127.0.0.1")
- testFileListener(t, "tcp", "127.0.0.1")
- if supportsIPv6 && supportsIPv4map {
- testFileListener(t, "tcp", "[::ffff:127.0.0.1]")
- testFileListener(t, "tcp", "127.0.0.1")
- testFileListener(t, "tcp", "[::ffff:127.0.0.1]")
- }
- if runtime.GOOS == "linux" {
- testFileListener(t, "unix", "@gotest/net")
- testFileListener(t, "unixpacket", "@gotest/net")
+
+ for _, tt := range fileListenerTests {
+ if skipServerTest(tt.net, "unix", tt.laddr, tt.ipv6, false, tt.linux) {
+ continue
+ }
+ if skipServerTest(tt.net, "unixpacket", tt.laddr, tt.ipv6, false, tt.linux) {
+ continue
+ }
+ testFileListener(t, tt.net, tt.laddr)
}
}
@@ -98,9 +131,13 @@ func testFilePacketConn(t *testing.T, pcf packetConnFile, listen bool) {
}
func testFilePacketConnListen(t *testing.T, net, laddr string) {
+ switch net {
+ case "udp", "udp4", "udp6":
+ laddr += ":0" // any available port
+ }
l, err := ListenPacket(net, laddr)
if err != nil {
- t.Fatalf("Listen failed: %v", err)
+ t.Fatalf("ListenPacket failed: %v", err)
}
testFilePacketConn(t, l.(packetConnFile), true)
if err := l.Close(); err != nil {
@@ -109,6 +146,10 @@ func testFilePacketConnListen(t *testing.T, net, laddr string) {
}
func testFilePacketConnDial(t *testing.T, net, raddr string) {
+ switch net {
+ case "udp", "udp4", "udp6":
+ raddr += ":12345"
+ }
c, err := Dial(net, raddr)
if err != nil {
t.Fatalf("Dial failed: %v", err)
@@ -119,19 +160,42 @@ func testFilePacketConnDial(t *testing.T, net, raddr string) {
}
}
+var filePacketConnTests = []struct {
+ net string
+ addr string
+ ipv6 bool // test with underlying AF_INET6 socket
+ linux bool // test with abstract unix domain socket, a Linux-ism
+}{
+ {net: "udp", addr: "127.0.0.1"},
+ {net: "udp", addr: "[::ffff:127.0.0.1]"},
+ {net: "udp", addr: "[::1]", ipv6: true},
+
+ {net: "udp4", addr: "127.0.0.1"},
+ {net: "udp4", addr: "[::ffff:127.0.0.1]"},
+
+ {net: "udp6", addr: "[::1]", ipv6: true},
+
+ {net: "unixgram", addr: "@gotest3/net", linux: true},
+}
+
func TestFilePacketConn(t *testing.T) {
- if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
+ switch runtime.GOOS {
+ case "plan9", "windows":
+ t.Logf("skipping test on %q", runtime.GOOS)
return
}
- testFilePacketConnListen(t, "udp", "127.0.0.1:0")
- testFilePacketConnDial(t, "udp", "127.0.0.1:12345")
- if supportsIPv6 {
- testFilePacketConnListen(t, "udp", "[::1]:0")
- }
- if supportsIPv6 && supportsIPv4map {
- testFilePacketConnDial(t, "udp", "[::ffff:127.0.0.1]:12345")
- }
- if runtime.GOOS == "linux" {
- testFilePacketConnListen(t, "unixgram", "@gotest1/net")
+
+ for _, tt := range filePacketConnTests {
+ if skipServerTest(tt.net, "unixgram", tt.addr, tt.ipv6, false, tt.linux) {
+ continue
+ }
+ testFilePacketConnListen(t, tt.net, tt.addr)
+ switch tt.addr {
+ case "", "0.0.0.0", "[::ffff:0.0.0.0]", "[::]":
+ default:
+ if tt.net != "unixgram" {
+ testFilePacketConnDial(t, tt.net, tt.addr)
+ }
+ }
}
}
diff --git a/libgo/go/net/http/client_test.go b/libgo/go/net/http/client_test.go
index aa0bf4be676..e00b62e590a 100644
--- a/libgo/go/net/http/client_test.go
+++ b/libgo/go/net/http/client_test.go
@@ -238,9 +238,9 @@ func TestRedirects(t *testing.T) {
}
var expectedCookies = []*Cookie{
- &Cookie{Name: "ChocolateChip", Value: "tasty"},
- &Cookie{Name: "First", Value: "Hit"},
- &Cookie{Name: "Second", Value: "Hit"},
+ {Name: "ChocolateChip", Value: "tasty"},
+ {Name: "First", Value: "Hit"},
+ {Name: "Second", Value: "Hit"},
}
var echoCookiesRedirectHandler = HandlerFunc(func(w ResponseWriter, r *Request) {
diff --git a/libgo/go/net/http/request.go b/libgo/go/net/http/request.go
index 5277657805d..f5bc6eb9100 100644
--- a/libgo/go/net/http/request.go
+++ b/libgo/go/net/http/request.go
@@ -455,11 +455,13 @@ func ReadRequest(b *bufio.Reader) (req *Request, err error) {
// First line: GET /index.html HTTP/1.0
var s string
if s, err = tp.ReadLine(); err != nil {
+ return nil, err
+ }
+ defer func() {
if err == io.EOF {
err = io.ErrUnexpectedEOF
}
- return nil, err
- }
+ }()
var f []string
if f = strings.SplitN(s, " ", 3); len(f) < 3 {
diff --git a/libgo/go/net/http/request_test.go b/libgo/go/net/http/request_test.go
index 7a3556d0367..6e00b9bfd39 100644
--- a/libgo/go/net/http/request_test.go
+++ b/libgo/go/net/http/request_test.go
@@ -5,6 +5,7 @@
package http_test
import (
+ "bufio"
"bytes"
"fmt"
"io"
@@ -177,6 +178,24 @@ func TestRequestMultipartCallOrder(t *testing.T) {
}
}
+var readRequestErrorTests = []struct {
+ in string
+ err error
+}{
+ {"GET / HTTP/1.1\r\nheader:foo\r\n\r\n", nil},
+ {"GET / HTTP/1.1\r\nheader:foo\r\n", io.ErrUnexpectedEOF},
+ {"", io.EOF},
+}
+
+func TestReadRequestErrors(t *testing.T) {
+ for i, tt := range readRequestErrorTests {
+ _, err := ReadRequest(bufio.NewReader(strings.NewReader(tt.in)))
+ if err != tt.err {
+ t.Errorf("%d. got error = %v; want %v", i, err, tt.err)
+ }
+ }
+}
+
func testMissingFile(t *testing.T, req *Request) {
f, fh, err := req.FormFile("missing")
if f != nil {
diff --git a/libgo/go/net/http/server.go b/libgo/go/net/http/server.go
index fa0df54a236..228ac401968 100644
--- a/libgo/go/net/http/server.go
+++ b/libgo/go/net/http/server.go
@@ -601,7 +601,7 @@ func (c *conn) serve() {
// while they're still writing their
// request. Undefined behavior.
msg = "413 Request Entity Too Large"
- } else if err == io.ErrUnexpectedEOF {
+ } else if err == io.EOF {
break // Don't reply
} else if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
break // Don't reply
diff --git a/libgo/go/net/http/transport.go b/libgo/go/net/http/transport.go
index 09579f8a093..024975946e5 100644
--- a/libgo/go/net/http/transport.go
+++ b/libgo/go/net/http/transport.go
@@ -196,7 +196,7 @@ func (t *Transport) CloseIdleConnections() {
pconn.close()
}
}
- t.idleConn = nil
+ t.idleConn = make(map[string][]*persistConn)
}
//
diff --git a/libgo/go/net/http/transport_test.go b/libgo/go/net/http/transport_test.go
index cbb3884f9ea..a9e401de58d 100644
--- a/libgo/go/net/http/transport_test.go
+++ b/libgo/go/net/http/transport_test.go
@@ -698,6 +698,32 @@ func TestTransportPersistConnLeak(t *testing.T) {
}
}
+// This used to crash; http://golang.org/issue/3266
+func TestTransportIdleConnCrash(t *testing.T) {
+ tr := &Transport{}
+ c := &Client{Transport: tr}
+
+ unblockCh := make(chan bool, 1)
+ ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+ <-unblockCh
+ tr.CloseIdleConnections()
+ }))
+ defer ts.Close()
+
+ didreq := make(chan bool)
+ go func() {
+ res, err := c.Get(ts.URL)
+ if err != nil {
+ t.Error(err)
+ } else {
+ res.Body.Close() // returns idle conn
+ }
+ didreq <- true
+ }()
+ unblockCh <- true
+ <-didreq
+}
+
type fooProto struct{}
func (fooProto) RoundTrip(req *Request) (*Response, error) {
diff --git a/libgo/go/net/http/triv.go b/libgo/go/net/http/triv.go
index 269af0ca3d5..232d6508906 100644
--- a/libgo/go/net/http/triv.go
+++ b/libgo/go/net/http/triv.go
@@ -15,7 +15,9 @@ import (
"log"
"net/http"
"os"
+ "os/exec"
"strconv"
+ "sync"
)
// hello world, the web server
@@ -28,14 +30,21 @@ func HelloServer(w http.ResponseWriter, req *http.Request) {
// Simple counter server. POSTing to it will set the value.
type Counter struct {
- n int
+ mu sync.Mutex // protects n
+ n int
}
// This makes Counter satisfy the expvar.Var interface, so we can export
// it directly.
-func (ctr *Counter) String() string { return fmt.Sprintf("%d", ctr.n) }
+func (ctr *Counter) String() string {
+ ctr.mu.Lock()
+ defer ctr.mu.Unlock()
+ return fmt.Sprintf("%d", ctr.n)
+}
func (ctr *Counter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+ ctr.mu.Lock()
+ defer ctr.mu.Unlock()
switch req.Method {
case "GET":
ctr.n++
@@ -95,54 +104,36 @@ func (ch Chan) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// exec a program, redirecting output
func DateServer(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("Content-Type", "text/plain; charset=utf-8")
- r, w, err := os.Pipe()
- if err != nil {
- fmt.Fprintf(rw, "pipe: %s\n", err)
- return
- }
- p, err := os.StartProcess("/bin/date", []string{"date"}, &os.ProcAttr{Files: []*os.File{nil, w, w}})
- defer r.Close()
- w.Close()
- if err != nil {
- fmt.Fprintf(rw, "fork/exec: %s\n", err)
- return
- }
- io.Copy(rw, r)
- wait, err := p.Wait(0)
+ date, err := exec.Command("/bin/date").Output()
if err != nil {
- fmt.Fprintf(rw, "wait: %s\n", err)
- return
- }
- if !wait.Exited() || wait.ExitStatus() != 0 {
- fmt.Fprintf(rw, "date: %v\n", wait)
+ http.Error(rw, err.Error(), 500)
return
}
+ rw.Write(date)
}
func Logger(w http.ResponseWriter, req *http.Request) {
- log.Print(req.URL.Raw)
- w.WriteHeader(404)
- w.Write([]byte("oops"))
+ log.Print(req.URL)
+ http.Error(w, "oops", 404)
}
-var webroot = flag.String("root", "/home/rsc", "web root directory")
+var webroot = flag.String("root", os.Getenv("HOME"), "web root directory")
func main() {
flag.Parse()
// The counter is published as a variable directly.
ctr := new(Counter)
- http.Handle("/counter", ctr)
expvar.Publish("counter", ctr)
-
+ http.Handle("/counter", ctr)
http.Handle("/", http.HandlerFunc(Logger))
http.Handle("/go/", http.StripPrefix("/go/", http.FileServer(http.Dir(*webroot))))
- http.Handle("/flags", http.HandlerFunc(FlagServer))
- http.Handle("/args", http.HandlerFunc(ArgServer))
- http.Handle("/go/hello", http.HandlerFunc(HelloServer))
http.Handle("/chan", ChanCreate())
- http.Handle("/date", http.HandlerFunc(DateServer))
+ http.HandleFunc("/flags", FlagServer)
+ http.HandleFunc("/args", ArgServer)
+ http.HandleFunc("/go/hello", HelloServer)
+ http.HandleFunc("/date", DateServer)
err := http.ListenAndServe(":12345", nil)
if err != nil {
log.Panicln("ListenAndServe:", err)
diff --git a/libgo/go/net/interface.go b/libgo/go/net/interface.go
index f25d046c171..ee23570a96d 100644
--- a/libgo/go/net/interface.go
+++ b/libgo/go/net/interface.go
@@ -78,7 +78,7 @@ func (ifi *Interface) MulticastAddrs() ([]Addr, error) {
return interfaceMulticastAddrTable(ifi.Index)
}
-// Interfaces returns a list of the systems's network interfaces.
+// Interfaces returns a list of the system's network interfaces.
func Interfaces() ([]Interface, error) {
return interfaceTable(0)
}
diff --git a/libgo/go/net/interface_linux.go b/libgo/go/net/interface_linux.go
index 15c2f3781b1..825b20227ae 100644
--- a/libgo/go/net/interface_linux.go
+++ b/libgo/go/net/interface_linux.go
@@ -7,14 +7,13 @@
package net
import (
- "fmt"
"os"
"syscall"
"unsafe"
)
// If the ifindex is zero, interfaceTable returns mappings of all
-// network interfaces. Otheriwse it returns a mapping of a specific
+// network interfaces. Otherwise it returns a mapping of a specific
// interface.
func interfaceTable(ifindex int) ([]Interface, error) {
tab, err := syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC)
@@ -194,7 +193,9 @@ func parseProcNetIGMP(path string, ifi *Interface) []Addr {
name = f[1]
case len(f[0]) == 8:
if ifi == nil || name == ifi.Name {
- fmt.Sscanf(f[0], "%08x", &b)
+ for i := 0; i+1 < len(f[0]); i += 2 {
+ b[i/2], _ = xtoi2(f[0][i:i+2], 0)
+ }
ifma := IPAddr{IP: IPv4(b[3], b[2], b[1], b[0])}
ifmat = append(ifmat, ifma.toAddr())
}
@@ -218,10 +219,11 @@ func parseProcNetIGMP6(path string, ifi *Interface) []Addr {
continue
}
if ifi == nil || f[1] == ifi.Name {
- fmt.Sscanf(f[2], "%32x", &b)
+ for i := 0; i+1 < len(f[2]); i += 2 {
+ b[i/2], _ = xtoi2(f[2][i:i+2], 0)
+ }
ifma := IPAddr{IP: IP{b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]}}
ifmat = append(ifmat, ifma.toAddr())
-
}
}
return ifmat
diff --git a/libgo/go/net/interface_stub.go b/libgo/go/net/interface_stub.go
index 4876b3af353..d4d7ce9c7f8 100644
--- a/libgo/go/net/interface_stub.go
+++ b/libgo/go/net/interface_stub.go
@@ -9,7 +9,7 @@
package net
// If the ifindex is zero, interfaceTable returns mappings of all
-// network interfaces. Otheriwse it returns a mapping of a specific
+// network interfaces. Otherwise it returns a mapping of a specific
// interface.
func interfaceTable(ifindex int) ([]Interface, error) {
return nil, nil
diff --git a/libgo/go/net/interface_windows.go b/libgo/go/net/interface_windows.go
index d0c97532699..4368b330621 100644
--- a/libgo/go/net/interface_windows.go
+++ b/libgo/go/net/interface_windows.go
@@ -56,7 +56,7 @@ func getInterfaceList() ([]syscall.InterfaceInfo, error) {
}
// If the ifindex is zero, interfaceTable returns mappings of all
-// network interfaces. Otheriwse it returns a mapping of a specific
+// network interfaces. Otherwise it returns a mapping of a specific
// interface.
func interfaceTable(ifindex int) ([]Interface, error) {
ai, err := getAdapterList()
diff --git a/libgo/go/net/iprawsock_posix.go b/libgo/go/net/iprawsock_posix.go
index 9caa86985a5..6bbe67c3d9a 100644
--- a/libgo/go/net/iprawsock_posix.go
+++ b/libgo/go/net/iprawsock_posix.go
@@ -34,6 +34,13 @@ func (a *IPAddr) family() int {
return syscall.AF_INET6
}
+func (a *IPAddr) isWildcard() bool {
+ if a == nil || a.IP == nil {
+ return true
+ }
+ return a.IP.IsUnspecified()
+}
+
func (a *IPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
return ipToSockaddr(family, a.IP, 0)
}
diff --git a/libgo/go/net/ipsock_posix.go b/libgo/go/net/ipsock_posix.go
index 4841057d6be..ed313195c97 100644
--- a/libgo/go/net/ipsock_posix.go
+++ b/libgo/go/net/ipsock_posix.go
@@ -38,6 +38,7 @@ func probeIPv6Stack() (supportsIPv6, supportsIPv4map bool) {
continue
}
defer closesocket(s)
+ syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0)
sa, err := probes[i].la.toAddr().sockaddr(syscall.AF_INET6)
if err != nil {
continue
@@ -55,58 +56,75 @@ func probeIPv6Stack() (supportsIPv6, supportsIPv4map bool) {
// favoriteAddrFamily returns the appropriate address family to
// the given net, laddr, raddr and mode. At first it figures
// address family out from the net. If mode indicates "listen"
-// and laddr.(type).IP is nil, it assumes that the user wants to
-// make a passive connection with wildcard address family, both
-// INET and INET6, and wildcard address. Otherwise guess: if the
-// addresses are IPv4 then returns INET, or else returns INET6.
-func favoriteAddrFamily(net string, laddr, raddr sockaddr, mode string) int {
+// and laddr is a wildcard, it assumes that the user wants to
+// make a passive connection with a wildcard address family, both
+// AF_INET and AF_INET6, and a wildcard address like following:
+//
+// 1. A wild-wild listen, "tcp" + ""
+// If the platform supports both IPv6 and IPv6 IPv4-mapping
+// capabilities, we assume that the user want to listen on
+// both IPv4 and IPv6 wildcard address over an AF_INET6
+// socket with IPV6_V6ONLY=0. Otherwise we prefer an IPv4
+// wildcard address listen over an AF_INET socket.
+//
+// 2. A wild-ipv4wild listen, "tcp" + "0.0.0.0"
+// Same as 1.
+//
+// 3. A wild-ipv6wild listen, "tcp" + "[::]"
+// Almost same as 1 but we prefer an IPv6 wildcard address
+// listen over an AF_INET6 socket with IPV6_V6ONLY=0 when
+// the platform supports IPv6 capability but not IPv6 IPv4-
+// mapping capability.
+//
+// 4. A ipv4-ipv4wild listen, "tcp4" + "" or "0.0.0.0"
+// We use an IPv4 (AF_INET) wildcard address listen.
+//
+// 5. A ipv6-ipv6wild listen, "tcp6" + "" or "[::]"
+// We use an IPv6 (AF_INET6, IPV6_V6ONLY=1) wildcard address
+// listen.
+//
+// Otherwise guess: if the addresses are IPv4 then returns AF_INET,
+// or else returns AF_INET6. It also returns a boolean value what
+// designates IPV6_V6ONLY option.
+//
+// Note that OpenBSD allows neither "net.inet6.ip6.v6only=1" change
+// nor IPPROTO_IPV6 level IPV6_V6ONLY socket option setting.
+func favoriteAddrFamily(net string, laddr, raddr sockaddr, mode string) (family int, ipv6only bool) {
switch net[len(net)-1] {
case '4':
- return syscall.AF_INET
+ return syscall.AF_INET, false
case '6':
- return syscall.AF_INET6
+ return syscall.AF_INET6, true
}
- if mode == "listen" {
- // Note that OpenBSD allows neither "net.inet6.ip6.v6only"
- // change nor IPPROTO_IPV6 level IPV6_V6ONLY socket option
- // setting.
- switch a := laddr.(type) {
- case *TCPAddr:
- if a.IP == nil && supportsIPv6 && supportsIPv4map {
- return syscall.AF_INET6
- }
- case *UDPAddr:
- if a.IP == nil && supportsIPv6 && supportsIPv4map {
- return syscall.AF_INET6
- }
- case *IPAddr:
- if a.IP == nil && supportsIPv6 && supportsIPv4map {
- return syscall.AF_INET6
- }
+ if mode == "listen" && laddr.isWildcard() {
+ if supportsIPv4map {
+ return syscall.AF_INET6, false
}
+ return laddr.family(), false
}
if (laddr == nil || laddr.family() == syscall.AF_INET) &&
(raddr == nil || raddr.family() == syscall.AF_INET) {
- return syscall.AF_INET
+ return syscall.AF_INET, false
}
- return syscall.AF_INET6
+ return syscall.AF_INET6, false
}
-// Internet sockets (TCP, UDP)
+// Internet sockets (TCP, UDP, IP)
-// A sockaddr represents a TCP or UDP network address that can
+// A sockaddr represents a TCP, UDP or IP network address that can
// be converted into a syscall.Sockaddr.
type sockaddr interface {
Addr
- sockaddr(family int) (syscall.Sockaddr, error)
family() int
+ isWildcard() bool
+ sockaddr(family int) (syscall.Sockaddr, error)
}
func internetSocket(net string, laddr, raddr sockaddr, sotype, proto int, mode string, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err error) {
var la, ra syscall.Sockaddr
- family := favoriteAddrFamily(net, laddr, raddr, mode)
+ family, ipv6only := favoriteAddrFamily(net, laddr, raddr, mode)
if laddr != nil {
if la, err = laddr.sockaddr(family); err != nil {
goto Error
@@ -117,7 +135,7 @@ func internetSocket(net string, laddr, raddr sockaddr, sotype, proto int, mode s
goto Error
}
}
- fd, err = socket(net, family, sotype, proto, la, ra, toAddr)
+ fd, err = socket(net, family, sotype, proto, ipv6only, la, ra, toAddr)
if err != nil {
goto Error
}
@@ -152,7 +170,7 @@ func ipToSockaddr(family int, ip IP, port int) (syscall.Sockaddr, error) {
}
// IPv4 callers use 0.0.0.0 to mean "announce on any available address".
// In IPv6 mode, Linux treats that as meaning "announce on 0.0.0.0",
- // which it refuses to do. Rewrite to the IPv6 all zeros.
+ // which it refuses to do. Rewrite to the IPv6 unspecified address.
if ip.Equal(IPv4zero) {
ip = IPv6zero
}
diff --git a/libgo/go/net/mac.go b/libgo/go/net/mac.go
index e0637d00b74..d616b1f689f 100644
--- a/libgo/go/net/mac.go
+++ b/libgo/go/net/mac.go
@@ -6,24 +6,26 @@
package net
-import (
- "bytes"
- "errors"
- "fmt"
-)
+import "errors"
+
+const hexDigit = "0123456789abcdef"
// A HardwareAddr represents a physical hardware address.
type HardwareAddr []byte
func (a HardwareAddr) String() string {
- var buf bytes.Buffer
+ if len(a) == 0 {
+ return ""
+ }
+ buf := make([]byte, 0, len(a)*3-1)
for i, b := range a {
if i > 0 {
- buf.WriteByte(':')
+ buf = append(buf, ':')
}
- fmt.Fprintf(&buf, "%02x", b)
+ buf = append(buf, hexDigit[b>>4])
+ buf = append(buf, hexDigit[b&0xF])
}
- return buf.String()
+ return string(buf)
}
// ParseMAC parses s as an IEEE 802 MAC-48, EUI-48, or EUI-64 using one of the
diff --git a/libgo/go/net/mac_test.go b/libgo/go/net/mac_test.go
index 3837e740cf9..8f9dc6685f8 100644
--- a/libgo/go/net/mac_test.go
+++ b/libgo/go/net/mac_test.go
@@ -43,12 +43,24 @@ func match(err error, s string) bool {
return err != nil && strings.Contains(err.Error(), s)
}
-func TestParseMAC(t *testing.T) {
- for _, tt := range mactests {
+func TestMACParseString(t *testing.T) {
+ for i, tt := range mactests {
out, err := ParseMAC(tt.in)
if !reflect.DeepEqual(out, tt.out) || !match(err, tt.err) {
t.Errorf("ParseMAC(%q) = %v, %v, want %v, %v", tt.in, out, err, tt.out,
tt.err)
}
+ if tt.err == "" {
+ // Verify that serialization works too, and that it round-trips.
+ s := out.String()
+ out2, err := ParseMAC(s)
+ if err != nil {
+ t.Errorf("%d. ParseMAC(%q) = %v", i, s, err)
+ continue
+ }
+ if !reflect.DeepEqual(out2, out) {
+ t.Errorf("%d. ParseMAC(%q) = %v, want %v", i, s, out2, out)
+ }
+ }
}
}
diff --git a/libgo/go/net/mail/message.go b/libgo/go/net/mail/message.go
index bf22c711e49..0917bbedf1b 100644
--- a/libgo/go/net/mail/message.go
+++ b/libgo/go/net/mail/message.go
@@ -394,8 +394,7 @@ func (p *addrParser) consumeAtom(dot bool) (atom string, err error) {
i := 1
for ; i < p.len() && isAtext((*p)[i], dot); i++ {
}
- // TODO(dsymonds): Remove the []byte() conversion here when 6g doesn't need it.
- atom, *p = string([]byte((*p)[:i])), (*p)[i:]
+ atom, *p = string((*p)[:i]), (*p)[i:]
return atom, nil
}
diff --git a/libgo/go/net/multicast_test.go b/libgo/go/net/multicast_test.go
index 1d760c21051..67261b1ee77 100644
--- a/libgo/go/net/multicast_test.go
+++ b/libgo/go/net/multicast_test.go
@@ -47,9 +47,11 @@ var multicastListenerTests = []struct {
func TestMulticastListener(t *testing.T) {
switch runtime.GOOS {
case "netbsd", "openbsd", "plan9", "windows":
+ t.Logf("skipping test on %q", runtime.GOOS)
return
case "linux":
if runtime.GOARCH == "arm" || runtime.GOARCH == "alpha" {
+ t.Logf("skipping test on %q/%q", runtime.GOOS, runtime.GOARCH)
return
}
}
@@ -86,7 +88,13 @@ func TestMulticastListener(t *testing.T) {
func TestSimpleMulticastListener(t *testing.T) {
switch runtime.GOOS {
case "plan9":
+ t.Logf("skipping test on %q", runtime.GOOS)
return
+ case "windows":
+ if testing.Short() || !*testExternal {
+ t.Logf("skipping test on windows to avoid firewall")
+ return
+ }
}
for _, tt := range multicastListenerTests {
diff --git a/libgo/go/net/net.go b/libgo/go/net/net.go
index bf242ff8dd6..9ebcdbe996c 100644
--- a/libgo/go/net/net.go
+++ b/libgo/go/net/net.go
@@ -54,6 +54,8 @@ type Addr interface {
}
// Conn is a generic stream-oriented network connection.
+//
+// Multiple goroutines may invoke methods on a Conn simultaneously.
type Conn interface {
// Read reads data from the connection.
// Read can be made to time out and return a Error with Timeout() == true
@@ -66,6 +68,7 @@ type Conn interface {
Write(b []byte) (n int, err error)
// Close closes the connection.
+ // Any blocked Read or Write operations will be unblocked and return errors.
Close() error
// LocalAddr returns the local network address.
@@ -89,11 +92,11 @@ type Conn interface {
// A zero value for t means I/O operations will not time out.
SetDeadline(t time.Time) error
- // SetReadDeadline sets the deadline for Read calls.
+ // SetReadDeadline sets the deadline for future Read calls.
// A zero value for t means Read will not time out.
SetReadDeadline(t time.Time) error
- // SetWriteDeadline sets the deadline for Write calls.
+ // SetWriteDeadline sets the deadline for future Write calls.
// Even if write times out, it may return n > 0, indicating that
// some of the data was successfully written.
// A zero value for t means Write will not time out.
@@ -108,6 +111,8 @@ type Error interface {
}
// PacketConn is a generic packet-oriented network connection.
+//
+// Multiple goroutines may invoke methods on a PacketConn simultaneously.
type PacketConn interface {
// ReadFrom reads a packet from the connection,
// copying the payload into b. It returns the number of
@@ -126,6 +131,7 @@ type PacketConn interface {
WriteTo(b []byte, addr Addr) (n int, err error)
// Close closes the connection.
+ // Any blocked ReadFrom or WriteTo operations will be unblocked and return errors.
Close() error
// LocalAddr returns the local network address.
@@ -135,13 +141,13 @@ type PacketConn interface {
// with the connection.
SetDeadline(t time.Time) error
- // SetReadDeadline sets the deadline for all Read calls to return.
+ // SetReadDeadline sets the deadline for future Read calls.
// If the deadline is reached, Read will fail with a timeout
// (see type Error) instead of blocking.
// A zero value for t means Read will not time out.
SetReadDeadline(t time.Time) error
- // SetWriteDeadline sets the deadline for all Write calls to return.
+ // SetWriteDeadline sets the deadline for future Write calls.
// If the deadline is reached, Write will fail with a timeout
// (see type Error) instead of blocking.
// A zero value for t means Write will not time out.
@@ -151,11 +157,14 @@ type PacketConn interface {
}
// A Listener is a generic network listener for stream-oriented protocols.
+//
+// Multiple goroutines may invoke methods on a Listener simultaneously.
type Listener interface {
// Accept waits for and returns the next connection to the listener.
Accept() (c Conn, err error)
// Close closes the listener.
+ // Any blocked Accept operations will be unblocked and return errors.
Close() error
// Addr returns the listener's network address.
diff --git a/libgo/go/net/net_test.go b/libgo/go/net/net_test.go
index c1a90de0131..fd145e1d70f 100644
--- a/libgo/go/net/net_test.go
+++ b/libgo/go/net/net_test.go
@@ -13,6 +13,7 @@ import (
func TestShutdown(t *testing.T) {
if runtime.GOOS == "plan9" {
+ t.Logf("skipping test on %q", runtime.GOOS)
return
}
l, err := Listen("tcp", "127.0.0.1:0")
diff --git a/libgo/go/net/parse_test.go b/libgo/go/net/parse_test.go
index dfbaba4d9e8..30fda45dfd4 100644
--- a/libgo/go/net/parse_test.go
+++ b/libgo/go/net/parse_test.go
@@ -13,7 +13,9 @@ import (
func TestReadLine(t *testing.T) {
// /etc/services file does not exist on windows and Plan 9.
- if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
+ switch runtime.GOOS {
+ case "plan9", "windows":
+ t.Logf("skipping test on %q", runtime.GOOS)
return
}
filename := "/etc/services" // a nice big file
diff --git a/libgo/go/net/rpc/client.go b/libgo/go/net/rpc/client.go
index f7abf21f157..db2da8e4418 100644
--- a/libgo/go/net/rpc/client.go
+++ b/libgo/go/net/rpc/client.go
@@ -36,7 +36,8 @@ type Call struct {
// Client represents an RPC Client.
// There may be multiple outstanding Calls associated
-// with a single Client.
+// with a single Client, and a Client may be used by
+// multiple goroutines simultaneously.
type Client struct {
mutex sync.Mutex // protects pending, seq, request
sending sync.Mutex
diff --git a/libgo/go/net/server_test.go b/libgo/go/net/server_test.go
index b9862168153..158b9477d03 100644
--- a/libgo/go/net/server_test.go
+++ b/libgo/go/net/server_test.go
@@ -9,234 +9,461 @@ import (
"io"
"os"
"runtime"
- "strings"
"testing"
"time"
)
-// Do not test empty datagrams by default.
-// It causes unexplained timeouts on some systems,
-// including Snow Leopard. I think that the kernel
-// doesn't quite expect them.
-var testUDP = flag.Bool("udp", false, "whether to test UDP datagrams")
+func skipServerTest(net, unixsotype, addr string, ipv6, ipv4map, linuxonly bool) bool {
+ switch runtime.GOOS {
+ case "linux":
+ case "plan9", "windows":
+ // "unix" sockets are not supported on Windows and Plan 9.
+ if net == unixsotype {
+ return true
+ }
+ default:
+ if net == unixsotype && linuxonly {
+ return true
+ }
+ }
+ switch addr {
+ case "", "0.0.0.0", "[::ffff:0.0.0.0]", "[::]":
+ if testing.Short() || !*testExternal {
+ return true
+ }
+ }
+ if ipv6 && !supportsIPv6 {
+ return true
+ }
+ if ipv4map && !supportsIPv4map {
+ return true
+ }
+ return false
+}
-func runEcho(fd io.ReadWriter, done chan<- int) {
- var buf [1024]byte
+var streamConnServerTests = []struct {
+ snet string // server side
+ saddr string
+ cnet string // client side
+ caddr string
+ ipv6 bool // test with underlying AF_INET6 socket
+ ipv4map bool // test with IPv6 IPv4-mapping functionality
+ empty bool // test with empty data
+ linux bool // test with abstract unix domain socket, a Linux-ism
+}{
+ {snet: "tcp", saddr: "", cnet: "tcp", caddr: "127.0.0.1"},
+ {snet: "tcp", saddr: "0.0.0.0", cnet: "tcp", caddr: "127.0.0.1"},
+ {snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp", caddr: "127.0.0.1"},
+ {snet: "tcp", saddr: "[::]", cnet: "tcp", caddr: "[::1]", ipv6: true},
- for {
- n, err := fd.Read(buf[0:])
- if err != nil || n == 0 || string(buf[:n]) == "END" {
- break
+ {snet: "tcp", saddr: "", cnet: "tcp", caddr: "[::1]", ipv4map: true},
+ {snet: "tcp", saddr: "0.0.0.0", cnet: "tcp", caddr: "[::1]", ipv4map: true},
+ {snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp", caddr: "[::1]", ipv4map: true},
+ {snet: "tcp", saddr: "[::]", cnet: "tcp", caddr: "127.0.0.1", ipv4map: true},
+
+ {snet: "tcp", saddr: "", cnet: "tcp4", caddr: "127.0.0.1"},
+ {snet: "tcp", saddr: "0.0.0.0", cnet: "tcp4", caddr: "127.0.0.1"},
+ {snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp4", caddr: "127.0.0.1"},
+ {snet: "tcp", saddr: "[::]", cnet: "tcp6", caddr: "[::1]", ipv6: true},
+
+ {snet: "tcp", saddr: "", cnet: "tcp6", caddr: "[::1]", ipv4map: true},
+ {snet: "tcp", saddr: "0.0.0.0", cnet: "tcp6", caddr: "[::1]", ipv4map: true},
+ {snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp6", caddr: "[::1]", ipv4map: true},
+ {snet: "tcp", saddr: "[::]", cnet: "tcp4", caddr: "127.0.0.1", ipv4map: true},
+
+ {snet: "tcp", saddr: "127.0.0.1", cnet: "tcp", caddr: "127.0.0.1"},
+ {snet: "tcp", saddr: "[::ffff:127.0.0.1]", cnet: "tcp", caddr: "127.0.0.1"},
+ {snet: "tcp", saddr: "[::1]", cnet: "tcp", caddr: "[::1]", ipv6: true},
+
+ {snet: "tcp4", saddr: "", cnet: "tcp4", caddr: "127.0.0.1"},
+ {snet: "tcp4", saddr: "0.0.0.0", cnet: "tcp4", caddr: "127.0.0.1"},
+ {snet: "tcp4", saddr: "[::ffff:0.0.0.0]", cnet: "tcp4", caddr: "127.0.0.1"},
+
+ {snet: "tcp4", saddr: "127.0.0.1", cnet: "tcp4", caddr: "127.0.0.1"},
+
+ {snet: "tcp6", saddr: "", cnet: "tcp6", caddr: "[::1]", ipv6: true},
+ {snet: "tcp6", saddr: "[::]", cnet: "tcp6", caddr: "[::1]", ipv6: true},
+
+ {snet: "tcp6", saddr: "[::1]", cnet: "tcp6", caddr: "[::1]", ipv6: true},
+
+ {snet: "unix", saddr: "/tmp/gotest1.net", cnet: "unix", caddr: "/tmp/gotest1.net.local"},
+ {snet: "unix", saddr: "@gotest2/net", cnet: "unix", caddr: "@gotest2/net.local", linux: true},
+}
+
+func TestStreamConnServer(t *testing.T) {
+ for _, tt := range streamConnServerTests {
+ if skipServerTest(tt.snet, "unix", tt.saddr, tt.ipv6, tt.ipv4map, tt.linux) {
+ continue
+ }
+
+ listening := make(chan string)
+ done := make(chan int)
+ switch tt.snet {
+ case "tcp", "tcp4", "tcp6":
+ tt.saddr += ":0"
+ case "unix":
+ os.Remove(tt.saddr)
+ os.Remove(tt.caddr)
+ }
+
+ go runStreamConnServer(t, tt.snet, tt.saddr, listening, done)
+ taddr := <-listening // wait for server to start
+
+ switch tt.cnet {
+ case "tcp", "tcp4", "tcp6":
+ _, port, err := SplitHostPort(taddr)
+ if err != nil {
+ t.Errorf("SplitHostPort(%q) failed: %v", taddr, err)
+ return
+ }
+ taddr = tt.caddr + ":" + port
+ }
+
+ runStreamConnClient(t, tt.cnet, taddr, tt.empty)
+ <-done // make sure server stopped
+
+ switch tt.snet {
+ case "unix":
+ os.Remove(tt.saddr)
+ os.Remove(tt.caddr)
+ }
+ }
+}
+
+var seqpacketConnServerTests = []struct {
+ net string
+ saddr string // server address
+ caddr string // client address
+ empty bool // test with empty data
+}{
+ {net: "unixpacket", saddr: "/tmp/gotest3.net", caddr: "/tmp/gotest3.net.local"},
+ {net: "unixpacket", saddr: "@gotest4/net", caddr: "@gotest4/net.local"},
+}
+
+func TestSeqpacketConnServer(t *testing.T) {
+ if runtime.GOOS != "linux" {
+ t.Logf("skipping test on %q", runtime.GOOS)
+ return
+ }
+
+ for _, tt := range seqpacketConnServerTests {
+ listening := make(chan string)
+ done := make(chan int)
+ switch tt.net {
+ case "unixpacket":
+ os.Remove(tt.saddr)
+ os.Remove(tt.caddr)
+ }
+
+ go runStreamConnServer(t, tt.net, tt.saddr, listening, done)
+ taddr := <-listening // wait for server to start
+
+ runStreamConnClient(t, tt.net, taddr, tt.empty)
+ <-done // make sure server stopped
+
+ switch tt.net {
+ case "unixpacket":
+ os.Remove(tt.saddr)
+ os.Remove(tt.caddr)
}
- fd.Write(buf[0:n])
}
- done <- 1
}
-func runServe(t *testing.T, network, addr string, listening chan<- string, done chan<- int) {
- l, err := Listen(network, addr)
+func runStreamConnServer(t *testing.T, net, laddr string, listening chan<- string, done chan<- int) {
+ l, err := Listen(net, laddr)
if err != nil {
- t.Fatalf("net.Listen(%q, %q) = _, %v", network, addr, err)
+ t.Errorf("Listen(%q, %q) failed: %v", net, laddr, err)
+ listening <- "<nil>"
+ done <- 1
+ return
}
+ defer l.Close()
listening <- l.Addr().String()
+ echo := func(rw io.ReadWriter, done chan<- int) {
+ buf := make([]byte, 1024)
+ for {
+ n, err := rw.Read(buf[0:])
+ if err != nil || n == 0 || string(buf[:n]) == "END" {
+ break
+ }
+ rw.Write(buf[0:n])
+ }
+ done <- 1
+ }
+
+run:
for {
- fd, err := l.Accept()
+ c, err := l.Accept()
if err != nil {
- break
+ continue run
}
echodone := make(chan int)
- go runEcho(fd, echodone)
- <-echodone // make sure Echo stops
- l.Close()
+ go echo(c, echodone)
+ <-echodone // make sure echo stopped
+ c.Close()
+ break run
}
done <- 1
}
-func connect(t *testing.T, network, addr string, isEmpty bool) {
- var fd Conn
- var err error
- if network == "unixgram" {
- fd, err = DialUnix(network, &UnixAddr{addr + ".local", network}, &UnixAddr{addr, network})
- } else {
- fd, err = Dial(network, addr)
- }
+func runStreamConnClient(t *testing.T, net, taddr string, isEmpty bool) {
+ c, err := Dial(net, taddr)
if err != nil {
- t.Fatalf("net.Dial(%q, %q) = _, %v", network, addr, err)
+ t.Errorf("Dial(%q, %q) failed: %v", net, taddr, err)
+ return
}
- fd.SetReadDeadline(time.Now().Add(1 * time.Second))
+ defer c.Close()
+ c.SetReadDeadline(time.Now().Add(1 * time.Second))
- var b []byte
+ var wb []byte
if !isEmpty {
- b = []byte("hello, world\n")
+ wb = []byte("StreamConnClient by Dial\n")
}
- var b1 [100]byte
-
- n, err1 := fd.Write(b)
- if n != len(b) {
- t.Fatalf("fd.Write(%q) = %d, %v", b, n, err1)
+ if n, err := c.Write(wb); err != nil || n != len(wb) {
+ t.Errorf("Write failed: %v, %v; want %v, <nil>", n, err, len(wb))
+ return
}
- n, err1 = fd.Read(b1[0:])
- if n != len(b) || err1 != nil {
- t.Fatalf("fd.Read() = %d, %v (want %d, nil)", n, err1, len(b))
+ rb := make([]byte, 1024)
+ if n, err := c.Read(rb[0:]); err != nil || n != len(wb) {
+ t.Errorf("Read failed: %v, %v; want %v, <nil>", n, err, len(wb))
+ return
}
// Send explicit ending for unixpacket.
// Older Linux kernels do not stop reads on close.
- if network == "unixpacket" {
- fd.Write([]byte("END"))
+ switch net {
+ case "unixpacket":
+ c.Write([]byte("END"))
}
-
- fd.Close()
}
-func doTest(t *testing.T, network, listenaddr, dialaddr string) {
- t.Logf("Test %q %q %q", network, listenaddr, dialaddr)
- switch listenaddr {
- case "", "0.0.0.0", "[::]", "[::ffff:0.0.0.0]":
- if testing.Short() || !*testExternal {
- t.Logf("skip wildcard listen during short test")
- return
- }
- }
- listening := make(chan string)
- done := make(chan int)
- if network == "tcp" || network == "tcp4" || network == "tcp6" {
- listenaddr += ":0" // any available port
- }
- go runServe(t, network, listenaddr, listening, done)
- addr := <-listening // wait for server to start
- if network == "tcp" || network == "tcp4" || network == "tcp6" {
- dialaddr += addr[strings.LastIndex(addr, ":"):]
- }
- connect(t, network, dialaddr, false)
- <-done // make sure server stopped
-}
+// Do not test empty datagrams by default.
+// It causes unexplained timeouts on some systems,
+// including Snow Leopard. I think that the kernel
+// doesn't quite expect them.
+var testDatagram = flag.Bool("datagram", false, "whether to test udp and unixgram")
-func TestTCPServer(t *testing.T) {
- doTest(t, "tcp", "", "127.0.0.1")
- doTest(t, "tcp", "0.0.0.0", "127.0.0.1")
- doTest(t, "tcp", "127.0.0.1", "127.0.0.1")
- doTest(t, "tcp4", "", "127.0.0.1")
- doTest(t, "tcp4", "0.0.0.0", "127.0.0.1")
- doTest(t, "tcp4", "127.0.0.1", "127.0.0.1")
- if supportsIPv6 {
- doTest(t, "tcp", "[::]", "[::1]")
- doTest(t, "tcp", "[::1]", "[::1]")
- doTest(t, "tcp6", "", "[::1]")
- doTest(t, "tcp6", "[::]", "[::1]")
- doTest(t, "tcp6", "[::1]", "[::1]")
- }
- if supportsIPv6 && supportsIPv4map {
- doTest(t, "tcp", "[::ffff:0.0.0.0]", "127.0.0.1")
- doTest(t, "tcp", "[::]", "127.0.0.1")
- doTest(t, "tcp4", "[::ffff:0.0.0.0]", "127.0.0.1")
- doTest(t, "tcp6", "", "127.0.0.1")
- doTest(t, "tcp6", "[::ffff:0.0.0.0]", "127.0.0.1")
- doTest(t, "tcp6", "[::]", "127.0.0.1")
- doTest(t, "tcp", "127.0.0.1", "[::ffff:127.0.0.1]")
- doTest(t, "tcp", "[::ffff:127.0.0.1]", "127.0.0.1")
- doTest(t, "tcp4", "127.0.0.1", "[::ffff:127.0.0.1]")
- doTest(t, "tcp4", "[::ffff:127.0.0.1]", "127.0.0.1")
- doTest(t, "tcp6", "127.0.0.1", "[::ffff:127.0.0.1]")
- doTest(t, "tcp6", "[::ffff:127.0.0.1]", "127.0.0.1")
- }
+var datagramPacketConnServerTests = []struct {
+ snet string // server side
+ saddr string
+ cnet string // client side
+ caddr string
+ ipv6 bool // test with underlying AF_INET6 socket
+ ipv4map bool // test with IPv6 IPv4-mapping functionality
+ dial bool // test with Dial or DialUnix
+ empty bool // test with empty data
+ linux bool // test with abstract unix domain socket, a Linux-ism
+}{
+ {snet: "udp", saddr: "", cnet: "udp", caddr: "127.0.0.1"},
+ {snet: "udp", saddr: "0.0.0.0", cnet: "udp", caddr: "127.0.0.1"},
+ {snet: "udp", saddr: "[::ffff:0.0.0.0]", cnet: "udp", caddr: "127.0.0.1"},
+ {snet: "udp", saddr: "[::]", cnet: "udp", caddr: "[::1]", ipv6: true},
+
+ {snet: "udp", saddr: "", cnet: "udp", caddr: "[::1]", ipv4map: true},
+ {snet: "udp", saddr: "0.0.0.0", cnet: "udp", caddr: "[::1]", ipv4map: true},
+ {snet: "udp", saddr: "[::ffff:0.0.0.0]", cnet: "udp", caddr: "[::1]", ipv4map: true},
+ {snet: "udp", saddr: "[::]", cnet: "udp", caddr: "127.0.0.1", ipv4map: true},
+
+ {snet: "udp", saddr: "", cnet: "udp4", caddr: "127.0.0.1"},
+ {snet: "udp", saddr: "0.0.0.0", cnet: "udp4", caddr: "127.0.0.1"},
+ {snet: "udp", saddr: "[::ffff:0.0.0.0]", cnet: "udp4", caddr: "127.0.0.1"},
+ {snet: "udp", saddr: "[::]", cnet: "udp6", caddr: "[::1]", ipv6: true},
+
+ {snet: "udp", saddr: "", cnet: "udp6", caddr: "[::1]", ipv4map: true},
+ {snet: "udp", saddr: "0.0.0.0", cnet: "udp6", caddr: "[::1]", ipv4map: true},
+ {snet: "udp", saddr: "[::ffff:0.0.0.0]", cnet: "udp6", caddr: "[::1]", ipv4map: true},
+ {snet: "udp", saddr: "[::]", cnet: "udp4", caddr: "127.0.0.1", ipv4map: true},
+
+ {snet: "udp", saddr: "127.0.0.1", cnet: "udp", caddr: "127.0.0.1"},
+ {snet: "udp", saddr: "[::ffff:127.0.0.1]", cnet: "udp", caddr: "127.0.0.1"},
+ {snet: "udp", saddr: "[::1]", cnet: "udp", caddr: "[::1]", ipv6: true},
+
+ {snet: "udp4", saddr: "", cnet: "udp4", caddr: "127.0.0.1"},
+ {snet: "udp4", saddr: "0.0.0.0", cnet: "udp4", caddr: "127.0.0.1"},
+ {snet: "udp4", saddr: "[::ffff:0.0.0.0]", cnet: "udp4", caddr: "127.0.0.1"},
+
+ {snet: "udp4", saddr: "127.0.0.1", cnet: "udp4", caddr: "127.0.0.1"},
+
+ {snet: "udp6", saddr: "", cnet: "udp6", caddr: "[::1]", ipv6: true},
+ {snet: "udp6", saddr: "[::]", cnet: "udp6", caddr: "[::1]", ipv6: true},
+
+ {snet: "udp6", saddr: "[::1]", cnet: "udp6", caddr: "[::1]", ipv6: true},
+
+ {snet: "udp", saddr: "127.0.0.1", cnet: "udp", caddr: "127.0.0.1", dial: true},
+ {snet: "udp", saddr: "127.0.0.1", cnet: "udp", caddr: "127.0.0.1", empty: true},
+ {snet: "udp", saddr: "127.0.0.1", cnet: "udp", caddr: "127.0.0.1", dial: true, empty: true},
+
+ {snet: "udp", saddr: "[::1]", cnet: "udp", caddr: "[::1]", ipv6: true, dial: true},
+ {snet: "udp", saddr: "[::1]", cnet: "udp", caddr: "[::1]", ipv6: true, empty: true},
+ {snet: "udp", saddr: "[::1]", cnet: "udp", caddr: "[::1]", ipv6: true, dial: true, empty: true},
+
+ {snet: "unixgram", saddr: "/tmp/gotest5.net", cnet: "unixgram", caddr: "/tmp/gotest5.net.local"},
+ {snet: "unixgram", saddr: "/tmp/gotest5.net", cnet: "unixgram", caddr: "/tmp/gotest5.net.local", dial: true},
+ {snet: "unixgram", saddr: "/tmp/gotest5.net", cnet: "unixgram", caddr: "/tmp/gotest5.net.local", empty: true},
+ {snet: "unixgram", saddr: "/tmp/gotest5.net", cnet: "unixgram", caddr: "/tmp/gotest5.net.local", dial: true, empty: true},
+
+ {snet: "unixgram", saddr: "@gotest6/net", cnet: "unixgram", caddr: "@gotest6/net.local", linux: true},
}
-func TestUnixServer(t *testing.T) {
- // "unix" sockets are not supported on windows and Plan 9.
- if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
+func TestDatagramPacketConnServer(t *testing.T) {
+ if !*testDatagram {
return
}
- os.Remove("/tmp/gotest.net")
- doTest(t, "unix", "/tmp/gotest.net", "/tmp/gotest.net")
- os.Remove("/tmp/gotest.net")
- if runtime.GOOS == "linux" {
- doTest(t, "unixpacket", "/tmp/gotest.net", "/tmp/gotest.net")
- os.Remove("/tmp/gotest.net")
- // Test abstract unix domain socket, a Linux-ism
- doTest(t, "unix", "@gotest/net", "@gotest/net")
- doTest(t, "unixpacket", "@gotest/net", "@gotest/net")
+
+ for _, tt := range datagramPacketConnServerTests {
+ if skipServerTest(tt.snet, "unixgram", tt.saddr, tt.ipv6, tt.ipv4map, tt.linux) {
+ continue
+ }
+
+ listening := make(chan string)
+ done := make(chan int)
+ switch tt.snet {
+ case "udp", "udp4", "udp6":
+ tt.saddr += ":0"
+ case "unixgram":
+ os.Remove(tt.saddr)
+ os.Remove(tt.caddr)
+ }
+
+ go runDatagramPacketConnServer(t, tt.snet, tt.saddr, listening, done)
+ taddr := <-listening // wait for server to start
+
+ switch tt.cnet {
+ case "udp", "udp4", "udp6":
+ _, port, err := SplitHostPort(taddr)
+ if err != nil {
+ t.Errorf("SplitHostPort(%q) failed: %v", taddr, err)
+ return
+ }
+ taddr = tt.caddr + ":" + port
+ tt.caddr += ":0"
+ }
+ if tt.dial {
+ runDatagramConnClient(t, tt.cnet, tt.caddr, taddr, tt.empty)
+ } else {
+ runDatagramPacketConnClient(t, tt.cnet, tt.caddr, taddr, tt.empty)
+ }
+ <-done // tell server to stop
+ <-done // make sure server stopped
+
+ switch tt.snet {
+ case "unixgram":
+ os.Remove(tt.saddr)
+ os.Remove(tt.caddr)
+ }
}
}
-func runPacket(t *testing.T, network, addr string, listening chan<- string, done chan<- int) {
- c, err := ListenPacket(network, addr)
+func runDatagramPacketConnServer(t *testing.T, net, laddr string, listening chan<- string, done chan<- int) {
+ c, err := ListenPacket(net, laddr)
if err != nil {
- t.Fatalf("net.ListenPacket(%q, %q) = _, %v", network, addr, err)
+ t.Errorf("ListenPacket(%q, %q) failed: %v", net, laddr, err)
+ listening <- "<nil>"
+ done <- 1
+ return
}
+ defer c.Close()
listening <- c.LocalAddr().String()
- var buf [1000]byte
-Run:
+
+ buf := make([]byte, 1024)
+run:
for {
c.SetReadDeadline(time.Now().Add(10 * time.Millisecond))
- n, addr, err := c.ReadFrom(buf[0:])
- if e, ok := err.(Error); ok && e.Timeout() {
+ n, ra, err := c.ReadFrom(buf[0:])
+ if nerr, ok := err.(Error); ok && nerr.Timeout() {
select {
case done <- 1:
- break Run
+ break run
default:
- continue Run
+ continue run
}
}
if err != nil {
- break
+ break run
}
- if _, err = c.WriteTo(buf[0:n], addr); err != nil {
- t.Fatalf("WriteTo %v: %v", addr, err)
+ if _, err = c.WriteTo(buf[0:n], ra); err != nil {
+ t.Errorf("WriteTo(%v) failed: %v", ra, err)
+ break run
}
}
- c.Close()
done <- 1
}
-func doTestPacket(t *testing.T, network, listenaddr, dialaddr string, isEmpty bool) {
- t.Logf("TestPacket %q %q %q", network, listenaddr, dialaddr)
- listening := make(chan string)
- done := make(chan int)
- if network == "udp" {
- listenaddr += ":0" // any available port
- }
- go runPacket(t, network, listenaddr, listening, done)
- addr := <-listening // wait for server to start
- if network == "udp" {
- dialaddr += addr[strings.LastIndex(addr, ":"):]
- }
- connect(t, network, dialaddr, isEmpty)
- <-done // tell server to stop
- <-done // wait for stop
-}
+func runDatagramConnClient(t *testing.T, net, laddr, taddr string, isEmpty bool) {
+ var c Conn
+ var err error
+ switch net {
+ case "udp", "udp4", "udp6":
+ c, err = Dial(net, taddr)
+ if err != nil {
+ t.Errorf("Dial(%q, %q) failed: %v", net, taddr, err)
+ return
+ }
+ case "unixgram":
+ c, err = DialUnix(net, &UnixAddr{laddr, net}, &UnixAddr{taddr, net})
+ if err != nil {
+ t.Errorf("DialUnix(%q, {%q, %q}) failed: %v", net, laddr, taddr, err)
+ return
+ }
+ }
+ defer c.Close()
+ c.SetReadDeadline(time.Now().Add(1 * time.Second))
-func TestUDPServer(t *testing.T) {
- if !*testUDP {
+ var wb []byte
+ if !isEmpty {
+ wb = []byte("DatagramConnClient by Dial\n")
+ }
+ if n, err := c.Write(wb[0:]); err != nil || n != len(wb) {
+ t.Errorf("Write failed: %v, %v; want %v, <nil>", n, err, len(wb))
return
}
- for _, isEmpty := range []bool{false, true} {
- doTestPacket(t, "udp", "0.0.0.0", "127.0.0.1", isEmpty)
- doTestPacket(t, "udp", "", "127.0.0.1", isEmpty)
- if supportsIPv6 && supportsIPv4map {
- doTestPacket(t, "udp", "[::]", "[::ffff:127.0.0.1]", isEmpty)
- doTestPacket(t, "udp", "[::]", "127.0.0.1", isEmpty)
- doTestPacket(t, "udp", "0.0.0.0", "[::ffff:127.0.0.1]", isEmpty)
- }
+
+ rb := make([]byte, 1024)
+ if n, err := c.Read(rb[0:]); err != nil || n != len(wb) {
+ t.Errorf("Read failed: %v, %v; want %v, <nil>", n, err, len(wb))
+ return
}
}
-func TestUnixDatagramServer(t *testing.T) {
- // "unix" sockets are not supported on windows and Plan 9.
- if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
+func runDatagramPacketConnClient(t *testing.T, net, laddr, taddr string, isEmpty bool) {
+ var ra Addr
+ var err error
+ switch net {
+ case "udp", "udp4", "udp6":
+ ra, err = ResolveUDPAddr(net, taddr)
+ if err != nil {
+ t.Errorf("ResolveUDPAddr(%q, %q) failed: %v", net, taddr, err)
+ return
+ }
+ case "unixgram":
+ ra, err = ResolveUnixAddr(net, taddr)
+ if err != nil {
+ t.Errorf("ResolveUxixAddr(%q, %q) failed: %v", net, taddr, err)
+ return
+ }
+ }
+ c, err := ListenPacket(net, laddr)
+ if err != nil {
+ t.Errorf("ListenPacket(%q, %q) faild: %v", net, laddr, err)
return
}
- for _, isEmpty := range []bool{false} {
- os.Remove("/tmp/gotest1.net")
- os.Remove("/tmp/gotest1.net.local")
- doTestPacket(t, "unixgram", "/tmp/gotest1.net", "/tmp/gotest1.net", isEmpty)
- os.Remove("/tmp/gotest1.net")
- os.Remove("/tmp/gotest1.net.local")
- if runtime.GOOS == "linux" {
- // Test abstract unix domain socket, a Linux-ism
- doTestPacket(t, "unixgram", "@gotest1/net", "@gotest1/net", isEmpty)
- }
+ defer c.Close()
+ c.SetReadDeadline(time.Now().Add(1 * time.Second))
+
+ var wb []byte
+ if !isEmpty {
+ wb = []byte("DatagramPacketConnClient by ListenPacket\n")
+ }
+ if n, err := c.WriteTo(wb[0:], ra); err != nil || n != len(wb) {
+ t.Errorf("WriteTo(%v) failed: %v, %v; want %v, <nil>", ra, n, err, len(wb))
+ return
+ }
+
+ rb := make([]byte, 1024)
+ if n, _, err := c.ReadFrom(rb[0:]); err != nil || n != len(wb) {
+ t.Errorf("ReadFrom failed: %v, %v; want %v, <nil>", n, err, len(wb))
+ return
}
}
diff --git a/libgo/go/net/sock.go b/libgo/go/net/sock.go
index dc139f04a25..3ae16054e47 100644
--- a/libgo/go/net/sock.go
+++ b/libgo/go/net/sock.go
@@ -16,7 +16,7 @@ import (
var listenerBacklog = maxListenerBacklog()
// Generic socket creation.
-func socket(net string, f, t, p int, la, ra syscall.Sockaddr, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err error) {
+func socket(net string, f, t, p int, ipv6only bool, la, ra syscall.Sockaddr, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err error) {
// See ../syscall/exec.go for description of ForkLock.
syscall.ForkLock.RLock()
s, err := syscall.Socket(f, t, p)
@@ -27,7 +27,7 @@ func socket(net string, f, t, p int, la, ra syscall.Sockaddr, toAddr func(syscal
syscall.CloseOnExec(s)
syscall.ForkLock.RUnlock()
- err = setDefaultSockopts(s, f, t)
+ err = setDefaultSockopts(s, f, t, ipv6only)
if err != nil {
closesocket(s)
return nil, err
diff --git a/libgo/go/net/sockopt.go b/libgo/go/net/sockopt.go
index 0a051d7ae3c..0cd19266fe0 100644
--- a/libgo/go/net/sockopt.go
+++ b/libgo/go/net/sockopt.go
@@ -9,7 +9,6 @@
package net
import (
- "bytes"
"os"
"syscall"
"time"
@@ -98,7 +97,7 @@ func setIPv4MreqToInterface(mreq *syscall.IPMreq, ifi *Interface) error {
}
}
done:
- if bytes.Equal(mreq.Multiaddr[:], IPv4zero.To4()) {
+ if bytesEqual(mreq.Multiaddr[:], IPv4zero.To4()) {
return errNoSuchMulticastInterface
}
return nil
diff --git a/libgo/go/net/sockopt_bsd.go b/libgo/go/net/sockopt_bsd.go
index 79e0e57e21e..fff65f362b1 100644
--- a/libgo/go/net/sockopt_bsd.go
+++ b/libgo/go/net/sockopt_bsd.go
@@ -13,12 +13,17 @@ import (
"syscall"
)
-func setDefaultSockopts(s, f, t int) error {
+func setDefaultSockopts(s, f, t int, ipv6only bool) error {
switch f {
case syscall.AF_INET6:
- // Allow both IP versions even if the OS default is otherwise.
- // Note that some operating systems never admit this option.
- syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0)
+ if ipv6only {
+ syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 1)
+ } else {
+ // Allow both IP versions even if the OS default
+ // is otherwise. Note that some operating systems
+ // never admit this option.
+ syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0)
+ }
}
// Allow broadcast.
err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)
diff --git a/libgo/go/net/sockopt_linux.go b/libgo/go/net/sockopt_linux.go
index 7509c29eecf..0f47538c541 100644
--- a/libgo/go/net/sockopt_linux.go
+++ b/libgo/go/net/sockopt_linux.go
@@ -11,12 +11,17 @@ import (
"syscall"
)
-func setDefaultSockopts(s, f, t int) error {
+func setDefaultSockopts(s, f, t int, ipv6only bool) error {
switch f {
case syscall.AF_INET6:
- // Allow both IP versions even if the OS default is otherwise.
- // Note that some operating systems never admit this option.
- syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0)
+ if ipv6only {
+ syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 1)
+ } else {
+ // Allow both IP versions even if the OS default
+ // is otherwise. Note that some operating systems
+ // never admit this option.
+ syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0)
+ }
}
// Allow broadcast.
err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)
diff --git a/libgo/go/net/sockopt_windows.go b/libgo/go/net/sockopt_windows.go
index b18af67d754..509b5963bf3 100644
--- a/libgo/go/net/sockopt_windows.go
+++ b/libgo/go/net/sockopt_windows.go
@@ -11,12 +11,17 @@ import (
"syscall"
)
-func setDefaultSockopts(s syscall.Handle, f, t int) error {
+func setDefaultSockopts(s syscall.Handle, f, t int, ipv6only bool) error {
switch f {
case syscall.AF_INET6:
- // Allow both IP versions even if the OS default is otherwise.
- // Note that some operating systems never admit this option.
- syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0)
+ if ipv6only {
+ syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 1)
+ } else {
+ // Allow both IP versions even if the OS default
+ // is otherwise. Note that some operating systems
+ // never admit this option.
+ syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0)
+ }
}
// Allow broadcast.
syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)
diff --git a/libgo/go/net/tcpsock_posix.go b/libgo/go/net/tcpsock_posix.go
index e05bc10170e..15f8efdd701 100644
--- a/libgo/go/net/tcpsock_posix.go
+++ b/libgo/go/net/tcpsock_posix.go
@@ -9,7 +9,6 @@
package net
import (
- "fmt"
"io"
"os"
"syscall"
@@ -30,7 +29,7 @@ func sockaddrToTCP(sa syscall.Sockaddr) Addr {
default:
if sa != nil {
// Diagnose when we will turn a non-nil sockaddr into a nil.
- panic(fmt.Sprintf("unexpected type in sockaddrToTCP: %T", sa))
+ panic("unexpected type in sockaddrToTCP")
}
}
return nil
@@ -46,6 +45,13 @@ func (a *TCPAddr) family() int {
return syscall.AF_INET6
}
+func (a *TCPAddr) isWildcard() bool {
+ if a == nil || a.IP == nil {
+ return true
+ }
+ return a.IP.IsUnspecified()
+}
+
func (a *TCPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
return ipToSockaddr(family, a.IP, a.Port)
}
diff --git a/libgo/go/net/timeout_test.go b/libgo/go/net/timeout_test.go
index ef350f0f946..672fb7241d7 100644
--- a/libgo/go/net/timeout_test.go
+++ b/libgo/go/net/timeout_test.go
@@ -11,13 +11,13 @@ import (
"time"
)
-func testTimeout(t *testing.T, network, addr string, readFrom bool) {
- fd, err := Dial(network, addr)
+func testTimeout(t *testing.T, net, addr string, readFrom bool) {
+ c, err := Dial(net, addr)
if err != nil {
- t.Errorf("dial %s %s failed: %v", network, addr, err)
+ t.Errorf("Dial(%q, %q) failed: %v", net, addr, err)
return
}
- defer fd.Close()
+ defer c.Close()
what := "Read"
if readFrom {
what = "ReadFrom"
@@ -26,22 +26,22 @@ func testTimeout(t *testing.T, network, addr string, readFrom bool) {
errc := make(chan error, 1)
go func() {
t0 := time.Now()
- fd.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
+ c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
var b [100]byte
var n int
- var err1 error
+ var err error
if readFrom {
- n, _, err1 = fd.(PacketConn).ReadFrom(b[0:])
+ n, _, err = c.(PacketConn).ReadFrom(b[0:])
} else {
- n, err1 = fd.Read(b[0:])
+ n, err = c.Read(b[0:])
}
t1 := time.Now()
- if n != 0 || err1 == nil || !err1.(Error).Timeout() {
- errc <- fmt.Errorf("fd.%s on %s %s did not return 0, timeout: %v, %v", what, network, addr, n, err1)
+ if n != 0 || err == nil || !err.(Error).Timeout() {
+ errc <- fmt.Errorf("%s(%q, %q) did not return 0, timeout: %v, %v", what, net, addr, n, err)
return
}
if dt := t1.Sub(t0); dt < 50*time.Millisecond || !testing.Short() && dt > 250*time.Millisecond {
- errc <- fmt.Errorf("fd.%s on %s %s took %s, expected 0.1s", what, network, addr, dt)
+ errc <- fmt.Errorf("%s(%q, %q) took %s, expected 0.1s", what, net, addr, dt)
return
}
errc <- nil
@@ -52,26 +52,39 @@ func testTimeout(t *testing.T, network, addr string, readFrom bool) {
t.Error(err)
}
case <-time.After(1 * time.Second):
- t.Errorf("%s on %s %s took over 1 second, expected 0.1s", what, network, addr)
+ t.Errorf("%s(%q, %q) took over 1 second, expected 0.1s", what, net, addr)
}
}
func TestTimeoutUDP(t *testing.T) {
- if runtime.GOOS == "plan9" {
+ switch runtime.GOOS {
+ case "plan9":
+ t.Logf("skipping test on %q", runtime.GOOS)
return
}
- testTimeout(t, "udp", "127.0.0.1:53", false)
- testTimeout(t, "udp", "127.0.0.1:53", true)
+
+ // set up a listener that won't talk back
+ listening := make(chan string)
+ done := make(chan int)
+ go runDatagramPacketConnServer(t, "udp", "127.0.0.1:0", listening, done)
+ addr := <-listening
+
+ testTimeout(t, "udp", addr, false)
+ testTimeout(t, "udp", addr, true)
+ <-done
}
func TestTimeoutTCP(t *testing.T) {
- if runtime.GOOS == "plan9" {
+ switch runtime.GOOS {
+ case "plan9":
+ t.Logf("skipping test on %q", runtime.GOOS)
return
}
+
// set up a listener that won't talk back
listening := make(chan string)
done := make(chan int)
- go runServe(t, "tcp", "127.0.0.1:0", listening, done)
+ go runStreamConnServer(t, "tcp", "127.0.0.1:0", listening, done)
addr := <-listening
testTimeout(t, "tcp", addr, false)
@@ -79,7 +92,9 @@ func TestTimeoutTCP(t *testing.T) {
}
func TestDeadlineReset(t *testing.T) {
- if runtime.GOOS == "plan9" {
+ switch runtime.GOOS {
+ case "plan9":
+ t.Logf("skipping test on %q", runtime.GOOS)
return
}
ln, err := Listen("tcp", "127.0.0.1:0")
diff --git a/libgo/go/net/udp_test.go b/libgo/go/net/udp_test.go
index ea5fad41a53..f80d3b5a9cf 100644
--- a/libgo/go/net/udp_test.go
+++ b/libgo/go/net/udp_test.go
@@ -10,7 +10,9 @@ import (
)
func TestWriteToUDP(t *testing.T) {
- if runtime.GOOS == "plan9" {
+ switch runtime.GOOS {
+ case "plan9":
+ t.Logf("skipping test on %q", runtime.GOOS)
return
}
diff --git a/libgo/go/net/udpsock_posix.go b/libgo/go/net/udpsock_posix.go
index 1f99dc53867..9e820e1c57a 100644
--- a/libgo/go/net/udpsock_posix.go
+++ b/libgo/go/net/udpsock_posix.go
@@ -37,6 +37,13 @@ func (a *UDPAddr) family() int {
return syscall.AF_INET6
}
+func (a *UDPAddr) isWildcard() bool {
+ if a == nil || a.IP == nil {
+ return true
+ }
+ return a.IP.IsUnspecified()
+}
+
func (a *UDPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
return ipToSockaddr(family, a.IP, a.Port)
}
diff --git a/libgo/go/net/unicast_test.go b/libgo/go/net/unicast_test.go
index 297276d3a7f..e5dd013db67 100644
--- a/libgo/go/net/unicast_test.go
+++ b/libgo/go/net/unicast_test.go
@@ -5,83 +5,482 @@
package net
import (
- "io"
"runtime"
+ "syscall"
"testing"
)
-var unicastTests = []struct {
- net string
- laddr string
- ipv6 bool
- packet bool
+var listenerTests = []struct {
+ net string
+ laddr string
+ ipv6 bool // test with underlying AF_INET6 socket
+ wildcard bool // test with wildcard address
}{
- {net: "tcp4", laddr: "127.0.0.1:0"},
- {net: "tcp4", laddr: "previous"},
- {net: "tcp6", laddr: "[::1]:0", ipv6: true},
- {net: "tcp6", laddr: "previous", ipv6: true},
- {net: "udp4", laddr: "127.0.0.1:0", packet: true},
- {net: "udp6", laddr: "[::1]:0", ipv6: true, packet: true},
+ {net: "tcp", laddr: "", wildcard: true},
+ {net: "tcp", laddr: "0.0.0.0", wildcard: true},
+ {net: "tcp", laddr: "[::ffff:0.0.0.0]", wildcard: true},
+ {net: "tcp", laddr: "[::]", ipv6: true, wildcard: true},
+
+ {net: "tcp", laddr: "127.0.0.1"},
+ {net: "tcp", laddr: "[::ffff:127.0.0.1]"},
+ {net: "tcp", laddr: "[::1]", ipv6: true},
+
+ {net: "tcp4", laddr: "", wildcard: true},
+ {net: "tcp4", laddr: "0.0.0.0", wildcard: true},
+ {net: "tcp4", laddr: "[::ffff:0.0.0.0]", wildcard: true},
+
+ {net: "tcp4", laddr: "127.0.0.1"},
+ {net: "tcp4", laddr: "[::ffff:127.0.0.1]"},
+
+ {net: "tcp6", laddr: "", ipv6: true, wildcard: true},
+ {net: "tcp6", laddr: "[::]", ipv6: true, wildcard: true},
+
+ {net: "tcp6", laddr: "[::1]", ipv6: true},
}
-func TestUnicastTCPAndUDP(t *testing.T) {
- if runtime.GOOS == "plan9" || runtime.GOOS == "windows" {
+// TestTCPListener tests both single and double listen to a test
+// listener with same address family, same listening address and
+// same port.
+func TestTCPListener(t *testing.T) {
+ switch runtime.GOOS {
+ case "plan9", "windows":
+ t.Logf("skipping test on %q", runtime.GOOS)
return
}
- prevladdr := ""
- for _, tt := range unicastTests {
+ for _, tt := range listenerTests {
+ if tt.wildcard && (testing.Short() || !*testExternal) {
+ continue
+ }
if tt.ipv6 && !supportsIPv6 {
continue
}
- var (
- fd *netFD
- closer io.Closer
- )
- if !tt.packet {
- if tt.laddr == "previous" {
- tt.laddr = prevladdr
+ l1, port := usableListenPort(t, tt.net, tt.laddr)
+ checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
+ l2, err := Listen(tt.net, tt.laddr+":"+port)
+ checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
+ fd := l1.(*TCPListener).fd
+ switch fd.family {
+ case syscall.AF_INET:
+ testIPv4UnicastSocketOptions(t, fd)
+ case syscall.AF_INET6:
+ testIPv6UnicastSocketOptions(t, fd)
+ }
+ l1.Close()
+ }
+}
+
+// TestUDPListener tests both single and double listen to a test
+// listener with same address family, same listening address and
+// same port.
+func TestUDPListener(t *testing.T) {
+ switch runtime.GOOS {
+ case "plan9", "windows":
+ t.Logf("skipping test on %q", runtime.GOOS)
+ return
+ }
+
+ toudpnet := func(net string) string {
+ switch net {
+ case "tcp":
+ return "udp"
+ case "tcp4":
+ return "udp4"
+ case "tcp6":
+ return "udp6"
+ }
+ return "<nil>"
+ }
+
+ for _, tt := range listenerTests {
+ if tt.wildcard && (testing.Short() || !*testExternal) {
+ continue
+ }
+ if tt.ipv6 && !supportsIPv6 {
+ continue
+ }
+ tt.net = toudpnet(tt.net)
+ l1, port := usableListenPacketPort(t, tt.net, tt.laddr)
+ checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
+ l2, err := ListenPacket(tt.net, tt.laddr+":"+port)
+ checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
+ fd := l1.(*UDPConn).fd
+ switch fd.family {
+ case syscall.AF_INET:
+ testIPv4UnicastSocketOptions(t, fd)
+ case syscall.AF_INET6:
+ testIPv6UnicastSocketOptions(t, fd)
+ }
+ l1.Close()
+ }
+}
+
+func TestSimpleTCPListener(t *testing.T) {
+ switch runtime.GOOS {
+ case "plan9":
+ t.Logf("skipping test on %q", runtime.GOOS)
+ return
+ }
+
+ for _, tt := range listenerTests {
+ if tt.wildcard && (testing.Short() || !*testExternal) {
+ continue
+ }
+ if tt.ipv6 {
+ continue
+ }
+ l1, port := usableListenPort(t, tt.net, tt.laddr)
+ checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
+ l2, err := Listen(tt.net, tt.laddr+":"+port)
+ checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
+ l1.Close()
+ }
+}
+
+func TestSimpleUDPListener(t *testing.T) {
+ switch runtime.GOOS {
+ case "plan9":
+ t.Logf("skipping test on %q", runtime.GOOS)
+ return
+ }
+
+ toudpnet := func(net string) string {
+ switch net {
+ case "tcp":
+ return "udp"
+ case "tcp4":
+ return "udp4"
+ case "tcp6":
+ return "udp6"
+ }
+ return "<nil>"
+ }
+
+ for _, tt := range listenerTests {
+ if tt.wildcard && (testing.Short() || !*testExternal) {
+ continue
+ }
+ if tt.ipv6 {
+ continue
+ }
+ tt.net = toudpnet(tt.net)
+ l1, port := usableListenPacketPort(t, tt.net, tt.laddr)
+ checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
+ l2, err := ListenPacket(tt.net, tt.laddr+":"+port)
+ checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
+ l1.Close()
+ }
+}
+
+var dualStackListenerTests = []struct {
+ net1 string // first listener
+ laddr1 string
+ net2 string // second listener
+ laddr2 string
+ wildcard bool // test with wildcard address
+ xerr error // expected error value, nil or other
+}{
+ // Test cases and expected results for the attemping 2nd listen on the same port
+ // 1st listen 2nd listen darwin freebsd linux openbsd
+ // ------------------------------------------------------------------------------------
+ // "tcp" "" "tcp" "" - - - -
+ // "tcp" "" "tcp" "0.0.0.0" - - - -
+ // "tcp" "0.0.0.0" "tcp" "" - - - -
+ // ------------------------------------------------------------------------------------
+ // "tcp" "" "tcp" "[::]" - - - ok
+ // "tcp" "[::]" "tcp" "" - - - ok
+ // "tcp" "0.0.0.0" "tcp" "[::]" - - - ok
+ // "tcp" "[::]" "tcp" "0.0.0.0" - - - ok
+ // "tcp" "[::ffff:0.0.0.0]" "tcp" "[::]" - - - ok
+ // "tcp" "[::]" "tcp" "[::ffff:0.0.0.0]" - - - ok
+ // ------------------------------------------------------------------------------------
+ // "tcp4" "" "tcp6" "" ok ok ok ok
+ // "tcp6" "" "tcp4" "" ok ok ok ok
+ // "tcp4" "0.0.0.0" "tcp6" "[::]" ok ok ok ok
+ // "tcp6" "[::]" "tcp4" "0.0.0.0" ok ok ok ok
+ // ------------------------------------------------------------------------------------
+ // "tcp" "127.0.0.1" "tcp" "[::1]" ok ok ok ok
+ // "tcp" "[::1]" "tcp" "127.0.0.1" ok ok ok ok
+ // "tcp4" "127.0.0.1" "tcp6" "[::1]" ok ok ok ok
+ // "tcp6" "[::1]" "tcp4" "127.0.0.1" ok ok ok ok
+ //
+ // Platform default configurations:
+ // darwin, kernel version 11.3.0
+ // net.inet6.ip6.v6only=0 (overridable by sysctl or IPV6_V6ONLY option)
+ // freebsd, kernel version 8.2
+ // net.inet6.ip6.v6only=1 (overridable by sysctl or IPV6_V6ONLY option)
+ // linux, kernel version 3.0.0
+ // net.ipv6.bindv6only=0 (overridable by sysctl or IPV6_V6ONLY option)
+ // openbsd, kernel version 5.0
+ // net.inet6.ip6.v6only=1 (overriding is prohibited)
+
+ {net1: "tcp", laddr1: "", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
+ {net1: "tcp", laddr1: "", net2: "tcp", laddr2: "0.0.0.0", wildcard: true, xerr: syscall.EADDRINUSE},
+ {net1: "tcp", laddr1: "0.0.0.0", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
+
+ {net1: "tcp", laddr1: "", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
+ {net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
+ {net1: "tcp", laddr1: "0.0.0.0", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
+ {net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "0.0.0.0", wildcard: true, xerr: syscall.EADDRINUSE},
+ {net1: "tcp", laddr1: "[::ffff:0.0.0.0]", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
+ {net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "[::ffff:0.0.0.0]", wildcard: true, xerr: syscall.EADDRINUSE},
+
+ {net1: "tcp4", laddr1: "", net2: "tcp6", laddr2: "", wildcard: true},
+ {net1: "tcp6", laddr1: "", net2: "tcp4", laddr2: "", wildcard: true},
+ {net1: "tcp4", laddr1: "0.0.0.0", net2: "tcp6", laddr2: "[::]", wildcard: true},
+ {net1: "tcp6", laddr1: "[::]", net2: "tcp4", laddr2: "0.0.0.0", wildcard: true},
+
+ {net1: "tcp", laddr1: "127.0.0.1", net2: "tcp", laddr2: "[::1]"},
+ {net1: "tcp", laddr1: "[::1]", net2: "tcp", laddr2: "127.0.0.1"},
+ {net1: "tcp4", laddr1: "127.0.0.1", net2: "tcp6", laddr2: "[::1]"},
+ {net1: "tcp6", laddr1: "[::1]", net2: "tcp4", laddr2: "127.0.0.1"},
+}
+
+// TestDualStackTCPListener tests both single and double listen
+// to a test listener with various address families, differnet
+// listening address and same port.
+func TestDualStackTCPListener(t *testing.T) {
+ switch runtime.GOOS {
+ case "plan9":
+ t.Logf("skipping test on %q", runtime.GOOS)
+ return
+ }
+ if !supportsIPv6 {
+ return
+ }
+
+ for _, tt := range dualStackListenerTests {
+ if tt.wildcard && (testing.Short() || !*testExternal) {
+ continue
+ }
+ switch runtime.GOOS {
+ case "openbsd":
+ if tt.wildcard && differentWildcardAddr(tt.laddr1, tt.laddr2) {
+ tt.xerr = nil
+ }
+ }
+ l1, port := usableListenPort(t, tt.net1, tt.laddr1)
+ laddr := tt.laddr1 + ":" + port
+ checkFirstListener(t, tt.net1, laddr, l1)
+ laddr = tt.laddr2 + ":" + port
+ l2, err := Listen(tt.net2, laddr)
+ checkDualStackSecondListener(t, tt.net2, laddr, tt.xerr, err, l2)
+ l1.Close()
+ }
+}
+
+// TestDualStackUDPListener tests both single and double listen
+// to a test listener with various address families, differnet
+// listening address and same port.
+func TestDualStackUDPListener(t *testing.T) {
+ switch runtime.GOOS {
+ case "plan9":
+ t.Logf("skipping test on %q", runtime.GOOS)
+ return
+ }
+ if !supportsIPv6 {
+ return
+ }
+
+ toudpnet := func(net string) string {
+ switch net {
+ case "tcp":
+ return "udp"
+ case "tcp4":
+ return "udp4"
+ case "tcp6":
+ return "udp6"
+ }
+ return "<nil>"
+ }
+
+ for _, tt := range dualStackListenerTests {
+ if tt.wildcard && (testing.Short() || !*testExternal) {
+ continue
+ }
+ tt.net1 = toudpnet(tt.net1)
+ tt.net2 = toudpnet(tt.net2)
+ switch runtime.GOOS {
+ case "openbsd":
+ if tt.wildcard && differentWildcardAddr(tt.laddr1, tt.laddr2) {
+ tt.xerr = nil
}
- l, err := Listen(tt.net, tt.laddr)
- if err != nil {
- t.Fatalf("Listen failed: %v", err)
+ }
+ l1, port := usableListenPacketPort(t, tt.net1, tt.laddr1)
+ laddr := tt.laddr1 + ":" + port
+ checkFirstListener(t, tt.net1, laddr, l1)
+ laddr = tt.laddr2 + ":" + port
+ l2, err := ListenPacket(tt.net2, laddr)
+ checkDualStackSecondListener(t, tt.net2, laddr, tt.xerr, err, l2)
+ l1.Close()
+ }
+}
+
+func usableListenPort(t *testing.T, net, laddr string) (l Listener, port string) {
+ var nladdr string
+ var err error
+ switch net {
+ default:
+ panic("usableListenPort net=" + net)
+ case "tcp", "tcp4", "tcp6":
+ l, err = Listen(net, laddr+":0")
+ if err != nil {
+ t.Fatalf("Probe Listen(%q, %q) failed: %v", net, laddr, err)
+ }
+ nladdr = l.(*TCPListener).Addr().String()
+ }
+ _, port, err = SplitHostPort(nladdr)
+ if err != nil {
+ t.Fatalf("SplitHostPort failed: %v", err)
+ }
+ return l, port
+}
+
+func usableListenPacketPort(t *testing.T, net, laddr string) (l PacketConn, port string) {
+ var nladdr string
+ var err error
+ switch net {
+ default:
+ panic("usableListenPacketPort net=" + net)
+ case "udp", "udp4", "udp6":
+ l, err = ListenPacket(net, laddr+":0")
+ if err != nil {
+ t.Fatalf("Probe ListenPacket(%q, %q) failed: %v", net, laddr, err)
+ }
+ nladdr = l.(*UDPConn).LocalAddr().String()
+ }
+ _, port, err = SplitHostPort(nladdr)
+ if err != nil {
+ t.Fatalf("SplitHostPort failed: %v", err)
+ }
+ return l, port
+}
+
+func differentWildcardAddr(i, j string) bool {
+ if (i == "" || i == "0.0.0.0" || i == "::ffff:0.0.0.0") && (j == "" || j == "0.0.0.0" || j == "::ffff:0.0.0.0") {
+ return false
+ }
+ if i == "[::]" && j == "[::]" {
+ return false
+ }
+ return true
+}
+
+func checkFirstListener(t *testing.T, net, laddr string, l interface{}) {
+ switch net {
+ case "tcp":
+ fd := l.(*TCPListener).fd
+ checkDualStackAddrFamily(t, net, laddr, fd)
+ case "tcp4":
+ fd := l.(*TCPListener).fd
+ if fd.family != syscall.AF_INET {
+ t.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET)
+ }
+ case "tcp6":
+ fd := l.(*TCPListener).fd
+ if fd.family != syscall.AF_INET6 {
+ t.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
+ }
+ case "udp":
+ fd := l.(*UDPConn).fd
+ checkDualStackAddrFamily(t, net, laddr, fd)
+ case "udp4":
+ fd := l.(*UDPConn).fd
+ if fd.family != syscall.AF_INET {
+ t.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET)
+ }
+ case "udp6":
+ fd := l.(*UDPConn).fd
+ if fd.family != syscall.AF_INET6 {
+ t.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
+ }
+ default:
+ t.Fatalf("Unexpected network: %q", net)
+ }
+}
+
+func checkSecondListener(t *testing.T, net, laddr string, err error, l interface{}) {
+ switch net {
+ case "tcp", "tcp4", "tcp6":
+ if err == nil {
+ l.(*TCPListener).Close()
+ t.Fatalf("Second Listen(%q, %q) should fail", net, laddr)
+ }
+ case "udp", "udp4", "udp6":
+ if err == nil {
+ l.(*UDPConn).Close()
+ t.Fatalf("Second ListenPacket(%q, %q) should fail", net, laddr)
+ }
+ default:
+ t.Fatalf("Unexpected network: %q", net)
+ }
+}
+
+func checkDualStackSecondListener(t *testing.T, net, laddr string, xerr, err error, l interface{}) {
+ switch net {
+ case "tcp", "tcp4", "tcp6":
+ if xerr == nil && err != nil || xerr != nil && err == nil {
+ t.Fatalf("Second Listen(%q, %q) returns %v, expected %v", net, laddr, err, xerr)
+ }
+ l.(*TCPListener).Close()
+ case "udp", "udp4", "udp6":
+ if xerr == nil && err != nil || xerr != nil && err == nil {
+ t.Fatalf("Second ListenPacket(%q, %q) returns %v, expected %v", net, laddr, err, xerr)
+ }
+ l.(*UDPConn).Close()
+ default:
+ t.Fatalf("Unexpected network: %q", net)
+ }
+}
+
+func checkDualStackAddrFamily(t *testing.T, net, laddr string, fd *netFD) {
+ switch a := fd.laddr.(type) {
+ case *TCPAddr:
+ // If a node under test supports both IPv6 capability
+ // and IPv6 IPv4-mapping capability, we can assume
+ // that the node listens on a wildcard address with an
+ // AF_INET6 socket.
+ if supportsIPv4map && fd.laddr.(*TCPAddr).isWildcard() {
+ if fd.family != syscall.AF_INET6 {
+ t.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
}
- prevladdr = l.Addr().String()
- closer = l
- fd = l.(*TCPListener).fd
} else {
- c, err := ListenPacket(tt.net, tt.laddr)
- if err != nil {
- t.Fatalf("ListenPacket failed: %v", err)
+ if fd.family != a.family() {
+ t.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, a.family())
}
- closer = c
- fd = c.(*UDPConn).fd
}
- if !tt.ipv6 {
- testIPv4UnicastSocketOptions(t, fd)
+ case *UDPAddr:
+ // If a node under test supports both IPv6 capability
+ // and IPv6 IPv4-mapping capability, we can assume
+ // that the node listens on a wildcard address with an
+ // AF_INET6 socket.
+ if supportsIPv4map && fd.laddr.(*UDPAddr).isWildcard() {
+ if fd.family != syscall.AF_INET6 {
+ t.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
+ }
} else {
- testIPv6UnicastSocketOptions(t, fd)
+ if fd.family != a.family() {
+ t.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, a.family())
+ }
}
- closer.Close()
+ default:
+ t.Fatalf("Unexpected protocol address type: %T", a)
}
}
func testIPv4UnicastSocketOptions(t *testing.T, fd *netFD) {
- tos, err := ipv4TOS(fd)
+ _, err := ipv4TOS(fd)
if err != nil {
t.Fatalf("ipv4TOS failed: %v", err)
}
- t.Logf("IPv4 TOS: %v", tos)
err = setIPv4TOS(fd, 1)
if err != nil {
t.Fatalf("setIPv4TOS failed: %v", err)
}
-
- ttl, err := ipv4TTL(fd)
+ _, err = ipv4TTL(fd)
if err != nil {
t.Fatalf("ipv4TTL failed: %v", err)
}
- t.Logf("IPv4 TTL: %v", ttl)
err = setIPv4TTL(fd, 1)
if err != nil {
t.Fatalf("setIPv4TTL failed: %v", err)
@@ -89,23 +488,51 @@ func testIPv4UnicastSocketOptions(t *testing.T, fd *netFD) {
}
func testIPv6UnicastSocketOptions(t *testing.T, fd *netFD) {
- tos, err := ipv6TrafficClass(fd)
+ _, err := ipv6TrafficClass(fd)
if err != nil {
t.Fatalf("ipv6TrafficClass failed: %v", err)
}
- t.Logf("IPv6 TrafficClass: %v", tos)
err = setIPv6TrafficClass(fd, 1)
if err != nil {
t.Fatalf("setIPv6TrafficClass failed: %v", err)
}
-
- hoplim, err := ipv6HopLimit(fd)
+ _, err = ipv6HopLimit(fd)
if err != nil {
t.Fatalf("ipv6HopLimit failed: %v", err)
}
- t.Logf("IPv6 HopLimit: %v", hoplim)
err = setIPv6HopLimit(fd, 1)
if err != nil {
t.Fatalf("setIPv6HopLimit failed: %v", err)
}
}
+
+var prohibitionaryDialArgTests = []struct {
+ net string
+ addr string
+}{
+ {"tcp6", "127.0.0.1"},
+ {"tcp6", "[::ffff:127.0.0.1]"},
+}
+
+func TestProhibitionaryDialArgs(t *testing.T) {
+ switch runtime.GOOS {
+ case "plan9":
+ t.Logf("skipping test on %q", runtime.GOOS)
+ return
+ }
+ // This test requires both IPv6 and IPv6 IPv4-mapping functionality.
+ if !supportsIPv4map || testing.Short() || !*testExternal {
+ return
+ }
+
+ l, port := usableListenPort(t, "tcp", "[::]")
+ defer l.Close()
+
+ for _, tt := range prohibitionaryDialArgTests {
+ c, err := Dial(tt.net, tt.addr+":"+port)
+ if err == nil {
+ c.Close()
+ t.Fatalf("Dial(%q, %q) should fail", tt.net, tt.addr)
+ }
+ }
+}
diff --git a/libgo/go/net/unixsock_posix.go b/libgo/go/net/unixsock_posix.go
index 3a94cf5c5ad..37a2b1e09ec 100644
--- a/libgo/go/net/unixsock_posix.go
+++ b/libgo/go/net/unixsock_posix.go
@@ -59,7 +59,7 @@ func unixSocket(net string, laddr, raddr *UnixAddr, mode string) (fd *netFD, err
f = sockaddrToUnixpacket
}
- fd, err = socket(net, syscall.AF_UNIX, sotype, 0, la, ra, f)
+ fd, err = socket(net, syscall.AF_UNIX, sotype, 0, false, la, ra, f)
if err != nil {
goto Error
}
@@ -208,8 +208,8 @@ func (c *UnixConn) SetWriteBuffer(bytes int) error {
}
// ReadFromUnix reads a packet from c, copying the payload into b.
-// It returns the number of bytes copied into b and the return address
-// that was on the packet.
+// It returns the number of bytes copied into b and the source address
+// of the packet.
//
// ReadFromUnix can be made to time out and return
// an error with Timeout() == true after a fixed time limit;
@@ -264,6 +264,11 @@ func (c *UnixConn) WriteTo(b []byte, addr Addr) (n int, err error) {
return c.WriteToUnix(b, a)
}
+// ReadMsgUnix reads a packet from c, copying the payload into b
+// and the associated out-of-band data into oob.
+// It returns the number of bytes copied into b, the number of
+// bytes copied into oob, the flags that were set on the packet,
+// and the source address of the packet.
func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAddr, err error) {
if !c.ok() {
return 0, 0, 0, nil, syscall.EINVAL
@@ -276,6 +281,9 @@ func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAdd
return
}
+// WriteMsgUnix writes a packet to addr via c, copying the payload from b
+// and the associated out-of-band data from oob. It returns the number
+// of payload and out-of-band bytes written.
func (c *UnixConn) WriteMsgUnix(b, oob []byte, addr *UnixAddr) (n, oobn int, err error) {
if !c.ok() {
return 0, 0, syscall.EINVAL
diff --git a/libgo/go/os/error.go b/libgo/go/os/error.go
index e0b83b5c22c..b88e49400de 100644
--- a/libgo/go/os/error.go
+++ b/libgo/go/os/error.go
@@ -42,3 +42,21 @@ func NewSyscallError(syscall string, err error) error {
}
return &SyscallError{syscall, err}
}
+
+// IsExist returns whether the error is known to report that a file or directory
+// already exists. It is satisfied by ErrExist as well as some syscall errors.
+func IsExist(err error) bool {
+ return isExist(err)
+}
+
+// IsNotExist returns whether the error is known to report that a file or directory
+// does not exist. It is satisfied by ErrNotExist as well as some syscall errors.
+func IsNotExist(err error) bool {
+ return isNotExist(err)
+}
+
+// IsPermission returns whether the error is known to report that permission is denied.
+// It is satisfied by ErrPermission as well as some syscall errors.
+func IsPermission(err error) bool {
+ return isPermission(err)
+}
diff --git a/libgo/go/os/error_plan9.go b/libgo/go/os/error_plan9.go
index 159d685e7cd..3c9dfb0b158 100644
--- a/libgo/go/os/error_plan9.go
+++ b/libgo/go/os/error_plan9.go
@@ -4,24 +4,21 @@
package os
-// IsExist returns whether the error is known to report that a file already exists.
-func IsExist(err error) bool {
+func isExist(err error) bool {
if pe, ok := err.(*PathError); ok {
err = pe.Err
}
return contains(err.Error(), " exists")
}
-// IsNotExist returns whether the error is known to report that a file does not exist.
-func IsNotExist(err error) bool {
+func isNotExist(err error) bool {
if pe, ok := err.(*PathError); ok {
err = pe.Err
}
return contains(err.Error(), "does not exist")
}
-// IsPermission returns whether the error is known to report that permission is denied.
-func IsPermission(err error) bool {
+func isPermission(err error) bool {
if pe, ok := err.(*PathError); ok {
err = pe.Err
}
diff --git a/libgo/go/os/error_posix.go b/libgo/go/os/error_posix.go
index 74b75d11218..1685c1f2132 100644
--- a/libgo/go/os/error_posix.go
+++ b/libgo/go/os/error_posix.go
@@ -2,33 +2,27 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin freebsd linux netbsd openbsd windows
+// +build darwin freebsd linux netbsd openbsd
package os
import "syscall"
-// IsExist returns whether the error is known to report that a file already exists.
-// It is satisfied by ErrExist as well as some syscall errors.
-func IsExist(err error) bool {
+func isExist(err error) bool {
if pe, ok := err.(*PathError); ok {
err = pe.Err
}
return err == syscall.EEXIST || err == ErrExist
}
-// IsNotExist returns whether the error is known to report that a file does not exist.
-// It is satisfied by ErrNotExist as well as some syscall errors.
-func IsNotExist(err error) bool {
+func isNotExist(err error) bool {
if pe, ok := err.(*PathError); ok {
err = pe.Err
}
return err == syscall.ENOENT || err == ErrNotExist
}
-// IsPermission returns whether the error is known to report that permission is denied.
-// It is satisfied by ErrPermission as well as some syscall errors.
-func IsPermission(err error) bool {
+func isPermission(err error) bool {
if pe, ok := err.(*PathError); ok {
err = pe.Err
}
diff --git a/libgo/go/os/error_test.go b/libgo/go/os/error_test.go
new file mode 100644
index 00000000000..42f846fa3c5
--- /dev/null
+++ b/libgo/go/os/error_test.go
@@ -0,0 +1,81 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os_test
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "testing"
+)
+
+func TestErrIsExist(t *testing.T) {
+ f, err := ioutil.TempFile("", "_Go_ErrIsExist")
+ if err != nil {
+ t.Fatalf("open ErrIsExist tempfile: %s", err)
+ return
+ }
+ defer os.Remove(f.Name())
+ defer f.Close()
+ f2, err := os.OpenFile(f.Name(), os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
+ if err == nil {
+ f2.Close()
+ t.Fatal("Open should have failed")
+ return
+ }
+ if s := checkErrorPredicate("os.IsExist", os.IsExist, err); s != "" {
+ t.Fatal(s)
+ return
+ }
+}
+
+func testErrNotExist(name string) string {
+ f, err := os.Open(name)
+ if err == nil {
+ f.Close()
+ return "Open should have failed"
+ }
+ if s := checkErrorPredicate("os.IsNotExist", os.IsNotExist, err); s != "" {
+ return s
+ }
+
+ err = os.Chdir(name)
+ if err == nil {
+ return "Chdir should have failed"
+ }
+ if s := checkErrorPredicate("os.IsNotExist", os.IsNotExist, err); s != "" {
+ return s
+ }
+ return ""
+}
+
+func TestErrIsNotExist(t *testing.T) {
+ tmpDir, err := ioutil.TempDir("", "_Go_ErrIsNotExist")
+ if err != nil {
+ t.Fatalf("create ErrIsNotExist tempdir: %s", err)
+ return
+ }
+ defer os.RemoveAll(tmpDir)
+
+ name := filepath.Join(tmpDir, "NotExists")
+ if s := testErrNotExist(name); s != "" {
+ t.Fatal(s)
+ return
+ }
+
+ name = filepath.Join(name, "NotExists2")
+ if s := testErrNotExist(name); s != "" {
+ t.Fatal(s)
+ return
+ }
+}
+
+func checkErrorPredicate(predName string, pred func(error) bool, err error) string {
+ if !pred(err) {
+ return fmt.Sprintf("%s does not work as expected for %#v", predName, err)
+ }
+ return ""
+}
diff --git a/libgo/go/os/error_windows.go b/libgo/go/os/error_windows.go
new file mode 100644
index 00000000000..5d692b07362
--- /dev/null
+++ b/libgo/go/os/error_windows.go
@@ -0,0 +1,30 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os
+
+import "syscall"
+
+func isExist(err error) bool {
+ if pe, ok := err.(*PathError); ok {
+ err = pe.Err
+ }
+ return err == syscall.ERROR_ALREADY_EXISTS ||
+ err == syscall.ERROR_FILE_EXISTS || err == ErrExist
+}
+
+func isNotExist(err error) bool {
+ if pe, ok := err.(*PathError); ok {
+ err = pe.Err
+ }
+ return err == syscall.ERROR_FILE_NOT_FOUND ||
+ err == syscall.ERROR_PATH_NOT_FOUND || err == ErrNotExist
+}
+
+func isPermission(err error) bool {
+ if pe, ok := err.(*PathError); ok {
+ err = pe.Err
+ }
+ return err == ErrPermission
+}
diff --git a/libgo/go/os/exec/exec.go b/libgo/go/os/exec/exec.go
index ebe92a9fba3..bbd04902b74 100644
--- a/libgo/go/os/exec/exec.go
+++ b/libgo/go/os/exec/exec.go
@@ -59,7 +59,7 @@ type Cmd struct {
// If either is nil, Run connects the corresponding file descriptor
// to the null device (os.DevNull).
//
- // If Stdout and Stderr are are the same writer, at most one
+ // If Stdout and Stderr are the same writer, at most one
// goroutine at a time will call Write.
Stdout io.Writer
Stderr io.Writer
diff --git a/libgo/go/os/file_unix.go b/libgo/go/os/file_unix.go
index a69680cb8c9..b8fb2e22c98 100644
--- a/libgo/go/os/file_unix.go
+++ b/libgo/go/os/file_unix.go
@@ -179,7 +179,21 @@ func (f *File) pread(b []byte, off int64) (n int, err error) {
// write writes len(b) bytes to the File.
// It returns the number of bytes written and an error, if any.
func (f *File) write(b []byte) (n int, err error) {
- return syscall.Write(f.fd, b)
+ for {
+ m, err := syscall.Write(f.fd, b)
+ n += m
+
+ // If the syscall wrote some data but not all (short write)
+ // or it returned EINTR, then assume it stopped early for
+ // reasons that are uninteresting to the caller, and try again.
+ if 0 < m && m < len(b) || err == syscall.EINTR {
+ b = b[m:]
+ continue
+ }
+
+ return n, err
+ }
+ panic("not reached")
}
// pwrite writes len(b) bytes to the File starting at byte offset off.
diff --git a/libgo/go/os/os_test.go b/libgo/go/os/os_test.go
index aa01669a5da..8d3f677fd4e 100644
--- a/libgo/go/os/os_test.go
+++ b/libgo/go/os/os_test.go
@@ -1045,3 +1045,22 @@ func TestSameFile(t *testing.T) {
t.Errorf("files should be different")
}
}
+
+func TestDevNullFile(t *testing.T) {
+ f, err := Open(DevNull)
+ if err != nil {
+ t.Fatalf("Open(%s): %v", DevNull, err)
+ }
+ defer f.Close()
+ fi, err := f.Stat()
+ if err != nil {
+ t.Fatalf("Stat(%s): %v", DevNull, err)
+ }
+ name := filepath.Base(DevNull)
+ if fi.Name() != name {
+ t.Fatalf("wrong file name have %v want %v", fi.Name(), name)
+ }
+ if fi.Size() != 0 {
+ t.Fatalf("wrong file size have %d want 0", fi.Size())
+ }
+}
diff --git a/libgo/go/os/types.go b/libgo/go/os/types.go
index c7c5199be1c..0c95c9cece0 100644
--- a/libgo/go/os/types.go
+++ b/libgo/go/os/types.go
@@ -15,7 +15,7 @@ func Getpagesize() int { return syscall.Getpagesize() }
// A FileInfo describes a file and is returned by Stat and Lstat
type FileInfo interface {
Name() string // base name of the file
- Size() int64 // length in bytes
+ Size() int64 // length in bytes for regular files; system-dependent for others
Mode() FileMode // file mode bits
ModTime() time.Time // modification time
IsDir() bool // abbreviation for Mode().IsDir()
@@ -58,7 +58,7 @@ const (
func (m FileMode) String() string {
const str = "dalTLDpSugct"
- var buf [20]byte
+ var buf [32]byte // Mode is uint32.
w := 0
for i, c := range str {
if m&(1<<uint(32-1-i)) != 0 {
diff --git a/libgo/go/path/filepath/match.go b/libgo/go/path/filepath/match.go
index 38d264fb97a..db8b0260ca8 100644
--- a/libgo/go/path/filepath/match.go
+++ b/libgo/go/path/filepath/match.go
@@ -7,6 +7,7 @@ package filepath
import (
"errors"
"os"
+ "runtime"
"sort"
"strings"
"unicode/utf8"
@@ -37,6 +38,9 @@ var ErrBadPattern = errors.New("syntax error in pattern")
// The only possible returned error is ErrBadPattern, when pattern
// is malformed.
//
+// On Windows, escaping is disabled. Instead, '\\' is treated as
+// path separator.
+//
func Match(pattern, name string) (matched bool, err error) {
Pattern:
for len(pattern) > 0 {
@@ -95,9 +99,11 @@ Scan:
for i = 0; i < len(pattern); i++ {
switch pattern[i] {
case '\\':
- // error check handled in matchChunk: bad pattern.
- if i+1 < len(pattern) {
- i++
+ if runtime.GOOS != "windows" {
+ // error check handled in matchChunk: bad pattern.
+ if i+1 < len(pattern) {
+ i++
+ }
}
case '[':
inrange = true
@@ -167,10 +173,12 @@ func matchChunk(chunk, s string) (rest string, ok bool, err error) {
chunk = chunk[1:]
case '\\':
- chunk = chunk[1:]
- if len(chunk) == 0 {
- err = ErrBadPattern
- return
+ if runtime.GOOS != "windows" {
+ chunk = chunk[1:]
+ if len(chunk) == 0 {
+ err = ErrBadPattern
+ return
+ }
}
fallthrough
@@ -191,7 +199,7 @@ func getEsc(chunk string) (r rune, nchunk string, err error) {
err = ErrBadPattern
return
}
- if chunk[0] == '\\' {
+ if chunk[0] == '\\' && runtime.GOOS != "windows" {
chunk = chunk[1:]
if len(chunk) == 0 {
err = ErrBadPattern
diff --git a/libgo/go/path/filepath/match_test.go b/libgo/go/path/filepath/match_test.go
index dc0fff2f5e0..e3d365881cc 100644
--- a/libgo/go/path/filepath/match_test.go
+++ b/libgo/go/path/filepath/match_test.go
@@ -7,6 +7,7 @@ package filepath_test
import (
. "path/filepath"
"runtime"
+ "strings"
"testing"
)
@@ -76,21 +77,26 @@ func errp(e error) string {
}
func TestMatch(t *testing.T) {
- if runtime.GOOS == "windows" {
- // XXX: Don't pass for windows.
- return
- }
for _, tt := range matchTests {
- ok, err := Match(tt.pattern, tt.s)
+ pattern := tt.pattern
+ s := tt.s
+ if runtime.GOOS == "windows" {
+ if strings.Index(pattern, "\\") >= 0 {
+ // no escape allowed on windows.
+ continue
+ }
+ pattern = Clean(pattern)
+ s = Clean(s)
+ }
+ ok, err := Match(pattern, s)
if ok != tt.match || err != tt.err {
- t.Errorf("Match(%#q, %#q) = %v, %q want %v, %q", tt.pattern, tt.s, ok, errp(err), tt.match, errp(tt.err))
+ t.Errorf("Match(%#q, %#q) = %v, %q want %v, %q", pattern, s, ok, errp(err), tt.match, errp(tt.err))
}
}
}
// contains returns true if vector contains the string s.
func contains(vector []string, s string) bool {
- s = ToSlash(s)
for _, elem := range vector {
if elem == s {
return true
@@ -110,18 +116,20 @@ var globTests = []struct {
}
func TestGlob(t *testing.T) {
- if runtime.GOOS == "windows" {
- // XXX: Don't pass for windows.
- return
- }
for _, tt := range globTests {
- matches, err := Glob(tt.pattern)
+ pattern := tt.pattern
+ result := tt.result
+ if runtime.GOOS == "windows" {
+ pattern = Clean(pattern)
+ result = Clean(result)
+ }
+ matches, err := Glob(pattern)
if err != nil {
- t.Errorf("Glob error for %q: %s", tt.pattern, err)
+ t.Errorf("Glob error for %q: %s", pattern, err)
continue
}
- if !contains(matches, tt.result) {
- t.Errorf("Glob(%#q) = %#v want %v", tt.pattern, matches, tt.result)
+ if !contains(matches, result) {
+ t.Errorf("Glob(%#q) = %#v want %v", pattern, matches, result)
}
}
for _, pattern := range []string{"no_match", "../*/no_match"} {
diff --git a/libgo/go/path/filepath/path.go b/libgo/go/path/filepath/path.go
index cfe46981f13..1e748726367 100644
--- a/libgo/go/path/filepath/path.go
+++ b/libgo/go/path/filepath/path.go
@@ -7,10 +7,8 @@
package filepath
import (
- "bytes"
"errors"
"os"
- "runtime"
"sort"
"strings"
)
@@ -191,64 +189,7 @@ func Ext(path string) string {
// If path is relative the result will be relative to the current directory,
// unless one of the components is an absolute symbolic link.
func EvalSymlinks(path string) (string, error) {
- if runtime.GOOS == "windows" {
- // Symlinks are not supported under windows.
- _, err := os.Lstat(path)
- if err != nil {
- return "", err
- }
- return Clean(path), nil
- }
- const maxIter = 255
- originalPath := path
- // consume path by taking each frontmost path element,
- // expanding it if it's a symlink, and appending it to b
- var b bytes.Buffer
- for n := 0; path != ""; n++ {
- if n > maxIter {
- return "", errors.New("EvalSymlinks: too many links in " + originalPath)
- }
-
- // find next path component, p
- i := strings.IndexRune(path, Separator)
- var p string
- if i == -1 {
- p, path = path, ""
- } else {
- p, path = path[:i], path[i+1:]
- }
-
- if p == "" {
- if b.Len() == 0 {
- // must be absolute path
- b.WriteRune(Separator)
- }
- continue
- }
-
- fi, err := os.Lstat(b.String() + p)
- if err != nil {
- return "", err
- }
- if fi.Mode()&os.ModeSymlink == 0 {
- b.WriteString(p)
- if path != "" {
- b.WriteRune(Separator)
- }
- continue
- }
-
- // it's a symlink, put it at the front of path
- dest, err := os.Readlink(b.String() + p)
- if err != nil {
- return "", err
- }
- if IsAbs(dest) {
- b.Reset()
- }
- path = dest + string(Separator) + path
- }
- return Clean(b.String()), nil
+ return evalSymlinks(path)
}
// Abs returns an absolute representation of path.
diff --git a/libgo/go/path/filepath/path_test.go b/libgo/go/path/filepath/path_test.go
index 93cca1e4c2b..b8766588cf5 100644
--- a/libgo/go/path/filepath/path_test.go
+++ b/libgo/go/path/filepath/path_test.go
@@ -10,6 +10,7 @@ import (
"path/filepath"
"reflect"
"runtime"
+ "strings"
"testing"
)
@@ -439,7 +440,7 @@ func TestBase(t *testing.T) {
tests := basetests
if runtime.GOOS == "windows" {
// make unix tests work on windows
- for i, _ := range tests {
+ for i := range tests {
tests[i].result = filepath.Clean(tests[i].result)
}
// add windows specific tests
@@ -482,7 +483,7 @@ func TestDir(t *testing.T) {
tests := dirtests
if runtime.GOOS == "windows" {
// make unix tests work on windows
- for i, _ := range tests {
+ for i := range tests {
tests[i].result = filepath.Clean(tests[i].result)
}
// add windows specific tests
@@ -620,6 +621,12 @@ func TestEvalSymlinks(t *testing.T) {
if d.path == d.dest {
// will test only real files and directories
tests = append(tests, d)
+ // test "canonical" names
+ d2 := EvalSymlinksTest{
+ path: strings.ToUpper(d.path),
+ dest: d.dest,
+ }
+ tests = append(tests, d2)
}
}
} else {
@@ -641,35 +648,61 @@ func TestEvalSymlinks(t *testing.T) {
}
}
-/* These tests do not work in the gccgo test environment.
+// Test directories relative to temporary directory.
+// The tests are run in absTestDirs[0].
+var absTestDirs = []string{
+ "a",
+ "a/b",
+ "a/b/c",
+}
-// Test paths relative to $GOROOT/src
-var abstests = []string{
- "../AUTHORS",
- "pkg/../../AUTHORS",
- "Make.inc",
- "pkg/math",
+// Test paths relative to temporary directory. $ expands to the directory.
+// The tests are run in absTestDirs[0].
+// We create absTestDirs first.
+var absTests = []string{
".",
- "$GOROOT/src/Make.inc",
- "$GOROOT/src/../src/Make.inc",
- "$GOROOT/misc/cgo",
- "$GOROOT",
+ "b",
+ "../a",
+ "../a/b",
+ "../a/b/./c/../../.././a",
+ "$",
+ "$/.",
+ "$/a/../a/b",
+ "$/a/b/c/../../.././a",
}
func TestAbs(t *testing.T) {
- t.Logf("test needs to be rewritten; disabled")
- return
-
oldwd, err := os.Getwd()
if err != nil {
- t.Fatal("Getwd failed: " + err.Error())
+ t.Fatal("Getwd failed: ", err)
}
defer os.Chdir(oldwd)
- goroot := os.Getenv("GOROOT")
- cwd := filepath.Join(goroot, "src")
- os.Chdir(cwd)
- for _, path := range abstests {
- path = strings.Replace(path, "$GOROOT", goroot, -1)
+
+ root, err := ioutil.TempDir("", "TestAbs")
+ if err != nil {
+ t.Fatal("TempDir failed: ", err)
+ }
+ defer os.RemoveAll(root)
+
+ err = os.Chdir(root)
+ if err != nil {
+ t.Fatal("chdir failed: ", err)
+ }
+
+ for _, dir := range absTestDirs {
+ err = os.Mkdir(dir, 0777)
+ if err != nil {
+ t.Fatal("Mkdir failed: ", err)
+ }
+ }
+
+ err = os.Chdir(absTestDirs[0])
+ if err != nil {
+ t.Fatal("chdir failed: ", err)
+ }
+
+ for _, path := range absTests {
+ path = strings.Replace(path, "$", root, -1)
info, err := os.Stat(path)
if err != nil {
t.Errorf("%s: %s", path, err)
@@ -694,8 +727,6 @@ func TestAbs(t *testing.T) {
}
}
-*/
-
type RelTests struct {
root, path, want string
}
@@ -783,6 +814,7 @@ type VolumeNameTest struct {
var volumenametests = []VolumeNameTest{
{`c:/foo/bar`, `c:`},
{`c:`, `c:`},
+ {`2:`, ``},
{``, ``},
{`\\\host`, ``},
{`\\\host\`, ``},
@@ -814,3 +846,26 @@ func TestVolumeName(t *testing.T) {
}
}
}
+
+func TestDriveLetterInEvalSymlinks(t *testing.T) {
+ if runtime.GOOS != "windows" {
+ return
+ }
+ wd, _ := os.Getwd()
+ if len(wd) < 3 {
+ t.Errorf("Current directory path %q is too short", wd)
+ }
+ lp := strings.ToLower(wd)
+ up := strings.ToUpper(wd)
+ flp, err := filepath.EvalSymlinks(lp)
+ if err != nil {
+ t.Fatalf("EvalSymlinks(%q) failed: %q", lp, err)
+ }
+ fup, err := filepath.EvalSymlinks(up)
+ if err != nil {
+ t.Fatalf("EvalSymlinks(%q) failed: %q", up, err)
+ }
+ if flp != fup {
+ t.Errorf("Results of EvalSymlinks do not match: %q and %q", flp, fup)
+ }
+}
diff --git a/libgo/go/path/filepath/path_windows.go b/libgo/go/path/filepath/path_windows.go
index 1d1d23bfe7c..3dcd0302195 100644
--- a/libgo/go/path/filepath/path_windows.go
+++ b/libgo/go/path/filepath/path_windows.go
@@ -35,9 +35,7 @@ func VolumeName(path string) (v string) {
}
// with drive letter
c := path[0]
- if path[1] == ':' &&
- ('0' <= c && c <= '9' || 'a' <= c && c <= 'z' ||
- 'A' <= c && c <= 'Z') {
+ if path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
return path[:2]
}
// is it UNC
diff --git a/libgo/go/path/filepath/symlink.go b/libgo/go/path/filepath/symlink.go
new file mode 100644
index 00000000000..307dd0f8fee
--- /dev/null
+++ b/libgo/go/path/filepath/symlink.go
@@ -0,0 +1,67 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !windows
+
+package filepath
+
+import (
+ "bytes"
+ "errors"
+ "os"
+ "strings"
+)
+
+func evalSymlinks(path string) (string, error) {
+ const maxIter = 255
+ originalPath := path
+ // consume path by taking each frontmost path element,
+ // expanding it if it's a symlink, and appending it to b
+ var b bytes.Buffer
+ for n := 0; path != ""; n++ {
+ if n > maxIter {
+ return "", errors.New("EvalSymlinks: too many links in " + originalPath)
+ }
+
+ // find next path component, p
+ i := strings.IndexRune(path, Separator)
+ var p string
+ if i == -1 {
+ p, path = path, ""
+ } else {
+ p, path = path[:i], path[i+1:]
+ }
+
+ if p == "" {
+ if b.Len() == 0 {
+ // must be absolute path
+ b.WriteRune(Separator)
+ }
+ continue
+ }
+
+ fi, err := os.Lstat(b.String() + p)
+ if err != nil {
+ return "", err
+ }
+ if fi.Mode()&os.ModeSymlink == 0 {
+ b.WriteString(p)
+ if path != "" {
+ b.WriteRune(Separator)
+ }
+ continue
+ }
+
+ // it's a symlink, put it at the front of path
+ dest, err := os.Readlink(b.String() + p)
+ if err != nil {
+ return "", err
+ }
+ if IsAbs(dest) {
+ b.Reset()
+ }
+ path = dest + string(Separator) + path
+ }
+ return Clean(b.String()), nil
+}
diff --git a/libgo/go/path/filepath/symlink_windows.go b/libgo/go/path/filepath/symlink_windows.go
new file mode 100644
index 00000000000..1ee939928e9
--- /dev/null
+++ b/libgo/go/path/filepath/symlink_windows.go
@@ -0,0 +1,63 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package filepath
+
+import (
+ "syscall"
+)
+
+func toShort(path string) (string, error) {
+ p := syscall.StringToUTF16(path)
+ b := p // GetShortPathName says we can reuse buffer
+ n, err := syscall.GetShortPathName(&p[0], &b[0], uint32(len(b)))
+ if err != nil {
+ return "", err
+ }
+ if n > uint32(len(b)) {
+ b = make([]uint16, n)
+ n, err = syscall.GetShortPathName(&p[0], &b[0], uint32(len(b)))
+ if err != nil {
+ return "", err
+ }
+ }
+ return syscall.UTF16ToString(b), nil
+}
+
+func toLong(path string) (string, error) {
+ p := syscall.StringToUTF16(path)
+ b := p // GetLongPathName says we can reuse buffer
+ n, err := syscall.GetLongPathName(&p[0], &b[0], uint32(len(b)))
+ if err != nil {
+ return "", err
+ }
+ if n > uint32(len(b)) {
+ b = make([]uint16, n)
+ n, err = syscall.GetLongPathName(&p[0], &b[0], uint32(len(b)))
+ if err != nil {
+ return "", err
+ }
+ }
+ b = b[:n]
+ return syscall.UTF16ToString(b), nil
+}
+
+func evalSymlinks(path string) (string, error) {
+ p, err := toShort(path)
+ if err != nil {
+ return "", err
+ }
+ p, err = toLong(p)
+ if err != nil {
+ return "", err
+ }
+ // syscall.GetLongPathName does not change the case of the drive letter,
+ // but the result of EvalSymlinks must be unique, so we have
+ // EvalSymlinks(`c:\a`) == EvalSymlinks(`C:\a`).
+ // Make drive letter upper case.
+ if len(p) >= 2 && p[1] == ':' && 'a' <= p[0] && p[0] <= 'z' {
+ p = string(p[0]+'A'-'a') + p[1:]
+ }
+ return Clean(p), nil
+}
diff --git a/libgo/go/reflect/type.go b/libgo/go/reflect/type.go
index b1dd0a1fecd..7fe18a9d735 100644
--- a/libgo/go/reflect/type.go
+++ b/libgo/go/reflect/type.go
@@ -66,9 +66,10 @@ type Type interface {
// It returns an empty string for unnamed types.
Name() string
- // PkgPath returns the type's package path.
- // The package path is a full package import path like "encoding/base64".
- // PkgPath returns an empty string for unnamed or predeclared types.
+ // PkgPath returns a named type's package path, that is, the import path
+ // that uniquely identifies the package, such as "encoding/base64".
+ // If the type was predeclared (string, error) or unnamed (*T, struct{}, []int),
+ // the package path will be the empty string.
PkgPath() string
// Size returns the number of bytes needed to store
@@ -234,6 +235,7 @@ type commonType struct {
kind uint8 // enumeration for C
align int8 // alignment of variable with this type
fieldAlign uint8 // alignment of struct field with this type
+ _ uint8 // unused/padding
size uintptr // size in bytes
hash uint32 // hash of type; avoids computation in hash tables
@@ -350,11 +352,18 @@ type structType struct {
// Method represents a single method.
type Method struct {
- PkgPath string // empty for uppercase Name
+ // Name is the method name.
+ // PkgPath is the package path that qualifies a lower case (unexported)
+ // method name. It is empty for upper case (exported) method names.
+ // The combination of PkgPath and Name uniquely identifies a method
+ // in a method set.
+ // See http://golang.org/ref/spec#Uniqueness_of_identifiers
Name string
- Type Type
- Func Value
- Index int
+ PkgPath string
+
+ Type Type // method type
+ Func Value // func with receiver as first argument
+ Index int // index for Type.Method
}
// High bit says whether type has
@@ -694,14 +703,20 @@ func (t *interfaceType) MethodByName(name string) (m Method, ok bool) {
return
}
+// A StructField describes a single field in a struct.
type StructField struct {
- PkgPath string // empty for uppercase Name
- Name string
- Type Type
- Tag StructTag
- Offset uintptr
- Index []int
- Anonymous bool
+ // Name is the field name.
+ // PkgPath is the package path that qualifies a lower case (unexported)
+ // field name. It is empty for upper case (exported) field names.
+ // See http://golang.org/ref/spec#Uniqueness_of_identifiers
+ Name string
+ PkgPath string
+
+ Type Type // field type
+ Tag StructTag // field tag string
+ Offset uintptr // offset within struct, in bytes
+ Index []int // index sequence for Type.FieldByIndex
+ Anonymous bool // is an anonymous field
}
// A StructTag is the tag string in a struct field.
diff --git a/libgo/go/reflect/value.go b/libgo/go/reflect/value.go
index b490e99f409..a12fcb2668f 100644
--- a/libgo/go/reflect/value.go
+++ b/libgo/go/reflect/value.go
@@ -54,6 +54,10 @@ func memmove(adst, asrc unsafe.Pointer, n uintptr) {
// its String method returns "<invalid Value>", and all other methods panic.
// Most functions and methods never return an invalid value.
// If one does, its documentation states the conditions explicitly.
+//
+// A Value can be used concurrently by multiple goroutines provided that
+// the underlying Go value can be used concurrently for the equivalent
+// direct operations.
type Value struct {
// typ holds the type of the value represented by a Value.
typ *commonType
@@ -1620,6 +1624,15 @@ func MakeSlice(typ Type, len, cap int) Value {
if typ.Kind() != Slice {
panic("reflect.MakeSlice of non-slice type")
}
+ if len < 0 {
+ panic("reflect.MakeSlice: negative len")
+ }
+ if cap < 0 {
+ panic("reflect.MakeSlice: negative cap")
+ }
+ if len > cap {
+ panic("reflect.MakeSlice: len > cap")
+ }
// Declare slice so that gc can see the base pointer in it.
var x []byte
diff --git a/libgo/go/runtime/compiler.go b/libgo/go/runtime/compiler.go
new file mode 100644
index 00000000000..0ed3b183fe2
--- /dev/null
+++ b/libgo/go/runtime/compiler.go
@@ -0,0 +1,13 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+// Compiler is the name of the compiler toolchain that built the
+// running binary. Known toolchains are:
+//
+// gc The 5g/6g/8g compiler suite at code.google.com/p/go.
+// gccgo The gccgo front end, part of the GCC compiler suite.
+//
+const Compiler = "gccgo"
diff --git a/libgo/go/runtime/debug/stack_test.go b/libgo/go/runtime/debug/stack_test.go
index 94293bb934b..f33f5072b40 100644
--- a/libgo/go/runtime/debug/stack_test.go
+++ b/libgo/go/runtime/debug/stack_test.go
@@ -39,13 +39,20 @@ func TestStack(t *testing.T) {
if len(lines) <= 6 {
t.Fatal("too few lines")
}
- check(t, lines[0], "src/pkg/runtime/debug/stack_test.go")
- check(t, lines[1], "\t(*T).ptrmethod: return Stack()")
- check(t, lines[2], "src/pkg/runtime/debug/stack_test.go")
- check(t, lines[3], "\tT.method: return t.ptrmethod()")
- check(t, lines[4], "src/pkg/runtime/debug/stack_test.go")
- check(t, lines[5], "\tTestStack: b := T(0).method()")
- check(t, lines[6], "src/pkg/testing/testing.go")
+ n := 0
+ frame := func(line, code string) {
+ check(t, lines[n], line)
+ n++
+ // The source might not be available while running the test.
+ if strings.HasPrefix(lines[n], "\t") {
+ check(t, lines[n], code)
+ n++
+ }
+ }
+ frame("src/pkg/runtime/debug/stack_test.go", "\t(*T).ptrmethod: return Stack()")
+ frame("src/pkg/runtime/debug/stack_test.go", "\tT.method: return t.ptrmethod()")
+ frame("src/pkg/runtime/debug/stack_test.go", "\tTestStack: b := T(0).method()")
+ frame("src/pkg/testing/testing.go", "")
}
func check(t *testing.T, line, has string) {
diff --git a/libgo/go/runtime/pprof/pprof_test.go b/libgo/go/runtime/pprof/pprof_test.go
index 2dc7aef7e96..82bb2a2926b 100644
--- a/libgo/go/runtime/pprof/pprof_test.go
+++ b/libgo/go/runtime/pprof/pprof_test.go
@@ -24,8 +24,9 @@ func TestCPUProfile(t *testing.T) {
}
vers := string(out)
t.Logf("uname -a: %v", vers)
- if strings.Contains(vers, "Darwin Kernel Version 10.8.0") && strings.Contains(vers, "root:xnu-1504.15.3~1/RELEASE_X86_64") {
- t.Logf("skipping test on known-broken kernel (64-bit Snow Leopard)")
+ // Lion uses "Darwin Kernel Version 11".
+ if strings.Contains(vers, "Darwin Kernel Version 10") && strings.Contains(vers, "RELEASE_X86_64") {
+ t.Logf("skipping test on known-broken kernel (64-bit Leopard / Snow Leopard)")
return
}
case "plan9":
diff --git a/libgo/go/sort/sort.go b/libgo/go/sort/sort.go
index 31da3c83d0d..62a4d55e798 100644
--- a/libgo/go/sort/sort.go
+++ b/libgo/go/sort/sort.go
@@ -183,17 +183,21 @@ func quickSort(data Interface, a, b, maxDepth int) {
}
}
+// Sort sorts data.
+// It makes one call to data.Len to determine n, and O(n*log(n)) calls to
+// data.Less and data.Swap. The sort is not guaranteed to be stable.
func Sort(data Interface) {
- // Switch to heapsort if depth of 2*ceil(lg(n)) is reached.
+ // Switch to heapsort if depth of 2*ceil(lg(n+1)) is reached.
n := data.Len()
maxDepth := 0
- for 1<<uint(maxDepth) < n {
+ for i := n; i > 0; i >>= 1 {
maxDepth++
}
maxDepth *= 2
quickSort(data, 0, n, maxDepth)
}
+// IsSorted reports whether data is sorted.
func IsSorted(data Interface) bool {
n := data.Len()
for i := n - 1; i > 0; i-- {
diff --git a/libgo/go/strconv/isprint.go b/libgo/go/strconv/isprint.go
new file mode 100644
index 00000000000..a03a07bfb5f
--- /dev/null
+++ b/libgo/go/strconv/isprint.go
@@ -0,0 +1,521 @@
+// DO NOT EDIT. GENERATED BY
+// go run makeisprint.go >x && mv x isprint.go
+
+package strconv
+
+// (474+134+42)*2 + (180)*4 = 2020 bytes
+
+var isPrint16 = []uint16{
+ 0x0020, 0x007e,
+ 0x00a1, 0x0377,
+ 0x037a, 0x037e,
+ 0x0384, 0x0527,
+ 0x0531, 0x0556,
+ 0x0559, 0x058a,
+ 0x0591, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x0606, 0x061b,
+ 0x061e, 0x070d,
+ 0x0710, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07fa,
+ 0x0800, 0x082d,
+ 0x0830, 0x085b,
+ 0x085e, 0x085e,
+ 0x0900, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09e3,
+ 0x09e6, 0x09fb,
+ 0x0a01, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a39,
+ 0x0a3c, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5e,
+ 0x0a66, 0x0a75,
+ 0x0a81, 0x0ab9,
+ 0x0abc, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0af1,
+ 0x0b01, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b63,
+ 0x0b66, 0x0b77,
+ 0x0b82, 0x0b8a,
+ 0x0b8e, 0x0b95,
+ 0x0b99, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c01, 0x0c39,
+ 0x0c3d, 0x0c4d,
+ 0x0c55, 0x0c59,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c78, 0x0c7f,
+ 0x0c82, 0x0cb9,
+ 0x0cbc, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0ce3,
+ 0x0ce6, 0x0cf2,
+ 0x0d02, 0x0d3a,
+ 0x0d3d, 0x0d4e,
+ 0x0d57, 0x0d57,
+ 0x0d60, 0x0d63,
+ 0x0d66, 0x0d75,
+ 0x0d79, 0x0d7f,
+ 0x0d82, 0x0d96,
+ 0x0d9a, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0ddf,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e84,
+ 0x0e87, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0ea7,
+ 0x0eaa, 0x0ebd,
+ 0x0ec0, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edd,
+ 0x0f00, 0x0f6c,
+ 0x0f71, 0x0fda,
+ 0x1000, 0x10c5,
+ 0x10d0, 0x10fc,
+ 0x1100, 0x124d,
+ 0x1250, 0x125d,
+ 0x1260, 0x128d,
+ 0x1290, 0x12b5,
+ 0x12b8, 0x12c5,
+ 0x12c8, 0x1315,
+ 0x1318, 0x135a,
+ 0x135d, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f4,
+ 0x1400, 0x169c,
+ 0x16a0, 0x16f0,
+ 0x1700, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x1773,
+ 0x1780, 0x17b3,
+ 0x17b6, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180d,
+ 0x1810, 0x1819,
+ 0x1820, 0x1877,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191c,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa0, 0x1aad,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b7c,
+ 0x1b80, 0x1baa,
+ 0x1bae, 0x1bb9,
+ 0x1bc0, 0x1bf3,
+ 0x1bfc, 0x1c37,
+ 0x1c3b, 0x1c49,
+ 0x1c4d, 0x1c7f,
+ 0x1cd0, 0x1cf2,
+ 0x1d00, 0x1de6,
+ 0x1dfc, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f7d,
+ 0x1f80, 0x1fd3,
+ 0x1fd6, 0x1fef,
+ 0x1ff2, 0x1ffe,
+ 0x2010, 0x2027,
+ 0x2030, 0x205e,
+ 0x2070, 0x2071,
+ 0x2074, 0x209c,
+ 0x20a0, 0x20b9,
+ 0x20d0, 0x20f0,
+ 0x2100, 0x2189,
+ 0x2190, 0x23f3,
+ 0x2400, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x2b4c,
+ 0x2b50, 0x2b59,
+ 0x2c00, 0x2cf1,
+ 0x2cf9, 0x2d25,
+ 0x2d30, 0x2d65,
+ 0x2d6f, 0x2d70,
+ 0x2d7f, 0x2d96,
+ 0x2da0, 0x2e31,
+ 0x2e80, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3001, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312d,
+ 0x3131, 0x31ba,
+ 0x31c0, 0x31e3,
+ 0x31f0, 0x4db5,
+ 0x4dc0, 0x9fcb,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa4d0, 0xa62b,
+ 0xa640, 0xa673,
+ 0xa67c, 0xa697,
+ 0xa6a0, 0xa6f7,
+ 0xa700, 0xa791,
+ 0xa7a0, 0xa7a9,
+ 0xa7fa, 0xa82b,
+ 0xa830, 0xa839,
+ 0xa840, 0xa877,
+ 0xa880, 0xa8c4,
+ 0xa8ce, 0xa8d9,
+ 0xa8e0, 0xa8fb,
+ 0xa900, 0xa953,
+ 0xa95f, 0xa97c,
+ 0xa980, 0xa9d9,
+ 0xa9de, 0xa9df,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa5c, 0xaa7b,
+ 0xaa80, 0xaac2,
+ 0xaadb, 0xaadf,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab2e,
+ 0xabc0, 0xabed,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xf900, 0xfa2d,
+ 0xfa30, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfbc1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfd,
+ 0xfe00, 0xfe19,
+ 0xfe20, 0xfe26,
+ 0xfe30, 0xfe6b,
+ 0xfe70, 0xfefc,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffee,
+ 0xfffc, 0xfffd,
+}
+
+var isNotPrint16 = []uint16{
+ 0x00ad,
+ 0x038b,
+ 0x038d,
+ 0x03a2,
+ 0x0560,
+ 0x0588,
+ 0x06dd,
+ 0x083f,
+ 0x0978,
+ 0x0980,
+ 0x0984,
+ 0x09a9,
+ 0x09b1,
+ 0x09de,
+ 0x0a04,
+ 0x0a29,
+ 0x0a31,
+ 0x0a34,
+ 0x0a37,
+ 0x0a3d,
+ 0x0a5d,
+ 0x0a84,
+ 0x0a8e,
+ 0x0a92,
+ 0x0aa9,
+ 0x0ab1,
+ 0x0ab4,
+ 0x0ac6,
+ 0x0aca,
+ 0x0af0,
+ 0x0b04,
+ 0x0b29,
+ 0x0b31,
+ 0x0b34,
+ 0x0b5e,
+ 0x0b84,
+ 0x0b91,
+ 0x0b9b,
+ 0x0b9d,
+ 0x0bc9,
+ 0x0c04,
+ 0x0c0d,
+ 0x0c11,
+ 0x0c29,
+ 0x0c34,
+ 0x0c45,
+ 0x0c49,
+ 0x0c57,
+ 0x0c84,
+ 0x0c8d,
+ 0x0c91,
+ 0x0ca9,
+ 0x0cb4,
+ 0x0cc5,
+ 0x0cc9,
+ 0x0cdf,
+ 0x0cf0,
+ 0x0d04,
+ 0x0d0d,
+ 0x0d11,
+ 0x0d45,
+ 0x0d49,
+ 0x0d84,
+ 0x0db2,
+ 0x0dbc,
+ 0x0dd5,
+ 0x0dd7,
+ 0x0e83,
+ 0x0e89,
+ 0x0e98,
+ 0x0ea0,
+ 0x0ea4,
+ 0x0ea6,
+ 0x0eac,
+ 0x0eba,
+ 0x0ec5,
+ 0x0ec7,
+ 0x0f48,
+ 0x0f98,
+ 0x0fbd,
+ 0x0fcd,
+ 0x1249,
+ 0x1257,
+ 0x1259,
+ 0x1289,
+ 0x12b1,
+ 0x12bf,
+ 0x12c1,
+ 0x12d7,
+ 0x1311,
+ 0x1680,
+ 0x170d,
+ 0x176d,
+ 0x1771,
+ 0x1a5f,
+ 0x1f58,
+ 0x1f5a,
+ 0x1f5c,
+ 0x1f5e,
+ 0x1fb5,
+ 0x1fc5,
+ 0x1fdc,
+ 0x1ff5,
+ 0x208f,
+ 0x2700,
+ 0x27cb,
+ 0x27cd,
+ 0x2c2f,
+ 0x2c5f,
+ 0x2da7,
+ 0x2daf,
+ 0x2db7,
+ 0x2dbf,
+ 0x2dc7,
+ 0x2dcf,
+ 0x2dd7,
+ 0x2ddf,
+ 0x2e9a,
+ 0x3040,
+ 0x318f,
+ 0x321f,
+ 0x32ff,
+ 0xa78f,
+ 0xa9ce,
+ 0xab27,
+ 0xfb37,
+ 0xfb3d,
+ 0xfb3f,
+ 0xfb42,
+ 0xfb45,
+ 0xfe53,
+ 0xfe67,
+ 0xfe75,
+ 0xffe7,
+}
+
+var isPrint32 = []uint32{
+ 0x010000, 0x01004d,
+ 0x010050, 0x01005d,
+ 0x010080, 0x0100fa,
+ 0x010100, 0x010102,
+ 0x010107, 0x010133,
+ 0x010137, 0x01018a,
+ 0x010190, 0x01019b,
+ 0x0101d0, 0x0101fd,
+ 0x010280, 0x01029c,
+ 0x0102a0, 0x0102d0,
+ 0x010300, 0x010323,
+ 0x010330, 0x01034a,
+ 0x010380, 0x0103c3,
+ 0x0103c8, 0x0103d5,
+ 0x010400, 0x01049d,
+ 0x0104a0, 0x0104a9,
+ 0x010800, 0x010805,
+ 0x010808, 0x010838,
+ 0x01083c, 0x01083c,
+ 0x01083f, 0x01085f,
+ 0x010900, 0x01091b,
+ 0x01091f, 0x010939,
+ 0x01093f, 0x01093f,
+ 0x010a00, 0x010a06,
+ 0x010a0c, 0x010a33,
+ 0x010a38, 0x010a3a,
+ 0x010a3f, 0x010a47,
+ 0x010a50, 0x010a58,
+ 0x010a60, 0x010a7f,
+ 0x010b00, 0x010b35,
+ 0x010b39, 0x010b55,
+ 0x010b58, 0x010b72,
+ 0x010b78, 0x010b7f,
+ 0x010c00, 0x010c48,
+ 0x010e60, 0x010e7e,
+ 0x011000, 0x01104d,
+ 0x011052, 0x01106f,
+ 0x011080, 0x0110c1,
+ 0x012000, 0x01236e,
+ 0x012400, 0x012462,
+ 0x012470, 0x012473,
+ 0x013000, 0x01342e,
+ 0x016800, 0x016a38,
+ 0x01b000, 0x01b001,
+ 0x01d000, 0x01d0f5,
+ 0x01d100, 0x01d126,
+ 0x01d129, 0x01d172,
+ 0x01d17b, 0x01d1dd,
+ 0x01d200, 0x01d245,
+ 0x01d300, 0x01d356,
+ 0x01d360, 0x01d371,
+ 0x01d400, 0x01d49f,
+ 0x01d4a2, 0x01d4a2,
+ 0x01d4a5, 0x01d4a6,
+ 0x01d4a9, 0x01d50a,
+ 0x01d50d, 0x01d546,
+ 0x01d54a, 0x01d6a5,
+ 0x01d6a8, 0x01d7cb,
+ 0x01d7ce, 0x01d7ff,
+ 0x01f000, 0x01f02b,
+ 0x01f030, 0x01f093,
+ 0x01f0a0, 0x01f0ae,
+ 0x01f0b1, 0x01f0be,
+ 0x01f0c1, 0x01f0df,
+ 0x01f100, 0x01f10a,
+ 0x01f110, 0x01f169,
+ 0x01f170, 0x01f19a,
+ 0x01f1e6, 0x01f202,
+ 0x01f210, 0x01f23a,
+ 0x01f240, 0x01f248,
+ 0x01f250, 0x01f251,
+ 0x01f300, 0x01f320,
+ 0x01f330, 0x01f37c,
+ 0x01f380, 0x01f393,
+ 0x01f3a0, 0x01f3ca,
+ 0x01f3e0, 0x01f3f0,
+ 0x01f400, 0x01f4fc,
+ 0x01f500, 0x01f53d,
+ 0x01f550, 0x01f567,
+ 0x01f5fb, 0x01f625,
+ 0x01f628, 0x01f62d,
+ 0x01f630, 0x01f640,
+ 0x01f645, 0x01f64f,
+ 0x01f680, 0x01f6c5,
+ 0x01f700, 0x01f773,
+ 0x020000, 0x02a6d6,
+ 0x02a700, 0x02b734,
+ 0x02b740, 0x02b81d,
+ 0x02f800, 0x02fa1d,
+ 0x0e0100, 0x0e01ef,
+}
+
+var isNotPrint32 = []uint16{ // add 0x10000 to each entry
+ 0x000c,
+ 0x0027,
+ 0x003b,
+ 0x003e,
+ 0x031f,
+ 0x039e,
+ 0x0809,
+ 0x0836,
+ 0x0856,
+ 0x0a04,
+ 0x0a14,
+ 0x0a18,
+ 0x10bd,
+ 0xd455,
+ 0xd49d,
+ 0xd4ad,
+ 0xd4ba,
+ 0xd4bc,
+ 0xd4c4,
+ 0xd506,
+ 0xd515,
+ 0xd51d,
+ 0xd53a,
+ 0xd53f,
+ 0xd545,
+ 0xd551,
+ 0xf0d0,
+ 0xf12f,
+ 0xf336,
+ 0xf3c5,
+ 0xf43f,
+ 0xf441,
+ 0xf4f8,
+ 0xf600,
+ 0xf611,
+ 0xf615,
+ 0xf617,
+ 0xf619,
+ 0xf61b,
+ 0xf61f,
+ 0xf62c,
+ 0xf634,
+}
diff --git a/libgo/go/strconv/makeisprint.go b/libgo/go/strconv/makeisprint.go
new file mode 100644
index 00000000000..8a6699bdb52
--- /dev/null
+++ b/libgo/go/strconv/makeisprint.go
@@ -0,0 +1,162 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+// makeisprint generates the tables for strconv's compact isPrint.
+package main
+
+import (
+ "fmt"
+ "os"
+ "unicode"
+)
+
+var (
+ range16 []uint16
+ except16 []uint16
+ range32 []uint32
+ except32 []uint32
+)
+
+// bsearch16 returns the smallest i such that a[i] >= x.
+// If there is no such i, bsearch16 returns len(a).
+func bsearch16(a []uint16, x uint16) int {
+ i, j := 0, len(a)
+ for i < j {
+ h := i + (j-i)/2
+ if a[h] < x {
+ i = h + 1
+ } else {
+ j = h
+ }
+ }
+ return i
+}
+
+// bsearch32 returns the smallest i such that a[i] >= x.
+// If there is no such i, bsearch32 returns len(a).
+func bsearch32(a []uint32, x uint32) int {
+ i, j := 0, len(a)
+ for i < j {
+ h := i + (j-i)/2
+ if a[h] < x {
+ i = h + 1
+ } else {
+ j = h
+ }
+ }
+ return i
+}
+
+func isPrint(r rune) bool {
+ // Same algorithm, either on uint16 or uint32 value.
+ // First, find first i such that rang[i] >= x.
+ // This is the index of either the start or end of a pair that might span x.
+ // The start is even (rang[i&^1]) and the end is odd (rang[i|1]).
+ // If we find x in a range, make sure x is not in exception list.
+
+ if 0 <= r && r < 1<<16 {
+ rr, rang, except := uint16(r), range16, except16
+ i := bsearch16(rang, rr)
+ if i >= len(rang) || rr < rang[i&^1] || rang[i|1] < rr {
+ return false
+ }
+ j := bsearch16(except, rr)
+ return j >= len(except) || except[j] != rr
+ }
+
+ rr, rang, except := uint32(r), range32, except32
+ i := bsearch32(rang, rr)
+ if i >= len(rang) || rr < rang[i&^1] || rang[i|1] < rr {
+ return false
+ }
+ j := bsearch32(except, rr)
+ return j >= len(except) || except[j] != rr
+}
+
+func scan(min, max rune) (rang, except []uint32) {
+ lo := rune(-1)
+ for i := min; ; i++ {
+ if (i > max || !unicode.IsPrint(i)) && lo >= 0 {
+ // End range, but avoid flip flop.
+ if i+1 <= max && unicode.IsPrint(i+1) {
+ except = append(except, uint32(i))
+ continue
+ }
+ rang = append(rang, uint32(lo), uint32(i-1))
+ lo = -1
+ }
+ if i > max {
+ break
+ }
+ if lo < 0 && unicode.IsPrint(i) {
+ lo = i
+ }
+ }
+ return
+}
+
+func to16(x []uint32) []uint16 {
+ var y []uint16
+ for _, v := range x {
+ if uint32(uint16(v)) != v {
+ panic("bad 32->16 conversion")
+ }
+ y = append(y, uint16(v))
+ }
+ return y
+}
+
+func main() {
+ rang, except := scan(0, 0xFFFF)
+ range16 = to16(rang)
+ except16 = to16(except)
+ range32, except32 = scan(0x10000, unicode.MaxRune)
+
+ for i := rune(0); i <= unicode.MaxRune; i++ {
+ if isPrint(i) != unicode.IsPrint(i) {
+ fmt.Fprintf(os.Stderr, "%U: isPrint=%v, want %v\n", i, isPrint(i), unicode.IsPrint(i))
+ return
+ }
+ }
+
+ fmt.Printf("// DO NOT EDIT. GENERATED BY\n")
+ fmt.Printf("// go run makeisprint.go >x && mv x isprint.go\n\n")
+ fmt.Printf("package strconv\n\n")
+
+ fmt.Printf("// (%d+%d+%d)*2 + (%d)*4 = %d bytes\n\n",
+ len(range16), len(except16), len(except32),
+ len(range32),
+ (len(range16)+len(except16)+len(except32))*2+
+ (len(range32))*4)
+
+ fmt.Printf("var isPrint16 = []uint16{\n")
+ for i := 0; i < len(range16); i += 2 {
+ fmt.Printf("\t%#04x, %#04x,\n", range16[i], range16[i+1])
+ }
+ fmt.Printf("}\n\n")
+
+ fmt.Printf("var isNotPrint16 = []uint16{\n")
+ for _, r := range except16 {
+ fmt.Printf("\t%#04x,\n", r)
+ }
+ fmt.Printf("}\n\n")
+
+ fmt.Printf("var isPrint32 = []uint32{\n")
+ for i := 0; i < len(range32); i += 2 {
+ fmt.Printf("\t%#06x, %#06x,\n", range32[i], range32[i+1])
+ }
+ fmt.Printf("}\n\n")
+
+ fmt.Printf("var isNotPrint32 = []uint16{ // add 0x10000 to each entry\n")
+ for _, r := range except32 {
+ if r >= 0x20000 {
+ fmt.Fprintf(os.Stderr, "%U too big for isNotPrint32\n", r)
+ return
+ }
+ fmt.Printf("\t%#04x,\n", r-0x10000)
+ }
+ fmt.Printf("}\n")
+}
diff --git a/libgo/go/strconv/quote.go b/libgo/go/strconv/quote.go
index 61dbcae70f4..8a73f9d3b28 100644
--- a/libgo/go/strconv/quote.go
+++ b/libgo/go/strconv/quote.go
@@ -5,17 +5,15 @@
package strconv
import (
- "bytes"
- "strings"
- "unicode"
"unicode/utf8"
)
const lowerhex = "0123456789abcdef"
func quoteWith(s string, quote byte, ASCIIonly bool) string {
- var buf bytes.Buffer
- buf.WriteByte(quote)
+ var runeTmp [utf8.UTFMax]byte
+ buf := make([]byte, 0, 3*len(s)/2) // Try to avoid more allocations.
+ buf = append(buf, quote)
for width := 0; len(s) > 0; s = s[width:] {
r := rune(s[0])
width = 1
@@ -23,71 +21,72 @@ func quoteWith(s string, quote byte, ASCIIonly bool) string {
r, width = utf8.DecodeRuneInString(s)
}
if width == 1 && r == utf8.RuneError {
- buf.WriteString(`\x`)
- buf.WriteByte(lowerhex[s[0]>>4])
- buf.WriteByte(lowerhex[s[0]&0xF])
+ buf = append(buf, `\x`...)
+ buf = append(buf, lowerhex[s[0]>>4])
+ buf = append(buf, lowerhex[s[0]&0xF])
continue
}
if r == rune(quote) || r == '\\' { // always backslashed
- buf.WriteByte('\\')
- buf.WriteByte(byte(r))
+ buf = append(buf, '\\')
+ buf = append(buf, byte(r))
continue
}
if ASCIIonly {
- if r <= unicode.MaxASCII && unicode.IsPrint(r) {
- buf.WriteRune(r)
+ if r < utf8.RuneSelf && IsPrint(r) {
+ buf = append(buf, byte(r))
continue
}
- } else if unicode.IsPrint(r) {
- buf.WriteRune(r)
+ } else if IsPrint(r) {
+ n := utf8.EncodeRune(runeTmp[:], r)
+ buf = append(buf, runeTmp[:n]...)
continue
}
switch r {
case '\a':
- buf.WriteString(`\a`)
+ buf = append(buf, `\a`...)
case '\b':
- buf.WriteString(`\b`)
+ buf = append(buf, `\b`...)
case '\f':
- buf.WriteString(`\f`)
+ buf = append(buf, `\f`...)
case '\n':
- buf.WriteString(`\n`)
+ buf = append(buf, `\n`...)
case '\r':
- buf.WriteString(`\r`)
+ buf = append(buf, `\r`...)
case '\t':
- buf.WriteString(`\t`)
+ buf = append(buf, `\t`...)
case '\v':
- buf.WriteString(`\v`)
+ buf = append(buf, `\v`...)
default:
switch {
case r < ' ':
- buf.WriteString(`\x`)
- buf.WriteByte(lowerhex[s[0]>>4])
- buf.WriteByte(lowerhex[s[0]&0xF])
- case r > unicode.MaxRune:
+ buf = append(buf, `\x`...)
+ buf = append(buf, lowerhex[s[0]>>4])
+ buf = append(buf, lowerhex[s[0]&0xF])
+ case r > utf8.MaxRune:
r = 0xFFFD
fallthrough
case r < 0x10000:
- buf.WriteString(`\u`)
+ buf = append(buf, `\u`...)
for s := 12; s >= 0; s -= 4 {
- buf.WriteByte(lowerhex[r>>uint(s)&0xF])
+ buf = append(buf, lowerhex[r>>uint(s)&0xF])
}
default:
- buf.WriteString(`\U`)
+ buf = append(buf, `\U`...)
for s := 28; s >= 0; s -= 4 {
- buf.WriteByte(lowerhex[r>>uint(s)&0xF])
+ buf = append(buf, lowerhex[r>>uint(s)&0xF])
}
}
}
}
- buf.WriteByte(quote)
- return buf.String()
+ buf = append(buf, quote)
+ return string(buf)
}
// Quote returns a double-quoted Go string literal representing s. The
// returned string uses Go escape sequences (\t, \n, \xFF, \u0100) for
// control characters and non-printable characters as defined by
-// unicode.IsPrint.
+// IsPrint.
func Quote(s string) string {
return quoteWith(s, '"', false)
}
@@ -100,8 +99,7 @@ func AppendQuote(dst []byte, s string) []byte {
// QuoteToASCII returns a double-quoted Go string literal representing s.
// The returned string uses Go escape sequences (\t, \n, \xFF, \u0100) for
-// non-ASCII characters and non-printable characters as defined by
-// unicode.IsPrint.
+// non-ASCII characters and non-printable characters as defined by IsPrint.
func QuoteToASCII(s string) string {
return quoteWith(s, '"', true)
}
@@ -114,8 +112,7 @@ func AppendQuoteToASCII(dst []byte, s string) []byte {
// QuoteRune returns a single-quoted Go character literal representing the
// rune. The returned string uses Go escape sequences (\t, \n, \xFF, \u0100)
-// for control characters and non-printable characters as defined by
-// unicode.IsPrint.
+// for control characters and non-printable characters as defined by IsPrint.
func QuoteRune(r rune) string {
// TODO: avoid the allocation here.
return quoteWith(string(r), '\'', false)
@@ -130,7 +127,7 @@ func AppendQuoteRune(dst []byte, r rune) []byte {
// QuoteRuneToASCII returns a single-quoted Go character literal representing
// the rune. The returned string uses Go escape sequences (\t, \n, \xFF,
// \u0100) for non-ASCII characters and non-printable characters as defined
-// by unicode.IsPrint.
+// by IsPrint.
func QuoteRuneToASCII(r rune) string {
// TODO: avoid the allocation here.
return quoteWith(string(r), '\'', true)
@@ -245,7 +242,7 @@ func UnquoteChar(s string, quote byte) (value rune, multibyte bool, tail string,
value = v
break
}
- if v > unicode.MaxRune {
+ if v > utf8.MaxRune {
err = ErrSyntax
return
}
@@ -304,7 +301,7 @@ func Unquote(s string) (t string, err error) {
s = s[1 : n-1]
if quote == '`' {
- if strings.Contains(s, "`") {
+ if contains(s, '`') {
return "", ErrSyntax
}
return s, nil
@@ -312,12 +309,12 @@ func Unquote(s string) (t string, err error) {
if quote != '"' && quote != '\'' {
return "", ErrSyntax
}
- if strings.Index(s, "\n") >= 0 {
+ if contains(s, '\n') {
return "", ErrSyntax
}
// Is it trivial? Avoid allocation.
- if strings.Index(s, `\`) < 0 && strings.IndexRune(s, rune(quote)) < 0 {
+ if !contains(s, '\\') && !contains(s, quote) {
switch quote {
case '"':
return s, nil
@@ -329,7 +326,8 @@ func Unquote(s string) (t string, err error) {
}
}
- var buf bytes.Buffer
+ var runeTmp [utf8.UTFMax]byte
+ buf := make([]byte, 0, 3*len(s)/2) // Try to avoid more allocations.
for len(s) > 0 {
c, multibyte, ss, err := UnquoteChar(s, quote)
if err != nil {
@@ -337,14 +335,107 @@ func Unquote(s string) (t string, err error) {
}
s = ss
if c < utf8.RuneSelf || !multibyte {
- buf.WriteByte(byte(c))
+ buf = append(buf, byte(c))
} else {
- buf.WriteString(string(c))
+ n := utf8.EncodeRune(runeTmp[:], c)
+ buf = append(buf, runeTmp[:n]...)
}
if quote == '\'' && len(s) != 0 {
// single-quoted must be single character
return "", ErrSyntax
}
}
- return buf.String(), nil
+ return string(buf), nil
+}
+
+// contains reports whether the string contains the byte c.
+func contains(s string, c byte) bool {
+ for i := 0; i < len(s); i++ {
+ if s[i] == c {
+ return true
+ }
+ }
+ return false
+}
+
+// bsearch16 returns the smallest i such that a[i] >= x.
+// If there is no such i, bsearch16 returns len(a).
+func bsearch16(a []uint16, x uint16) int {
+ i, j := 0, len(a)
+ for i < j {
+ h := i + (j-i)/2
+ if a[h] < x {
+ i = h + 1
+ } else {
+ j = h
+ }
+ }
+ return i
+}
+
+// bsearch32 returns the smallest i such that a[i] >= x.
+// If there is no such i, bsearch32 returns len(a).
+func bsearch32(a []uint32, x uint32) int {
+ i, j := 0, len(a)
+ for i < j {
+ h := i + (j-i)/2
+ if a[h] < x {
+ i = h + 1
+ } else {
+ j = h
+ }
+ }
+ return i
+}
+
+// TODO: IsPrint is a local implementation of unicode.IsPrint, verified by the tests
+// to give the same answer. It allows this package not to depend on unicode,
+// and therefore not pull in all the Unicode tables. If the linker were better
+// at tossing unused tables, we could get rid of this implementation.
+// That would be nice.
+
+// IsPrint reports whether the rune is defined as printable by Go, with
+// the same definition as unicode.IsPrint: letters, numbers, punctuation,
+// symbols and ASCII space.
+func IsPrint(r rune) bool {
+ // Fast check for Latin-1
+ if r <= 0xFF {
+ if 0x20 <= r && r <= 0x7E {
+ // All the ASCII is printable from space through DEL-1.
+ return true
+ }
+ if 0xA1 <= r && r <= 0xFF {
+ // Similarly for ¡ through ÿ...
+ return r != 0xAD // ...except for the bizarre soft hyphen.
+ }
+ return false
+ }
+
+ // Same algorithm, either on uint16 or uint32 value.
+ // First, find first i such that isPrint[i] >= x.
+ // This is the index of either the start or end of a pair that might span x.
+ // The start is even (isPrint[i&^1]) and the end is odd (isPrint[i|1]).
+ // If we find x in a range, make sure x is not in isNotPrint list.
+
+ if 0 <= r && r < 1<<16 {
+ rr, isPrint, isNotPrint := uint16(r), isPrint16, isNotPrint16
+ i := bsearch16(isPrint, rr)
+ if i >= len(isPrint) || rr < isPrint[i&^1] || isPrint[i|1] < rr {
+ return false
+ }
+ j := bsearch16(isNotPrint, rr)
+ return j >= len(isNotPrint) || isNotPrint[j] != rr
+ }
+
+ rr, isPrint, isNotPrint := uint32(r), isPrint32, isNotPrint32
+ i := bsearch32(isPrint, rr)
+ if i >= len(isPrint) || rr < isPrint[i&^1] || isPrint[i|1] < rr {
+ return false
+ }
+ if r >= 0x20000 {
+ return true
+ }
+ r -= 0x10000
+ j := bsearch16(isNotPrint, uint16(r))
+ return j >= len(isNotPrint) || isNotPrint[j] != uint16(r)
}
diff --git a/libgo/go/strconv/quote_test.go b/libgo/go/strconv/quote_test.go
index 3f544c43cd5..61d9bf9a571 100644
--- a/libgo/go/strconv/quote_test.go
+++ b/libgo/go/strconv/quote_test.go
@@ -7,8 +7,23 @@ package strconv_test
import (
. "strconv"
"testing"
+ "unicode"
)
+// Verify that our isPrint agrees with unicode.IsPrint
+func TestIsPrint(t *testing.T) {
+ n := 0
+ for r := rune(0); r <= unicode.MaxRune; r++ {
+ if IsPrint(r) != unicode.IsPrint(r) {
+ t.Errorf("IsPrint(%U)=%t incorrect", r, IsPrint(r))
+ n++
+ if n > 10 {
+ return
+ }
+ }
+ }
+}
+
type quoteTest struct {
in string
out string
diff --git a/libgo/go/strings/example_test.go b/libgo/go/strings/example_test.go
index daeb85ef6bb..11417107282 100644
--- a/libgo/go/strings/example_test.go
+++ b/libgo/go/strings/example_test.go
@@ -60,7 +60,7 @@ func ExampleIndex() {
// -1
}
-func ExampleRune() {
+func ExampleIndexRune() {
fmt.Println(strings.IndexRune("chicken", 'k'))
fmt.Println(strings.IndexRune("chicken", 'd'))
// Output:
diff --git a/libgo/go/sync/atomic/atomic_test.go b/libgo/go/sync/atomic/atomic_test.go
index a06c85c3a9e..f60d997ce83 100644
--- a/libgo/go/sync/atomic/atomic_test.go
+++ b/libgo/go/sync/atomic/atomic_test.go
@@ -1012,6 +1012,10 @@ func TestHammerStoreLoad(t *testing.T) {
}
func TestStoreLoadSeqCst32(t *testing.T) {
+ if runtime.NumCPU() == 1 {
+ t.Logf("Skipping test on %v processor machine", runtime.NumCPU())
+ return
+ }
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
N := int32(1e3)
if testing.Short() {
@@ -1049,6 +1053,10 @@ func TestStoreLoadSeqCst32(t *testing.T) {
}
func TestStoreLoadSeqCst64(t *testing.T) {
+ if runtime.NumCPU() == 1 {
+ t.Logf("Skipping test on %v processor machine", runtime.NumCPU())
+ return
+ }
if test64err != nil {
t.Logf("Skipping 64-bit tests: %v", test64err)
return
@@ -1090,6 +1098,10 @@ func TestStoreLoadSeqCst64(t *testing.T) {
}
func TestStoreLoadRelAcq32(t *testing.T) {
+ if runtime.NumCPU() == 1 {
+ t.Logf("Skipping test on %v processor machine", runtime.NumCPU())
+ return
+ }
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
N := int32(1e3)
if testing.Short() {
@@ -1132,6 +1144,10 @@ func TestStoreLoadRelAcq32(t *testing.T) {
}
func TestStoreLoadRelAcq64(t *testing.T) {
+ if runtime.NumCPU() == 1 {
+ t.Logf("Skipping test on %v processor machine", runtime.NumCPU())
+ return
+ }
if test64err != nil {
t.Logf("Skipping 64-bit tests: %v", test64err)
return
diff --git a/libgo/go/syscall/mksyscall.awk b/libgo/go/syscall/mksyscall.awk
index 5e30e863231..b81796031ca 100644
--- a/libgo/go/syscall/mksyscall.awk
+++ b/libgo/go/syscall/mksyscall.awk
@@ -199,6 +199,7 @@ BEGIN {
}
printf("c_%s(%s)\n", cfnname, args)
+ seterr = 0
if (gofnresults != "") {
fields = split(gofnresults, goresults, ", *")
if (fields > 2) {
@@ -218,13 +219,17 @@ BEGIN {
gotype = goparam[2]
if (goname == "err") {
+ print "\tvar errno Errno"
+ print "\tsetErrno := false"
if (cfnresult ~ /^\*/) {
print "\tif _r == nil {"
} else {
print "\tif _r < 0 {"
}
- print "\t\terr = GetErrno()"
+ print "\t\terrno = GetErrno()"
+ print "\t\tsetErrno = true"
print "\t}"
+ seterr = 1
} else if (gotype == "uintptr" && cfnresult ~ /^\*/) {
printf("\t%s = (%s)(unsafe.Pointer(_r))\n", goname, gotype)
} else {
@@ -243,6 +248,12 @@ BEGIN {
print "\tExitsyscall()"
}
+ if (seterr) {
+ print "\tif setErrno {"
+ print "\t\terr = errno"
+ print "\t}"
+ }
+
if (gofnresults != "") {
print "\treturn"
}
diff --git a/libgo/go/testing/testing.go b/libgo/go/testing/testing.go
index 7072262a91d..1cb8a078c6d 100644
--- a/libgo/go/testing/testing.go
+++ b/libgo/go/testing/testing.go
@@ -108,6 +108,8 @@ var (
cpuListStr = flag.String("test.cpu", "", "comma-separated list of number of CPUs to use for each test")
parallel = flag.Int("test.parallel", runtime.GOMAXPROCS(0), "maximum test parallelism")
+ haveExamples bool // are there examples?
+
cpuList []int
)
@@ -280,6 +282,7 @@ func Main(matchString func(pat, str string) (bool, error), tests []InternalTest,
before()
startAlarm()
+ haveExamples = len(examples) > 0
testOk := RunTests(matchString, tests)
exampleOk := RunExamples(matchString, examples)
if !testOk || !exampleOk {
@@ -304,7 +307,7 @@ func (t *T) report() {
func RunTests(matchString func(pat, str string) (bool, error), tests []InternalTest) (ok bool) {
ok = true
- if len(tests) == 0 {
+ if len(tests) == 0 && !haveExamples {
fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
return
}
diff --git a/libgo/go/text/template/doc.go b/libgo/go/text/template/doc.go
index 10e0f7fc373..aa50ab97f6f 100644
--- a/libgo/go/text/template/doc.go
+++ b/libgo/go/text/template/doc.go
@@ -244,7 +244,7 @@ Functions
During execution functions are found in two function maps: first in the
template, then in the global function map. By default, no functions are defined
-in the template but the Funcs methods can be used to add them.
+in the template but the Funcs method can be used to add them.
Predefined global functions are named as follows.
diff --git a/libgo/go/text/template/exec.go b/libgo/go/text/template/exec.go
index ad0118e4e68..9a720cf43e3 100644
--- a/libgo/go/text/template/exec.go
+++ b/libgo/go/text/template/exec.go
@@ -369,6 +369,7 @@ func (s *state) evalVariableNode(dot reflect.Value, v *parse.VariableNode, args
// $x.Field has $x as the first ident, Field as the second. Eval the var, then the fields.
value := s.varValue(v.Ident[0])
if len(v.Ident) == 1 {
+ s.notAFunction(args, final)
return value
}
return s.evalFieldChain(dot, value, v.Ident[1:], args, final)
diff --git a/libgo/go/text/template/exec_test.go b/libgo/go/text/template/exec_test.go
index 70ab39cad20..5446027ff7a 100644
--- a/libgo/go/text/template/exec_test.go
+++ b/libgo/go/text/template/exec_test.go
@@ -466,6 +466,10 @@ var execTests = []execTest{
{"bug6b", "{{vfunc .V0 .V0}}", "vfunc", tVal, true},
{"bug6c", "{{vfunc .V1 .V0}}", "vfunc", tVal, true},
{"bug6d", "{{vfunc .V1 .V1}}", "vfunc", tVal, true},
+ // Legal parse but illegal execution: non-function should have no arguments.
+ {"bug7a", "{{3 2}}", "", tVal, false},
+ {"bug7b", "{{$x := 1}}{{$x 2}}", "", tVal, false},
+ {"bug7c", "{{$x := 1}}{{3 | $x}}", "", tVal, false},
}
func zeroArgs() string {
diff --git a/libgo/go/text/template/multi_test.go b/libgo/go/text/template/multi_test.go
index 22dedc4f839..bd98bd047ec 100644
--- a/libgo/go/text/template/multi_test.go
+++ b/libgo/go/text/template/multi_test.go
@@ -93,7 +93,7 @@ var multiExecTests = []execTest{
{"invoke dot []int", `{{template "dot" .SI}}`, "[3 4 5]", tVal, true},
{"invoke dotV", `{{template "dotV" .U}}`, "v", tVal, true},
{"invoke nested int", `{{template "nested" .I}}`, "17", tVal, true},
- {"variable declared by template", `{{template "nested" $x=.SI}},{{index $x 1}}`, "[3 4 5],4", tVal, true},
+ {"variable declared by template", `{{template "nested" $x:=.SI}},{{index $x 1}}`, "[3 4 5],4", tVal, true},
// User-defined function: test argument evaluator.
{"testFunc literal", `{{oneArg "joe"}}`, "oneArg=joe", tVal, true},
diff --git a/libgo/go/text/template/parse/lex.go b/libgo/go/text/template/parse/lex.go
index 54e75ee0ca2..7705c0b88ff 100644
--- a/libgo/go/text/template/parse/lex.go
+++ b/libgo/go/text/template/parse/lex.go
@@ -347,6 +347,9 @@ Loop:
default:
l.backup()
word := l.input[l.start:l.pos]
+ if !l.atTerminator() {
+ return l.errorf("unexpected character %+U", r)
+ }
switch {
case key[word] > itemKeyword:
l.emit(key[word])
@@ -365,6 +368,28 @@ Loop:
return lexInsideAction
}
+// atTerminator reports whether the input is at valid termination character to
+// appear after an identifier. Mostly to catch cases like "$x+2" not being
+// acceptable without a space, in case we decide one day to implement
+// arithmetic.
+func (l *lexer) atTerminator() bool {
+ r := l.peek()
+ if isSpace(r) {
+ return true
+ }
+ switch r {
+ case eof, ',', '|', ':':
+ return true
+ }
+ // Does r start the delimiter? This can be ambiguous (with delim=="//", $x/2 will
+ // succeed but should fail) but only in extremely rare cases caused by willfully
+ // bad choice of delimiter.
+ if rd, _ := utf8.DecodeRuneInString(l.rightDelim); rd == r {
+ return true
+ }
+ return false
+}
+
// lexChar scans a character constant. The initial quote is already
// scanned. Syntax checking is done by the parse.
func lexChar(l *lexer) stateFn {
diff --git a/libgo/go/text/template/parse/parse.go b/libgo/go/text/template/parse/parse.go
index d67b3888085..c0087b2785b 100644
--- a/libgo/go/text/template/parse/parse.go
+++ b/libgo/go/text/template/parse/parse.go
@@ -326,7 +326,7 @@ func (t *Tree) pipeline(context string) (pipe *PipeNode) {
for {
if v := t.peek(); v.typ == itemVariable {
t.next()
- if next := t.peek(); next.typ == itemColonEquals || next.typ == itemChar {
+ if next := t.peek(); next.typ == itemColonEquals || (next.typ == itemChar && next.val == ",") {
t.next()
variable := newVariable(v.val)
if len(variable.Ident) != 1 {
diff --git a/libgo/go/text/template/parse/parse_test.go b/libgo/go/text/template/parse/parse_test.go
index 18c0a8b835e..b2e788238d3 100644
--- a/libgo/go/text/template/parse/parse_test.go
+++ b/libgo/go/text/template/parse/parse_test.go
@@ -201,6 +201,10 @@ var parseTests = []parseTest{
`{{range .X | .M}}"true"{{else}}"false"{{end}}`},
{"range []int", "{{range .SI}}{{.}}{{end}}", noError,
`{{range .SI}}{{.}}{{end}}`},
+ {"range 1 var", "{{range $x := .SI}}{{.}}{{end}}", noError,
+ `{{range $x := .SI}}{{.}}{{end}}`},
+ {"range 2 vars", "{{range $x, $y := .SI}}{{.}}{{end}}", noError,
+ `{{range $x, $y := .SI}}{{.}}{{end}}`},
{"constants", "{{range .SI 1 -3.2i true false 'a'}}{{end}}", noError,
`{{range .SI 1 -3.2i true false 'a'}}{{end}}`},
{"template", "{{template `x`}}", noError,
@@ -226,6 +230,17 @@ var parseTests = []parseTest{
{"invalid punctuation", "{{printf 3, 4}}", hasError, ""},
{"multidecl outside range", "{{with $v, $u := 3}}{{end}}", hasError, ""},
{"too many decls in range", "{{range $u, $v, $w := 3}}{{end}}", hasError, ""},
+ // Equals (and other chars) do not assignments make (yet).
+ {"bug0a", "{{$x := 0}}{{$x}}", noError, "{{$x := 0}}{{$x}}"},
+ {"bug0b", "{{$x = 1}}{{$x}}", hasError, ""},
+ {"bug0c", "{{$x ! 2}}{{$x}}", hasError, ""},
+ {"bug0d", "{{$x % 3}}{{$x}}", hasError, ""},
+ // Check the parse fails for := rather than comma.
+ {"bug0e", "{{range $x := $y := 3}}{{end}}", hasError, ""},
+ // Another bug: variable read must ignore following punctuation.
+ {"bug1a", "{{$x:=.}}{{$x!2}}", hasError, ""}, // ! is just illegal here.
+ {"bug1b", "{{$x:=.}}{{$x+2}}", hasError, ""}, // $x+2 should not parse as ($x) (+2).
+ {"bug1c", "{{$x:=.}}{{$x +2}}", noError, "{{$x := .}}{{$x +2}}"}, // It's OK with a space.
}
var builtins = map[string]interface{}{
diff --git a/libgo/go/time/tick_test.go b/libgo/go/time/tick_test.go
index 914f02c861c..d8a086ceb25 100644
--- a/libgo/go/time/tick_test.go
+++ b/libgo/go/time/tick_test.go
@@ -22,7 +22,7 @@ func TestTicker(t *testing.T) {
dt := t1.Sub(t0)
target := Delta * Count
slop := target * 2 / 10
- if dt < target-slop || dt > target+slop {
+ if dt < target-slop || (!testing.Short() && dt > target+slop) {
t.Fatalf("%d %s ticks took %s, expected [%s,%s]", Count, Delta, dt, target-slop, target+slop)
}
// Now test that the ticker stopped
diff --git a/libgo/go/time/time.go b/libgo/go/time/time.go
index f7ded24d292..473bc2a4516 100644
--- a/libgo/go/time/time.go
+++ b/libgo/go/time/time.go
@@ -13,7 +13,8 @@ import "errors"
//
// Programs using times should typically store and pass them as values,
// not pointers. That is, time variables and struct fields should be of
-// type time.Time, not *time.Time.
+// type time.Time, not *time.Time. A Time value can be used by
+// multiple goroutines simultaneously.
//
// Time instants can be compared using the Before, After, and Equal methods.
// The Sub method subtracts two instants, producing a Duration.
@@ -755,13 +756,13 @@ func (t Time) Zone() (name string, offset int) {
return
}
-// Unix returns the Unix time, the number of seconds elapsed
+// Unix returns t as a Unix time, the number of seconds elapsed
// since January 1, 1970 UTC.
func (t Time) Unix() int64 {
return t.sec + internalToUnix
}
-// UnixNano returns the Unix time, the number of nanoseconds elapsed
+// UnixNano returns t as a Unix time, the number of nanoseconds elapsed
// since January 1, 1970 UTC.
func (t Time) UnixNano() int64 {
return (t.sec+internalToUnix)*1e9 + int64(t.nsec)
diff --git a/libgo/go/unicode/utf16/export_test.go b/libgo/go/unicode/utf16/export_test.go
new file mode 100644
index 00000000000..306247e48f1
--- /dev/null
+++ b/libgo/go/unicode/utf16/export_test.go
@@ -0,0 +1,11 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package utf16
+
+// Extra names for constants so we can validate them during testing.
+const (
+ MaxRune = maxRune
+ ReplacementChar = replacementChar
+)
diff --git a/libgo/go/unicode/utf16/utf16.go b/libgo/go/unicode/utf16/utf16.go
index 2b2eb28f2df..903e4012aa4 100644
--- a/libgo/go/unicode/utf16/utf16.go
+++ b/libgo/go/unicode/utf16/utf16.go
@@ -5,7 +5,14 @@
// Package utf16 implements encoding and decoding of UTF-16 sequences.
package utf16
-import "unicode"
+// The conditions replacementChar==unicode.ReplacementChar and
+// maxRune==unicode.MaxRune are verified in the tests.
+// Defining them locally avoids this package depending on package unicode.
+
+const (
+ replacementChar = '\uFFFD' // Unicode replacement character
+ maxRune = '\U0010FFFF' // Maximum valid Unicode code point.
+)
const (
// 0xd800-0xdc00 encodes the high 10 bits of a pair.
@@ -31,15 +38,15 @@ func DecodeRune(r1, r2 rune) rune {
if surr1 <= r1 && r1 < surr2 && surr2 <= r2 && r2 < surr3 {
return (rune(r1)-surr1)<<10 | (rune(r2) - surr2) + 0x10000
}
- return unicode.ReplacementChar
+ return replacementChar
}
// EncodeRune returns the UTF-16 surrogate pair r1, r2 for the given rune.
// If the rune is not a valid Unicode code point or does not need encoding,
// EncodeRune returns U+FFFD, U+FFFD.
func EncodeRune(r rune) (r1, r2 rune) {
- if r < surrSelf || r > unicode.MaxRune || IsSurrogate(r) {
- return unicode.ReplacementChar, unicode.ReplacementChar
+ if r < surrSelf || r > maxRune || IsSurrogate(r) {
+ return replacementChar, replacementChar
}
r -= surrSelf
return surr1 + (r>>10)&0x3ff, surr2 + r&0x3ff
@@ -58,8 +65,8 @@ func Encode(s []rune) []uint16 {
n = 0
for _, v := range s {
switch {
- case v < 0, surr1 <= v && v < surr3, v > unicode.MaxRune:
- v = unicode.ReplacementChar
+ case v < 0, surr1 <= v && v < surr3, v > maxRune:
+ v = replacementChar
fallthrough
case v < surrSelf:
a[n] = uint16(v)
@@ -89,7 +96,7 @@ func Decode(s []uint16) []rune {
n++
case surr1 <= r && r < surr3:
// invalid surrogate sequence
- a[n] = unicode.ReplacementChar
+ a[n] = replacementChar
n++
default:
// normal rune
diff --git a/libgo/go/unicode/utf16/utf16_test.go b/libgo/go/unicode/utf16/utf16_test.go
index d453b2f984d..ee16a303df3 100644
--- a/libgo/go/unicode/utf16/utf16_test.go
+++ b/libgo/go/unicode/utf16/utf16_test.go
@@ -11,6 +11,16 @@ import (
. "unicode/utf16"
)
+// Validate the constants redefined from unicode.
+func TestConstants(t *testing.T) {
+ if MaxRune != unicode.MaxRune {
+ t.Errorf("utf16.maxRune is wrong: %x should be %x", MaxRune, unicode.MaxRune)
+ }
+ if ReplacementChar != unicode.ReplacementChar {
+ t.Errorf("utf16.replacementChar is wrong: %x should be %x", ReplacementChar, unicode.ReplacementChar)
+ }
+}
+
type encodeTest struct {
in []rune
out []uint16
diff --git a/libgo/go/unicode/utf8/utf8.go b/libgo/go/unicode/utf8/utf8.go
index 631533a5a35..57ea19e96d4 100644
--- a/libgo/go/unicode/utf8/utf8.go
+++ b/libgo/go/unicode/utf8/utf8.go
@@ -6,13 +6,16 @@
// UTF-8. It includes functions to translate between runes and UTF-8 byte sequences.
package utf8
-import "unicode" // only needed for a couple of constants
+// The conditions RuneError==unicode.ReplacementChar and
+// MaxRune==unicode.MaxRune are verified in the tests.
+// Defining them locally avoids this package depending on package unicode.
// Numbers fundamental to the encoding.
const (
- RuneError = unicode.ReplacementChar // the "error" Rune or "replacement character".
- RuneSelf = 0x80 // characters below Runeself are represented as themselves in a single byte.
- UTFMax = 4 // maximum number of bytes of a UTF-8 encoded Unicode character.
+ RuneError = '\uFFFD' // the "error" Rune or "Unicode replacement character"
+ RuneSelf = 0x80 // characters below Runeself are represented as themselves in a single byte.
+ MaxRune = '\U0010FFFF' // Maximum valid Unicode code point.
+ UTFMax = 4 // maximum number of bytes of a UTF-8 encoded Unicode character.
)
const (
@@ -309,7 +312,7 @@ func EncodeRune(p []byte, r rune) int {
return 2
}
- if uint32(r) > unicode.MaxRune {
+ if uint32(r) > MaxRune {
r = RuneError
}
diff --git a/libgo/go/unicode/utf8/utf8_test.go b/libgo/go/unicode/utf8/utf8_test.go
index 63514265bb9..4f73c8fb81a 100644
--- a/libgo/go/unicode/utf8/utf8_test.go
+++ b/libgo/go/unicode/utf8/utf8_test.go
@@ -7,9 +7,30 @@ package utf8_test
import (
"bytes"
"testing"
+ "unicode"
. "unicode/utf8"
)
+// Validate the constants redefined from unicode.
+func init() {
+ if MaxRune != unicode.MaxRune {
+ panic("utf8.MaxRune is wrong")
+ }
+ if RuneError != unicode.ReplacementChar {
+ panic("utf8.RuneError is wrong")
+ }
+}
+
+// Validate the constants redefined from unicode.
+func TestConstants(t *testing.T) {
+ if MaxRune != unicode.MaxRune {
+ t.Errorf("utf8.MaxRune is wrong: %x should be %x", MaxRune, unicode.MaxRune)
+ }
+ if RuneError != unicode.ReplacementChar {
+ t.Errorf("utf8.RuneError is wrong: %x should be %x", RuneError, unicode.ReplacementChar)
+ }
+}
+
type Utf8Map struct {
r rune
str string
diff --git a/libgo/merge.sh b/libgo/merge.sh
index 32652118fe5..9e2ca01cc96 100755
--- a/libgo/merge.sh
+++ b/libgo/merge.sh
@@ -163,7 +163,7 @@ done
done
done
-runtime="chan.c cpuprof.c goc2c.c lock_futex.c lock_sema.c mcache.c mcentral.c mfinal.c mfixalloc.c mgc0.c mheap.c msize.c proc.c runtime.c runtime.h signal_unix.c malloc.h malloc.goc mprof.goc runtime1.goc sema.goc sigqueue.goc string.goc time.goc"
+runtime="chan.c cpuprof.c lock_futex.c lock_sema.c mcache.c mcentral.c mfinal.c mfixalloc.c mgc0.c mheap.c msize.c proc.c runtime.c runtime.h signal_unix.c malloc.h malloc.goc mprof.goc runtime1.goc sema.goc sigqueue.goc string.goc time.goc"
for f in $runtime; do
merge_c $f $f
done
diff --git a/libgo/runtime/malloc.goc b/libgo/runtime/malloc.goc
index 3fde250af3b..97cfabe040a 100644
--- a/libgo/runtime/malloc.goc
+++ b/libgo/runtime/malloc.goc
@@ -390,6 +390,23 @@ runtime_MHeap_SysAlloc(MHeap *h, uintptr n)
{
byte *p;
+
+ if(n > (uintptr)(h->arena_end - h->arena_used)) {
+ // We are in 32-bit mode, maybe we didn't use all possible address space yet.
+ // Reserve some more space.
+ byte *new_end;
+ uintptr needed;
+
+ needed = (uintptr)h->arena_used + n - (uintptr)h->arena_end;
+ // Round wanted arena size to a multiple of 256MB.
+ needed = (needed + (256<<20) - 1) & ~((256<<20)-1);
+ new_end = h->arena_end + needed;
+ if(new_end <= h->arena_start + MaxArena32) {
+ p = runtime_SysReserve(h->arena_end, new_end - h->arena_end);
+ if(p == h->arena_end)
+ h->arena_end = new_end;
+ }
+ }
if(n <= (uintptr)(h->arena_end - h->arena_used)) {
// Keep taking from our reservation.
p = h->arena_used;
@@ -411,7 +428,8 @@ runtime_MHeap_SysAlloc(MHeap *h, uintptr n)
return nil;
if(p < h->arena_start || (uintptr)(p+n - h->arena_start) >= MaxArena32) {
- runtime_printf("runtime: memory allocated by OS not in usable range\n");
+ runtime_printf("runtime: memory allocated by OS (%p) not in usable range [%p,%p)\n",
+ p, h->arena_start, h->arena_start+MaxArena32);
runtime_SysFree(p, n);
return nil;
}
diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c
index 31e8287e704..9ad9f9659b9 100644
--- a/libgo/runtime/proc.c
+++ b/libgo/runtime/proc.c
@@ -406,7 +406,9 @@ runtime_schedinit(void)
n = maxgomaxprocs;
runtime_gomaxprocs = n;
}
- setmcpumax(runtime_gomaxprocs);
+ // wait for the main goroutine to start before taking
+ // GOMAXPROCS into account.
+ setmcpumax(1);
runtime_singleproc = runtime_gomaxprocs == 1;
canaddmcpu(); // mcpu++ to account for bootstrap m
@@ -432,6 +434,8 @@ runtime_main(void)
// by calling runtime.LockOSThread during initialization
// to preserve the lock.
runtime_LockOSThread();
+ // From now on, newgoroutines may use non-main threads.
+ setmcpumax(runtime_gomaxprocs);
runtime_sched.init = true;
scvg = __go_go(runtime_MHeap_Scavenger, nil);
main_init();
@@ -444,6 +448,11 @@ runtime_main(void)
// roots.
mstats.enablegc = 1;
+ // The deadlock detection has false negatives.
+ // Let scvg start up, to eliminate the false negative
+ // for the trivial program func main() { select{} }.
+ runtime_gosched();
+
main_main();
runtime_exit(0);
for(;;)
@@ -791,6 +800,20 @@ top:
}
// Look for deadlock situation.
+ // There is a race with the scavenger that causes false negatives:
+ // if the scavenger is just starting, then we have
+ // scvg != nil && grunning == 0 && gwait == 0
+ // and we do not detect a deadlock. It is possible that we should
+ // add that case to the if statement here, but it is too close to Go 1
+ // to make such a subtle change. Instead, we work around the
+ // false negative in trivial programs by calling runtime.gosched
+ // from the main goroutine just before main.main.
+ // See runtime_main above.
+ //
+ // On a related note, it is also possible that the scvg == nil case is
+ // wrong and should include gwait, but that does not happen in
+ // standard Go programs, which all start the scavenger.
+ //
if((scvg == nil && runtime_sched.grunning == 0) ||
(scvg != nil && runtime_sched.grunning == 1 && runtime_sched.gwait == 0 &&
(scvg->status == Grunning || scvg->status == Gsyscall))) {
@@ -962,6 +985,11 @@ runtime_mstart(void* mp)
}
#endif
+ // Install signal handlers; after minit so that minit can
+ // prepare the thread to be able to handle the signals.
+ if(m == &runtime_m0)
+ runtime_initsig();
+
schedule(nil);
return nil;
}
diff --git a/libgo/runtime/runtime.c b/libgo/runtime/runtime.c
index d1ce26db499..a0dbf80b0a0 100644
--- a/libgo/runtime/runtime.c
+++ b/libgo/runtime/runtime.c
@@ -74,7 +74,7 @@ void
runtime_panicstring(const char *s)
{
Eface err;
-
+
if(runtime_m()->gcing) {
runtime_printf("panic: %s\n", s);
runtime_throw("panic during gc");
@@ -101,7 +101,7 @@ runtime_goargs(void)
{
String *s;
int32 i;
-
+
// for windows implementation see "os" package
if(Windows)
return;
@@ -119,7 +119,7 @@ runtime_goenvs_unix(void)
{
String *s;
int32 i, n;
-
+
for(n=0; argv[argc+1+n] != 0; n++)
;
@@ -195,8 +195,6 @@ void
runtime_check(void)
{
__go_register_gc_roots(&runtime_roots);
-
- runtime_initsig ();
}
int64
diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h
index 2deb46ec8b4..a81c210a2b8 100644
--- a/libgo/runtime/runtime.h
+++ b/libgo/runtime/runtime.h
@@ -416,7 +416,6 @@ void runtime_usleep(uint32);
/*
* runtime c-called (but written in Go)
*/
-void runtime_newError(String, Eface*);
void runtime_printany(Eface)
__asm__("libgo_runtime.runtime.Printany");
void runtime_newTypeAssertionError(const String*, const String*, const String*, const String*, Eface*)
@@ -429,7 +428,6 @@ void runtime_newErrorString(String, Eface*)
*/
void runtime_semacquire(uint32 volatile *);
void runtime_semrelease(uint32 volatile *);
-String runtime_signame(int32 sig);
int32 runtime_gomaxprocsfunc(int32 n);
void runtime_procyield(uint32);
void runtime_osyield(void);
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 5bed2c69d50..66321424d45 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,8 @@
+2012-03-31 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR bootstrap/52812
+ * configure.tgt (i[456]86-*-linux*): Handle -mx32 like -m64.
+
2012-03-22 Jakub Jelinek <jakub@redhat.com>
PR middle-end/52547
diff --git a/libgomp/configure.tgt b/libgomp/configure.tgt
index 09cab5177ed..d5a1480e481 100644
--- a/libgomp/configure.tgt
+++ b/libgomp/configure.tgt
@@ -59,7 +59,7 @@ if test $enable_linux_futex = yes; then
i[456]86-*-linux*)
config_path="linux/x86 linux posix"
case " ${CC} ${CFLAGS} " in
- *" -m64 "*)
+ *" -m64 "*|*" -mx32 "*)
;;
*)
if test -z "$with_arch"; then
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index add9ff9d1a7..4a3f8034892 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,8 @@
+2012-04-02 Tristan Gingold <gingold@adacore.com>
+
+ * stack-limit.c: Includes ansidecl.h.
+ (stack_limit_increase): Add ATTRIBUTE_UNUSED
+
2012-03-20 Jason Merrill <jason@redhat.com>
* cp-demangle.c (cplus_demangle_type): Handle 'auto'.
diff --git a/libiberty/stack-limit.c b/libiberty/stack-limit.c
index e64cac28d1d..82c3d44498e 100644
--- a/libiberty/stack-limit.c
+++ b/libiberty/stack-limit.c
@@ -34,6 +34,7 @@ Attempt to increase stack size limit to @var{pref} bytes if possible.
*/
#include "config.h"
+#include "ansidecl.h"
#ifdef HAVE_STDINT_H
#include <stdint.h>
@@ -43,7 +44,7 @@ Attempt to increase stack size limit to @var{pref} bytes if possible.
#endif
void
-stack_limit_increase (unsigned long pref)
+stack_limit_increase (unsigned long pref ATTRIBUTE_UNUSED)
{
#if defined(HAVE_SETRLIMIT) && defined(HAVE_GETRLIMIT) \
&& defined(RLIMIT_STACK) && defined(RLIM_INFINITY)
diff --git a/libitm/ChangeLog b/libitm/ChangeLog
index ecc36adbc12..456d1cd190f 100644
--- a/libitm/ChangeLog
+++ b/libitm/ChangeLog
@@ -1,3 +1,12 @@
+2012-04-03 Tristan Gingold <gingold@adacore.com>
+
+ * configure: Regenerate.
+
+2012-03-31 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR bootstrap/52812
+ * configure.tgt (i[456]86-*-linux*): Handle -mx32 like -m64.
+
2012-03-16 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
* testsuite/lib/libitm.exp: load fortran-modules.exp
diff --git a/libitm/configure b/libitm/configure
index 76d11c42dd7..8e1d19ee5a8 100644
--- a/libitm/configure
+++ b/libitm/configure
@@ -15794,7 +15794,7 @@ else
# read() to the same fd. The only system known to have a problem here
# is VMS, where text files have record structure.
case "$host_os" in
- vms* | ultrix*)
+ *vms* | ultrix*)
gcc_cv_func_mmap_file=no ;;
*)
gcc_cv_func_mmap_file=yes;;
@@ -15818,7 +15818,7 @@ else
# Systems known to be in this category are Windows (all variants),
# VMS, and Darwin.
case "$host_os" in
- vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00)
+ *vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00)
gcc_cv_func_mmap_dev_zero=no ;;
*)
gcc_cv_func_mmap_dev_zero=yes;;
@@ -15875,7 +15875,7 @@ else
# above for use of /dev/zero.
# Systems known to be in this category are Windows, VMS, and SCO Unix.
case "$host_os" in
- vms* | cygwin* | pe | mingw* | sco* | udk* )
+ *vms* | cygwin* | pe | mingw* | sco* | udk* )
gcc_cv_func_mmap_anon=no ;;
*)
gcc_cv_func_mmap_anon=yes;;
diff --git a/libitm/configure.tgt b/libitm/configure.tgt
index e2a58885699..d6828e83cab 100644
--- a/libitm/configure.tgt
+++ b/libitm/configure.tgt
@@ -53,7 +53,7 @@ case "${target_cpu}" in
i[3456]86)
case " ${CC} ${CFLAGS} " in
- *" -m64 "*)
+ *" -m64 "*|*" -mx32 "*)
;;
*)
if test -z "$with_arch"; then
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 4f29ab4b3f7..bb8bc2a0f87 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,40 @@
+2012-04-02 Tristan Gingold <gingold@adacore.com>
+
+ * crossconfig.m4 (*-*-*vms*): Add.
+ * configure: Regenerate.
+
+2012-04-01 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ PR libstdc++/52591
+ * include/bits/stl_vector.h (vector::operator=(vector&&)): Dispatch
+ to _M_move_assign depending on whether allocator is moved.
+ (vector::_M_move_assign): Add overloaded functions.
+ * testsuite/23_containers/vector/52591.cc: New.
+ * testsuite/23_containers/vector/requirements/dr438/assign_neg.cc:
+ Adjust dg-error line number.
+ * testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc:
+ Likewise.
+ * testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc:
+ Likewise.
+ * testsuite/23_containers/vector/requirements/dr438/insert_neg.cc:
+ Likewise.
+
+2012-04-01 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * include/std/functional (__callable_functor): Overload for
+ volatile-qualified pointers.
+ * testsuite/20_util/function/10.cc: New.
+
+2012-03-30 Jeffrey Yasskin <jyasskin@gcc.gnu.org>
+ Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/52799
+ * include/bits/deque.tcc (emplace): Fix thinko, replace push_front
+ -> emplace_front, and likewise for *_back.
+ * testsuite/23_containers/deque/modifiers/emplace/52799.cc: New.
+ * testsuite/23_containers/list/modifiers/emplace/52799.cc: Likewise.
+ * testsuite/23_containers/vector/modifiers/emplace/52799.cc: Likewise.
+
2012-03-28 Benjamin Kosnik <bkoz@redhat.com>
PR libstdc++/52689
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 727979bbe0b..48f6ed6ff4e 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -63935,6 +63935,5667 @@ $as_echo "$ac_ld_relro" >&6; }
fi
;;
+ *-*vms*)
+ # Check for available headers.
+ # Don't call GLIBCXX_CHECK_LINKER_FEATURES, VMS doesn't have a GNU ld
+
+ ac_test_CXXFLAGS="${CXXFLAGS+set}"
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS='-fno-builtin -D_GNU_SOURCE'
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sin in -lm" >&5
+$as_echo_n "checking for sin in -lm... " >&6; }
+if test "${ac_cv_lib_m_sin+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+if test x$gcc_no_link = xyes; then
+ as_fn_error "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sin ();
+int
+main ()
+{
+return sin ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_sin=yes
+else
+ ac_cv_lib_m_sin=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sin" >&5
+$as_echo "$ac_cv_lib_m_sin" >&6; }
+if test "x$ac_cv_lib_m_sin" = x""yes; then :
+ libm="-lm"
+fi
+
+ ac_save_LIBS="$LIBS"
+ LIBS="$LIBS $libm"
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for isinf declaration" >&5
+$as_echo_n "checking for isinf declaration... " >&6; }
+ if test x${glibcxx_cv_func_isinf_use+set} != xset; then
+ if test "${glibcxx_cv_func_isinf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ isinf(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_isinf_use=yes
+else
+ glibcxx_cv_func_isinf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_isinf_use" >&5
+$as_echo "$glibcxx_cv_func_isinf_use" >&6; }
+
+ if test x$glibcxx_cv_func_isinf_use = x"yes"; then
+ for ac_func in isinf
+do :
+ ac_fn_c_check_func "$LINENO" "isinf" "ac_cv_func_isinf"
+if test "x$ac_cv_func_isinf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_ISINF 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _isinf declaration" >&5
+$as_echo_n "checking for _isinf declaration... " >&6; }
+ if test x${glibcxx_cv_func__isinf_use+set} != xset; then
+ if test "${glibcxx_cv_func__isinf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _isinf(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__isinf_use=yes
+else
+ glibcxx_cv_func__isinf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__isinf_use" >&5
+$as_echo "$glibcxx_cv_func__isinf_use" >&6; }
+
+ if test x$glibcxx_cv_func__isinf_use = x"yes"; then
+ for ac_func in _isinf
+do :
+ ac_fn_c_check_func "$LINENO" "_isinf" "ac_cv_func__isinf"
+if test "x$ac_cv_func__isinf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__ISINF 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for isnan declaration" >&5
+$as_echo_n "checking for isnan declaration... " >&6; }
+ if test x${glibcxx_cv_func_isnan_use+set} != xset; then
+ if test "${glibcxx_cv_func_isnan_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ isnan(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_isnan_use=yes
+else
+ glibcxx_cv_func_isnan_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_isnan_use" >&5
+$as_echo "$glibcxx_cv_func_isnan_use" >&6; }
+
+ if test x$glibcxx_cv_func_isnan_use = x"yes"; then
+ for ac_func in isnan
+do :
+ ac_fn_c_check_func "$LINENO" "isnan" "ac_cv_func_isnan"
+if test "x$ac_cv_func_isnan" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_ISNAN 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _isnan declaration" >&5
+$as_echo_n "checking for _isnan declaration... " >&6; }
+ if test x${glibcxx_cv_func__isnan_use+set} != xset; then
+ if test "${glibcxx_cv_func__isnan_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _isnan(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__isnan_use=yes
+else
+ glibcxx_cv_func__isnan_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__isnan_use" >&5
+$as_echo "$glibcxx_cv_func__isnan_use" >&6; }
+
+ if test x$glibcxx_cv_func__isnan_use = x"yes"; then
+ for ac_func in _isnan
+do :
+ ac_fn_c_check_func "$LINENO" "_isnan" "ac_cv_func__isnan"
+if test "x$ac_cv_func__isnan" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__ISNAN 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for finite declaration" >&5
+$as_echo_n "checking for finite declaration... " >&6; }
+ if test x${glibcxx_cv_func_finite_use+set} != xset; then
+ if test "${glibcxx_cv_func_finite_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ finite(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_finite_use=yes
+else
+ glibcxx_cv_func_finite_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_finite_use" >&5
+$as_echo "$glibcxx_cv_func_finite_use" >&6; }
+
+ if test x$glibcxx_cv_func_finite_use = x"yes"; then
+ for ac_func in finite
+do :
+ ac_fn_c_check_func "$LINENO" "finite" "ac_cv_func_finite"
+if test "x$ac_cv_func_finite" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FINITE 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _finite declaration" >&5
+$as_echo_n "checking for _finite declaration... " >&6; }
+ if test x${glibcxx_cv_func__finite_use+set} != xset; then
+ if test "${glibcxx_cv_func__finite_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _finite(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__finite_use=yes
+else
+ glibcxx_cv_func__finite_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__finite_use" >&5
+$as_echo "$glibcxx_cv_func__finite_use" >&6; }
+
+ if test x$glibcxx_cv_func__finite_use = x"yes"; then
+ for ac_func in _finite
+do :
+ ac_fn_c_check_func "$LINENO" "_finite" "ac_cv_func__finite"
+if test "x$ac_cv_func__finite" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__FINITE 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sincos declaration" >&5
+$as_echo_n "checking for sincos declaration... " >&6; }
+ if test x${glibcxx_cv_func_sincos_use+set} != xset; then
+ if test "${glibcxx_cv_func_sincos_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ sincos(0, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_sincos_use=yes
+else
+ glibcxx_cv_func_sincos_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_sincos_use" >&5
+$as_echo "$glibcxx_cv_func_sincos_use" >&6; }
+
+ if test x$glibcxx_cv_func_sincos_use = x"yes"; then
+ for ac_func in sincos
+do :
+ ac_fn_c_check_func "$LINENO" "sincos" "ac_cv_func_sincos"
+if test "x$ac_cv_func_sincos" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SINCOS 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _sincos declaration" >&5
+$as_echo_n "checking for _sincos declaration... " >&6; }
+ if test x${glibcxx_cv_func__sincos_use+set} != xset; then
+ if test "${glibcxx_cv_func__sincos_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _sincos(0, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__sincos_use=yes
+else
+ glibcxx_cv_func__sincos_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__sincos_use" >&5
+$as_echo "$glibcxx_cv_func__sincos_use" >&6; }
+
+ if test x$glibcxx_cv_func__sincos_use = x"yes"; then
+ for ac_func in _sincos
+do :
+ ac_fn_c_check_func "$LINENO" "_sincos" "ac_cv_func__sincos"
+if test "x$ac_cv_func__sincos" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__SINCOS 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fpclass declaration" >&5
+$as_echo_n "checking for fpclass declaration... " >&6; }
+ if test x${glibcxx_cv_func_fpclass_use+set} != xset; then
+ if test "${glibcxx_cv_func_fpclass_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ fpclass(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_fpclass_use=yes
+else
+ glibcxx_cv_func_fpclass_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_fpclass_use" >&5
+$as_echo "$glibcxx_cv_func_fpclass_use" >&6; }
+
+ if test x$glibcxx_cv_func_fpclass_use = x"yes"; then
+ for ac_func in fpclass
+do :
+ ac_fn_c_check_func "$LINENO" "fpclass" "ac_cv_func_fpclass"
+if test "x$ac_cv_func_fpclass" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FPCLASS 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _fpclass declaration" >&5
+$as_echo_n "checking for _fpclass declaration... " >&6; }
+ if test x${glibcxx_cv_func__fpclass_use+set} != xset; then
+ if test "${glibcxx_cv_func__fpclass_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _fpclass(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__fpclass_use=yes
+else
+ glibcxx_cv_func__fpclass_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__fpclass_use" >&5
+$as_echo "$glibcxx_cv_func__fpclass_use" >&6; }
+
+ if test x$glibcxx_cv_func__fpclass_use = x"yes"; then
+ for ac_func in _fpclass
+do :
+ ac_fn_c_check_func "$LINENO" "_fpclass" "ac_cv_func__fpclass"
+if test "x$ac_cv_func__fpclass" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__FPCLASS 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for qfpclass declaration" >&5
+$as_echo_n "checking for qfpclass declaration... " >&6; }
+ if test x${glibcxx_cv_func_qfpclass_use+set} != xset; then
+ if test "${glibcxx_cv_func_qfpclass_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ qfpclass(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_qfpclass_use=yes
+else
+ glibcxx_cv_func_qfpclass_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_qfpclass_use" >&5
+$as_echo "$glibcxx_cv_func_qfpclass_use" >&6; }
+
+ if test x$glibcxx_cv_func_qfpclass_use = x"yes"; then
+ for ac_func in qfpclass
+do :
+ ac_fn_c_check_func "$LINENO" "qfpclass" "ac_cv_func_qfpclass"
+if test "x$ac_cv_func_qfpclass" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_QFPCLASS 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _qfpclass declaration" >&5
+$as_echo_n "checking for _qfpclass declaration... " >&6; }
+ if test x${glibcxx_cv_func__qfpclass_use+set} != xset; then
+ if test "${glibcxx_cv_func__qfpclass_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _qfpclass(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__qfpclass_use=yes
+else
+ glibcxx_cv_func__qfpclass_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__qfpclass_use" >&5
+$as_echo "$glibcxx_cv_func__qfpclass_use" >&6; }
+
+ if test x$glibcxx_cv_func__qfpclass_use = x"yes"; then
+ for ac_func in _qfpclass
+do :
+ ac_fn_c_check_func "$LINENO" "_qfpclass" "ac_cv_func__qfpclass"
+if test "x$ac_cv_func__qfpclass" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__QFPCLASS 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for hypot declaration" >&5
+$as_echo_n "checking for hypot declaration... " >&6; }
+ if test x${glibcxx_cv_func_hypot_use+set} != xset; then
+ if test "${glibcxx_cv_func_hypot_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ hypot(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_hypot_use=yes
+else
+ glibcxx_cv_func_hypot_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_hypot_use" >&5
+$as_echo "$glibcxx_cv_func_hypot_use" >&6; }
+
+ if test x$glibcxx_cv_func_hypot_use = x"yes"; then
+ for ac_func in hypot
+do :
+ ac_fn_c_check_func "$LINENO" "hypot" "ac_cv_func_hypot"
+if test "x$ac_cv_func_hypot" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_HYPOT 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _hypot declaration" >&5
+$as_echo_n "checking for _hypot declaration... " >&6; }
+ if test x${glibcxx_cv_func__hypot_use+set} != xset; then
+ if test "${glibcxx_cv_func__hypot_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _hypot(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__hypot_use=yes
+else
+ glibcxx_cv_func__hypot_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__hypot_use" >&5
+$as_echo "$glibcxx_cv_func__hypot_use" >&6; }
+
+ if test x$glibcxx_cv_func__hypot_use = x"yes"; then
+ for ac_func in _hypot
+do :
+ ac_fn_c_check_func "$LINENO" "_hypot" "ac_cv_func__hypot"
+if test "x$ac_cv_func__hypot" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__HYPOT 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for float trig functions" >&5
+$as_echo_n "checking for float trig functions... " >&6; }
+ if test "${glibcxx_cv_func_float_trig_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+acosf (0); asinf (0); atanf (0); cosf (0); sinf (0); tanf (0); coshf (0); sinhf (0); tanhf (0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_float_trig_use=yes
+else
+ glibcxx_cv_func_float_trig_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_float_trig_use" >&5
+$as_echo "$glibcxx_cv_func_float_trig_use" >&6; }
+ if test x$glibcxx_cv_func_float_trig_use = x"yes"; then
+ for ac_func in acosf asinf atanf cosf sinf tanf coshf sinhf tanhf
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _float trig functions" >&5
+$as_echo_n "checking for _float trig functions... " >&6; }
+ if test "${glibcxx_cv_func__float_trig_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+_acosf (0); _asinf (0); _atanf (0); _cosf (0); _sinf (0); _tanf (0); _coshf (0); _sinhf (0); _tanhf (0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__float_trig_use=yes
+else
+ glibcxx_cv_func__float_trig_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__float_trig_use" >&5
+$as_echo "$glibcxx_cv_func__float_trig_use" >&6; }
+ if test x$glibcxx_cv_func__float_trig_use = x"yes"; then
+ for ac_func in _acosf _asinf _atanf _cosf _sinf _tanf _coshf _sinhf _tanhf
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for float round functions" >&5
+$as_echo_n "checking for float round functions... " >&6; }
+ if test "${glibcxx_cv_func_float_round_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ceilf (0); floorf (0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_float_round_use=yes
+else
+ glibcxx_cv_func_float_round_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_float_round_use" >&5
+$as_echo "$glibcxx_cv_func_float_round_use" >&6; }
+ if test x$glibcxx_cv_func_float_round_use = x"yes"; then
+ for ac_func in ceilf floorf
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _float round functions" >&5
+$as_echo_n "checking for _float round functions... " >&6; }
+ if test "${glibcxx_cv_func__float_round_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+_ceilf (0); _floorf (0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__float_round_use=yes
+else
+ glibcxx_cv_func__float_round_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__float_round_use" >&5
+$as_echo "$glibcxx_cv_func__float_round_use" >&6; }
+ if test x$glibcxx_cv_func__float_round_use = x"yes"; then
+ for ac_func in _ceilf _floorf
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for expf declaration" >&5
+$as_echo_n "checking for expf declaration... " >&6; }
+ if test x${glibcxx_cv_func_expf_use+set} != xset; then
+ if test "${glibcxx_cv_func_expf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ expf(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_expf_use=yes
+else
+ glibcxx_cv_func_expf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_expf_use" >&5
+$as_echo "$glibcxx_cv_func_expf_use" >&6; }
+
+ if test x$glibcxx_cv_func_expf_use = x"yes"; then
+ for ac_func in expf
+do :
+ ac_fn_c_check_func "$LINENO" "expf" "ac_cv_func_expf"
+if test "x$ac_cv_func_expf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_EXPF 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _expf declaration" >&5
+$as_echo_n "checking for _expf declaration... " >&6; }
+ if test x${glibcxx_cv_func__expf_use+set} != xset; then
+ if test "${glibcxx_cv_func__expf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _expf(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__expf_use=yes
+else
+ glibcxx_cv_func__expf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__expf_use" >&5
+$as_echo "$glibcxx_cv_func__expf_use" >&6; }
+
+ if test x$glibcxx_cv_func__expf_use = x"yes"; then
+ for ac_func in _expf
+do :
+ ac_fn_c_check_func "$LINENO" "_expf" "ac_cv_func__expf"
+if test "x$ac_cv_func__expf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__EXPF 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for isnanf declaration" >&5
+$as_echo_n "checking for isnanf declaration... " >&6; }
+ if test x${glibcxx_cv_func_isnanf_use+set} != xset; then
+ if test "${glibcxx_cv_func_isnanf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ isnanf(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_isnanf_use=yes
+else
+ glibcxx_cv_func_isnanf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_isnanf_use" >&5
+$as_echo "$glibcxx_cv_func_isnanf_use" >&6; }
+
+ if test x$glibcxx_cv_func_isnanf_use = x"yes"; then
+ for ac_func in isnanf
+do :
+ ac_fn_c_check_func "$LINENO" "isnanf" "ac_cv_func_isnanf"
+if test "x$ac_cv_func_isnanf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_ISNANF 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _isnanf declaration" >&5
+$as_echo_n "checking for _isnanf declaration... " >&6; }
+ if test x${glibcxx_cv_func__isnanf_use+set} != xset; then
+ if test "${glibcxx_cv_func__isnanf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _isnanf(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__isnanf_use=yes
+else
+ glibcxx_cv_func__isnanf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__isnanf_use" >&5
+$as_echo "$glibcxx_cv_func__isnanf_use" >&6; }
+
+ if test x$glibcxx_cv_func__isnanf_use = x"yes"; then
+ for ac_func in _isnanf
+do :
+ ac_fn_c_check_func "$LINENO" "_isnanf" "ac_cv_func__isnanf"
+if test "x$ac_cv_func__isnanf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__ISNANF 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for isinff declaration" >&5
+$as_echo_n "checking for isinff declaration... " >&6; }
+ if test x${glibcxx_cv_func_isinff_use+set} != xset; then
+ if test "${glibcxx_cv_func_isinff_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ isinff(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_isinff_use=yes
+else
+ glibcxx_cv_func_isinff_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_isinff_use" >&5
+$as_echo "$glibcxx_cv_func_isinff_use" >&6; }
+
+ if test x$glibcxx_cv_func_isinff_use = x"yes"; then
+ for ac_func in isinff
+do :
+ ac_fn_c_check_func "$LINENO" "isinff" "ac_cv_func_isinff"
+if test "x$ac_cv_func_isinff" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_ISINFF 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _isinff declaration" >&5
+$as_echo_n "checking for _isinff declaration... " >&6; }
+ if test x${glibcxx_cv_func__isinff_use+set} != xset; then
+ if test "${glibcxx_cv_func__isinff_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _isinff(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__isinff_use=yes
+else
+ glibcxx_cv_func__isinff_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__isinff_use" >&5
+$as_echo "$glibcxx_cv_func__isinff_use" >&6; }
+
+ if test x$glibcxx_cv_func__isinff_use = x"yes"; then
+ for ac_func in _isinff
+do :
+ ac_fn_c_check_func "$LINENO" "_isinff" "ac_cv_func__isinff"
+if test "x$ac_cv_func__isinff" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__ISINFF 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for atan2f declaration" >&5
+$as_echo_n "checking for atan2f declaration... " >&6; }
+ if test x${glibcxx_cv_func_atan2f_use+set} != xset; then
+ if test "${glibcxx_cv_func_atan2f_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ atan2f(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_atan2f_use=yes
+else
+ glibcxx_cv_func_atan2f_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_atan2f_use" >&5
+$as_echo "$glibcxx_cv_func_atan2f_use" >&6; }
+
+ if test x$glibcxx_cv_func_atan2f_use = x"yes"; then
+ for ac_func in atan2f
+do :
+ ac_fn_c_check_func "$LINENO" "atan2f" "ac_cv_func_atan2f"
+if test "x$ac_cv_func_atan2f" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_ATAN2F 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _atan2f declaration" >&5
+$as_echo_n "checking for _atan2f declaration... " >&6; }
+ if test x${glibcxx_cv_func__atan2f_use+set} != xset; then
+ if test "${glibcxx_cv_func__atan2f_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _atan2f(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__atan2f_use=yes
+else
+ glibcxx_cv_func__atan2f_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__atan2f_use" >&5
+$as_echo "$glibcxx_cv_func__atan2f_use" >&6; }
+
+ if test x$glibcxx_cv_func__atan2f_use = x"yes"; then
+ for ac_func in _atan2f
+do :
+ ac_fn_c_check_func "$LINENO" "_atan2f" "ac_cv_func__atan2f"
+if test "x$ac_cv_func__atan2f" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__ATAN2F 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fabsf declaration" >&5
+$as_echo_n "checking for fabsf declaration... " >&6; }
+ if test x${glibcxx_cv_func_fabsf_use+set} != xset; then
+ if test "${glibcxx_cv_func_fabsf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ fabsf(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_fabsf_use=yes
+else
+ glibcxx_cv_func_fabsf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_fabsf_use" >&5
+$as_echo "$glibcxx_cv_func_fabsf_use" >&6; }
+
+ if test x$glibcxx_cv_func_fabsf_use = x"yes"; then
+ for ac_func in fabsf
+do :
+ ac_fn_c_check_func "$LINENO" "fabsf" "ac_cv_func_fabsf"
+if test "x$ac_cv_func_fabsf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FABSF 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _fabsf declaration" >&5
+$as_echo_n "checking for _fabsf declaration... " >&6; }
+ if test x${glibcxx_cv_func__fabsf_use+set} != xset; then
+ if test "${glibcxx_cv_func__fabsf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _fabsf(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__fabsf_use=yes
+else
+ glibcxx_cv_func__fabsf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__fabsf_use" >&5
+$as_echo "$glibcxx_cv_func__fabsf_use" >&6; }
+
+ if test x$glibcxx_cv_func__fabsf_use = x"yes"; then
+ for ac_func in _fabsf
+do :
+ ac_fn_c_check_func "$LINENO" "_fabsf" "ac_cv_func__fabsf"
+if test "x$ac_cv_func__fabsf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__FABSF 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fmodf declaration" >&5
+$as_echo_n "checking for fmodf declaration... " >&6; }
+ if test x${glibcxx_cv_func_fmodf_use+set} != xset; then
+ if test "${glibcxx_cv_func_fmodf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ fmodf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_fmodf_use=yes
+else
+ glibcxx_cv_func_fmodf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_fmodf_use" >&5
+$as_echo "$glibcxx_cv_func_fmodf_use" >&6; }
+
+ if test x$glibcxx_cv_func_fmodf_use = x"yes"; then
+ for ac_func in fmodf
+do :
+ ac_fn_c_check_func "$LINENO" "fmodf" "ac_cv_func_fmodf"
+if test "x$ac_cv_func_fmodf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FMODF 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _fmodf declaration" >&5
+$as_echo_n "checking for _fmodf declaration... " >&6; }
+ if test x${glibcxx_cv_func__fmodf_use+set} != xset; then
+ if test "${glibcxx_cv_func__fmodf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _fmodf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__fmodf_use=yes
+else
+ glibcxx_cv_func__fmodf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__fmodf_use" >&5
+$as_echo "$glibcxx_cv_func__fmodf_use" >&6; }
+
+ if test x$glibcxx_cv_func__fmodf_use = x"yes"; then
+ for ac_func in _fmodf
+do :
+ ac_fn_c_check_func "$LINENO" "_fmodf" "ac_cv_func__fmodf"
+if test "x$ac_cv_func__fmodf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__FMODF 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for frexpf declaration" >&5
+$as_echo_n "checking for frexpf declaration... " >&6; }
+ if test x${glibcxx_cv_func_frexpf_use+set} != xset; then
+ if test "${glibcxx_cv_func_frexpf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ frexpf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_frexpf_use=yes
+else
+ glibcxx_cv_func_frexpf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_frexpf_use" >&5
+$as_echo "$glibcxx_cv_func_frexpf_use" >&6; }
+
+ if test x$glibcxx_cv_func_frexpf_use = x"yes"; then
+ for ac_func in frexpf
+do :
+ ac_fn_c_check_func "$LINENO" "frexpf" "ac_cv_func_frexpf"
+if test "x$ac_cv_func_frexpf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FREXPF 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _frexpf declaration" >&5
+$as_echo_n "checking for _frexpf declaration... " >&6; }
+ if test x${glibcxx_cv_func__frexpf_use+set} != xset; then
+ if test "${glibcxx_cv_func__frexpf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _frexpf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__frexpf_use=yes
+else
+ glibcxx_cv_func__frexpf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__frexpf_use" >&5
+$as_echo "$glibcxx_cv_func__frexpf_use" >&6; }
+
+ if test x$glibcxx_cv_func__frexpf_use = x"yes"; then
+ for ac_func in _frexpf
+do :
+ ac_fn_c_check_func "$LINENO" "_frexpf" "ac_cv_func__frexpf"
+if test "x$ac_cv_func__frexpf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__FREXPF 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for hypotf declaration" >&5
+$as_echo_n "checking for hypotf declaration... " >&6; }
+ if test x${glibcxx_cv_func_hypotf_use+set} != xset; then
+ if test "${glibcxx_cv_func_hypotf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ hypotf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_hypotf_use=yes
+else
+ glibcxx_cv_func_hypotf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_hypotf_use" >&5
+$as_echo "$glibcxx_cv_func_hypotf_use" >&6; }
+
+ if test x$glibcxx_cv_func_hypotf_use = x"yes"; then
+ for ac_func in hypotf
+do :
+ ac_fn_c_check_func "$LINENO" "hypotf" "ac_cv_func_hypotf"
+if test "x$ac_cv_func_hypotf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_HYPOTF 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _hypotf declaration" >&5
+$as_echo_n "checking for _hypotf declaration... " >&6; }
+ if test x${glibcxx_cv_func__hypotf_use+set} != xset; then
+ if test "${glibcxx_cv_func__hypotf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _hypotf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__hypotf_use=yes
+else
+ glibcxx_cv_func__hypotf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__hypotf_use" >&5
+$as_echo "$glibcxx_cv_func__hypotf_use" >&6; }
+
+ if test x$glibcxx_cv_func__hypotf_use = x"yes"; then
+ for ac_func in _hypotf
+do :
+ ac_fn_c_check_func "$LINENO" "_hypotf" "ac_cv_func__hypotf"
+if test "x$ac_cv_func__hypotf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__HYPOTF 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldexpf declaration" >&5
+$as_echo_n "checking for ldexpf declaration... " >&6; }
+ if test x${glibcxx_cv_func_ldexpf_use+set} != xset; then
+ if test "${glibcxx_cv_func_ldexpf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ ldexpf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_ldexpf_use=yes
+else
+ glibcxx_cv_func_ldexpf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_ldexpf_use" >&5
+$as_echo "$glibcxx_cv_func_ldexpf_use" >&6; }
+
+ if test x$glibcxx_cv_func_ldexpf_use = x"yes"; then
+ for ac_func in ldexpf
+do :
+ ac_fn_c_check_func "$LINENO" "ldexpf" "ac_cv_func_ldexpf"
+if test "x$ac_cv_func_ldexpf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LDEXPF 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _ldexpf declaration" >&5
+$as_echo_n "checking for _ldexpf declaration... " >&6; }
+ if test x${glibcxx_cv_func__ldexpf_use+set} != xset; then
+ if test "${glibcxx_cv_func__ldexpf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _ldexpf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__ldexpf_use=yes
+else
+ glibcxx_cv_func__ldexpf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__ldexpf_use" >&5
+$as_echo "$glibcxx_cv_func__ldexpf_use" >&6; }
+
+ if test x$glibcxx_cv_func__ldexpf_use = x"yes"; then
+ for ac_func in _ldexpf
+do :
+ ac_fn_c_check_func "$LINENO" "_ldexpf" "ac_cv_func__ldexpf"
+if test "x$ac_cv_func__ldexpf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__LDEXPF 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for logf declaration" >&5
+$as_echo_n "checking for logf declaration... " >&6; }
+ if test x${glibcxx_cv_func_logf_use+set} != xset; then
+ if test "${glibcxx_cv_func_logf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ logf(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_logf_use=yes
+else
+ glibcxx_cv_func_logf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_logf_use" >&5
+$as_echo "$glibcxx_cv_func_logf_use" >&6; }
+
+ if test x$glibcxx_cv_func_logf_use = x"yes"; then
+ for ac_func in logf
+do :
+ ac_fn_c_check_func "$LINENO" "logf" "ac_cv_func_logf"
+if test "x$ac_cv_func_logf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LOGF 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _logf declaration" >&5
+$as_echo_n "checking for _logf declaration... " >&6; }
+ if test x${glibcxx_cv_func__logf_use+set} != xset; then
+ if test "${glibcxx_cv_func__logf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _logf(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__logf_use=yes
+else
+ glibcxx_cv_func__logf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__logf_use" >&5
+$as_echo "$glibcxx_cv_func__logf_use" >&6; }
+
+ if test x$glibcxx_cv_func__logf_use = x"yes"; then
+ for ac_func in _logf
+do :
+ ac_fn_c_check_func "$LINENO" "_logf" "ac_cv_func__logf"
+if test "x$ac_cv_func__logf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__LOGF 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for log10f declaration" >&5
+$as_echo_n "checking for log10f declaration... " >&6; }
+ if test x${glibcxx_cv_func_log10f_use+set} != xset; then
+ if test "${glibcxx_cv_func_log10f_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ log10f(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_log10f_use=yes
+else
+ glibcxx_cv_func_log10f_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_log10f_use" >&5
+$as_echo "$glibcxx_cv_func_log10f_use" >&6; }
+
+ if test x$glibcxx_cv_func_log10f_use = x"yes"; then
+ for ac_func in log10f
+do :
+ ac_fn_c_check_func "$LINENO" "log10f" "ac_cv_func_log10f"
+if test "x$ac_cv_func_log10f" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LOG10F 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _log10f declaration" >&5
+$as_echo_n "checking for _log10f declaration... " >&6; }
+ if test x${glibcxx_cv_func__log10f_use+set} != xset; then
+ if test "${glibcxx_cv_func__log10f_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _log10f(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__log10f_use=yes
+else
+ glibcxx_cv_func__log10f_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__log10f_use" >&5
+$as_echo "$glibcxx_cv_func__log10f_use" >&6; }
+
+ if test x$glibcxx_cv_func__log10f_use = x"yes"; then
+ for ac_func in _log10f
+do :
+ ac_fn_c_check_func "$LINENO" "_log10f" "ac_cv_func__log10f"
+if test "x$ac_cv_func__log10f" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__LOG10F 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for modff declaration" >&5
+$as_echo_n "checking for modff declaration... " >&6; }
+ if test x${glibcxx_cv_func_modff_use+set} != xset; then
+ if test "${glibcxx_cv_func_modff_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ modff(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_modff_use=yes
+else
+ glibcxx_cv_func_modff_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_modff_use" >&5
+$as_echo "$glibcxx_cv_func_modff_use" >&6; }
+
+ if test x$glibcxx_cv_func_modff_use = x"yes"; then
+ for ac_func in modff
+do :
+ ac_fn_c_check_func "$LINENO" "modff" "ac_cv_func_modff"
+if test "x$ac_cv_func_modff" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_MODFF 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _modff declaration" >&5
+$as_echo_n "checking for _modff declaration... " >&6; }
+ if test x${glibcxx_cv_func__modff_use+set} != xset; then
+ if test "${glibcxx_cv_func__modff_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _modff(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__modff_use=yes
+else
+ glibcxx_cv_func__modff_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__modff_use" >&5
+$as_echo "$glibcxx_cv_func__modff_use" >&6; }
+
+ if test x$glibcxx_cv_func__modff_use = x"yes"; then
+ for ac_func in _modff
+do :
+ ac_fn_c_check_func "$LINENO" "_modff" "ac_cv_func__modff"
+if test "x$ac_cv_func__modff" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__MODFF 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for modf declaration" >&5
+$as_echo_n "checking for modf declaration... " >&6; }
+ if test x${glibcxx_cv_func_modf_use+set} != xset; then
+ if test "${glibcxx_cv_func_modf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ modf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_modf_use=yes
+else
+ glibcxx_cv_func_modf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_modf_use" >&5
+$as_echo "$glibcxx_cv_func_modf_use" >&6; }
+
+ if test x$glibcxx_cv_func_modf_use = x"yes"; then
+ for ac_func in modf
+do :
+ ac_fn_c_check_func "$LINENO" "modf" "ac_cv_func_modf"
+if test "x$ac_cv_func_modf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_MODF 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _modf declaration" >&5
+$as_echo_n "checking for _modf declaration... " >&6; }
+ if test x${glibcxx_cv_func__modf_use+set} != xset; then
+ if test "${glibcxx_cv_func__modf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _modf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__modf_use=yes
+else
+ glibcxx_cv_func__modf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__modf_use" >&5
+$as_echo "$glibcxx_cv_func__modf_use" >&6; }
+
+ if test x$glibcxx_cv_func__modf_use = x"yes"; then
+ for ac_func in _modf
+do :
+ ac_fn_c_check_func "$LINENO" "_modf" "ac_cv_func__modf"
+if test "x$ac_cv_func__modf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__MODF 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for powf declaration" >&5
+$as_echo_n "checking for powf declaration... " >&6; }
+ if test x${glibcxx_cv_func_powf_use+set} != xset; then
+ if test "${glibcxx_cv_func_powf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ powf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_powf_use=yes
+else
+ glibcxx_cv_func_powf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_powf_use" >&5
+$as_echo "$glibcxx_cv_func_powf_use" >&6; }
+
+ if test x$glibcxx_cv_func_powf_use = x"yes"; then
+ for ac_func in powf
+do :
+ ac_fn_c_check_func "$LINENO" "powf" "ac_cv_func_powf"
+if test "x$ac_cv_func_powf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_POWF 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _powf declaration" >&5
+$as_echo_n "checking for _powf declaration... " >&6; }
+ if test x${glibcxx_cv_func__powf_use+set} != xset; then
+ if test "${glibcxx_cv_func__powf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _powf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__powf_use=yes
+else
+ glibcxx_cv_func__powf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__powf_use" >&5
+$as_echo "$glibcxx_cv_func__powf_use" >&6; }
+
+ if test x$glibcxx_cv_func__powf_use = x"yes"; then
+ for ac_func in _powf
+do :
+ ac_fn_c_check_func "$LINENO" "_powf" "ac_cv_func__powf"
+if test "x$ac_cv_func__powf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__POWF 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqrtf declaration" >&5
+$as_echo_n "checking for sqrtf declaration... " >&6; }
+ if test x${glibcxx_cv_func_sqrtf_use+set} != xset; then
+ if test "${glibcxx_cv_func_sqrtf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ sqrtf(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_sqrtf_use=yes
+else
+ glibcxx_cv_func_sqrtf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_sqrtf_use" >&5
+$as_echo "$glibcxx_cv_func_sqrtf_use" >&6; }
+
+ if test x$glibcxx_cv_func_sqrtf_use = x"yes"; then
+ for ac_func in sqrtf
+do :
+ ac_fn_c_check_func "$LINENO" "sqrtf" "ac_cv_func_sqrtf"
+if test "x$ac_cv_func_sqrtf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SQRTF 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _sqrtf declaration" >&5
+$as_echo_n "checking for _sqrtf declaration... " >&6; }
+ if test x${glibcxx_cv_func__sqrtf_use+set} != xset; then
+ if test "${glibcxx_cv_func__sqrtf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _sqrtf(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__sqrtf_use=yes
+else
+ glibcxx_cv_func__sqrtf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__sqrtf_use" >&5
+$as_echo "$glibcxx_cv_func__sqrtf_use" >&6; }
+
+ if test x$glibcxx_cv_func__sqrtf_use = x"yes"; then
+ for ac_func in _sqrtf
+do :
+ ac_fn_c_check_func "$LINENO" "_sqrtf" "ac_cv_func__sqrtf"
+if test "x$ac_cv_func__sqrtf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__SQRTF 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sincosf declaration" >&5
+$as_echo_n "checking for sincosf declaration... " >&6; }
+ if test x${glibcxx_cv_func_sincosf_use+set} != xset; then
+ if test "${glibcxx_cv_func_sincosf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ sincosf(0, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_sincosf_use=yes
+else
+ glibcxx_cv_func_sincosf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_sincosf_use" >&5
+$as_echo "$glibcxx_cv_func_sincosf_use" >&6; }
+
+ if test x$glibcxx_cv_func_sincosf_use = x"yes"; then
+ for ac_func in sincosf
+do :
+ ac_fn_c_check_func "$LINENO" "sincosf" "ac_cv_func_sincosf"
+if test "x$ac_cv_func_sincosf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SINCOSF 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _sincosf declaration" >&5
+$as_echo_n "checking for _sincosf declaration... " >&6; }
+ if test x${glibcxx_cv_func__sincosf_use+set} != xset; then
+ if test "${glibcxx_cv_func__sincosf_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _sincosf(0, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__sincosf_use=yes
+else
+ glibcxx_cv_func__sincosf_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__sincosf_use" >&5
+$as_echo "$glibcxx_cv_func__sincosf_use" >&6; }
+
+ if test x$glibcxx_cv_func__sincosf_use = x"yes"; then
+ for ac_func in _sincosf
+do :
+ ac_fn_c_check_func "$LINENO" "_sincosf" "ac_cv_func__sincosf"
+if test "x$ac_cv_func__sincosf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__SINCOSF 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for finitef declaration" >&5
+$as_echo_n "checking for finitef declaration... " >&6; }
+ if test x${glibcxx_cv_func_finitef_use+set} != xset; then
+ if test "${glibcxx_cv_func_finitef_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ finitef(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_finitef_use=yes
+else
+ glibcxx_cv_func_finitef_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_finitef_use" >&5
+$as_echo "$glibcxx_cv_func_finitef_use" >&6; }
+
+ if test x$glibcxx_cv_func_finitef_use = x"yes"; then
+ for ac_func in finitef
+do :
+ ac_fn_c_check_func "$LINENO" "finitef" "ac_cv_func_finitef"
+if test "x$ac_cv_func_finitef" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FINITEF 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _finitef declaration" >&5
+$as_echo_n "checking for _finitef declaration... " >&6; }
+ if test x${glibcxx_cv_func__finitef_use+set} != xset; then
+ if test "${glibcxx_cv_func__finitef_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _finitef(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__finitef_use=yes
+else
+ glibcxx_cv_func__finitef_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__finitef_use" >&5
+$as_echo "$glibcxx_cv_func__finitef_use" >&6; }
+
+ if test x$glibcxx_cv_func__finitef_use = x"yes"; then
+ for ac_func in _finitef
+do :
+ ac_fn_c_check_func "$LINENO" "_finitef" "ac_cv_func__finitef"
+if test "x$ac_cv_func__finitef" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__FINITEF 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double trig functions" >&5
+$as_echo_n "checking for long double trig functions... " >&6; }
+ if test "${glibcxx_cv_func_long_double_trig_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+acosl (0); asinl (0); atanl (0); cosl (0); sinl (0); tanl (0); coshl (0); sinhl (0); tanhl (0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_long_double_trig_use=yes
+else
+ glibcxx_cv_func_long_double_trig_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_long_double_trig_use" >&5
+$as_echo "$glibcxx_cv_func_long_double_trig_use" >&6; }
+ if test x$glibcxx_cv_func_long_double_trig_use = x"yes"; then
+ for ac_func in acosl asinl atanl cosl sinl tanl coshl sinhl tanhl
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _long double trig functions" >&5
+$as_echo_n "checking for _long double trig functions... " >&6; }
+ if test "${glibcxx_cv_func__long_double_trig_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+_acosl (0); _asinl (0); _atanl (0); _cosl (0); _sinl (0); _tanl (0); _coshl (0); _sinhl (0); _tanhl (0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__long_double_trig_use=yes
+else
+ glibcxx_cv_func__long_double_trig_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__long_double_trig_use" >&5
+$as_echo "$glibcxx_cv_func__long_double_trig_use" >&6; }
+ if test x$glibcxx_cv_func__long_double_trig_use = x"yes"; then
+ for ac_func in _acosl _asinl _atanl _cosl _sinl _tanl _coshl _sinhl _tanhl
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double round functions" >&5
+$as_echo_n "checking for long double round functions... " >&6; }
+ if test "${glibcxx_cv_func_long_double_round_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ceill (0); floorl (0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_long_double_round_use=yes
+else
+ glibcxx_cv_func_long_double_round_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_long_double_round_use" >&5
+$as_echo "$glibcxx_cv_func_long_double_round_use" >&6; }
+ if test x$glibcxx_cv_func_long_double_round_use = x"yes"; then
+ for ac_func in ceill floorl
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _long double round functions" >&5
+$as_echo_n "checking for _long double round functions... " >&6; }
+ if test "${glibcxx_cv_func__long_double_round_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+_ceill (0); _floorl (0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__long_double_round_use=yes
+else
+ glibcxx_cv_func__long_double_round_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__long_double_round_use" >&5
+$as_echo "$glibcxx_cv_func__long_double_round_use" >&6; }
+ if test x$glibcxx_cv_func__long_double_round_use = x"yes"; then
+ for ac_func in _ceill _floorl
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for isnanl declaration" >&5
+$as_echo_n "checking for isnanl declaration... " >&6; }
+ if test x${glibcxx_cv_func_isnanl_use+set} != xset; then
+ if test "${glibcxx_cv_func_isnanl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ isnanl(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_isnanl_use=yes
+else
+ glibcxx_cv_func_isnanl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_isnanl_use" >&5
+$as_echo "$glibcxx_cv_func_isnanl_use" >&6; }
+
+ if test x$glibcxx_cv_func_isnanl_use = x"yes"; then
+ for ac_func in isnanl
+do :
+ ac_fn_c_check_func "$LINENO" "isnanl" "ac_cv_func_isnanl"
+if test "x$ac_cv_func_isnanl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_ISNANL 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _isnanl declaration" >&5
+$as_echo_n "checking for _isnanl declaration... " >&6; }
+ if test x${glibcxx_cv_func__isnanl_use+set} != xset; then
+ if test "${glibcxx_cv_func__isnanl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _isnanl(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__isnanl_use=yes
+else
+ glibcxx_cv_func__isnanl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__isnanl_use" >&5
+$as_echo "$glibcxx_cv_func__isnanl_use" >&6; }
+
+ if test x$glibcxx_cv_func__isnanl_use = x"yes"; then
+ for ac_func in _isnanl
+do :
+ ac_fn_c_check_func "$LINENO" "_isnanl" "ac_cv_func__isnanl"
+if test "x$ac_cv_func__isnanl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__ISNANL 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for isinfl declaration" >&5
+$as_echo_n "checking for isinfl declaration... " >&6; }
+ if test x${glibcxx_cv_func_isinfl_use+set} != xset; then
+ if test "${glibcxx_cv_func_isinfl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ isinfl(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_isinfl_use=yes
+else
+ glibcxx_cv_func_isinfl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_isinfl_use" >&5
+$as_echo "$glibcxx_cv_func_isinfl_use" >&6; }
+
+ if test x$glibcxx_cv_func_isinfl_use = x"yes"; then
+ for ac_func in isinfl
+do :
+ ac_fn_c_check_func "$LINENO" "isinfl" "ac_cv_func_isinfl"
+if test "x$ac_cv_func_isinfl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_ISINFL 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _isinfl declaration" >&5
+$as_echo_n "checking for _isinfl declaration... " >&6; }
+ if test x${glibcxx_cv_func__isinfl_use+set} != xset; then
+ if test "${glibcxx_cv_func__isinfl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _isinfl(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__isinfl_use=yes
+else
+ glibcxx_cv_func__isinfl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__isinfl_use" >&5
+$as_echo "$glibcxx_cv_func__isinfl_use" >&6; }
+
+ if test x$glibcxx_cv_func__isinfl_use = x"yes"; then
+ for ac_func in _isinfl
+do :
+ ac_fn_c_check_func "$LINENO" "_isinfl" "ac_cv_func__isinfl"
+if test "x$ac_cv_func__isinfl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__ISINFL 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for atan2l declaration" >&5
+$as_echo_n "checking for atan2l declaration... " >&6; }
+ if test x${glibcxx_cv_func_atan2l_use+set} != xset; then
+ if test "${glibcxx_cv_func_atan2l_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ atan2l(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_atan2l_use=yes
+else
+ glibcxx_cv_func_atan2l_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_atan2l_use" >&5
+$as_echo "$glibcxx_cv_func_atan2l_use" >&6; }
+
+ if test x$glibcxx_cv_func_atan2l_use = x"yes"; then
+ for ac_func in atan2l
+do :
+ ac_fn_c_check_func "$LINENO" "atan2l" "ac_cv_func_atan2l"
+if test "x$ac_cv_func_atan2l" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_ATAN2L 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _atan2l declaration" >&5
+$as_echo_n "checking for _atan2l declaration... " >&6; }
+ if test x${glibcxx_cv_func__atan2l_use+set} != xset; then
+ if test "${glibcxx_cv_func__atan2l_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _atan2l(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__atan2l_use=yes
+else
+ glibcxx_cv_func__atan2l_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__atan2l_use" >&5
+$as_echo "$glibcxx_cv_func__atan2l_use" >&6; }
+
+ if test x$glibcxx_cv_func__atan2l_use = x"yes"; then
+ for ac_func in _atan2l
+do :
+ ac_fn_c_check_func "$LINENO" "_atan2l" "ac_cv_func__atan2l"
+if test "x$ac_cv_func__atan2l" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__ATAN2L 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for expl declaration" >&5
+$as_echo_n "checking for expl declaration... " >&6; }
+ if test x${glibcxx_cv_func_expl_use+set} != xset; then
+ if test "${glibcxx_cv_func_expl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ expl(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_expl_use=yes
+else
+ glibcxx_cv_func_expl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_expl_use" >&5
+$as_echo "$glibcxx_cv_func_expl_use" >&6; }
+
+ if test x$glibcxx_cv_func_expl_use = x"yes"; then
+ for ac_func in expl
+do :
+ ac_fn_c_check_func "$LINENO" "expl" "ac_cv_func_expl"
+if test "x$ac_cv_func_expl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_EXPL 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _expl declaration" >&5
+$as_echo_n "checking for _expl declaration... " >&6; }
+ if test x${glibcxx_cv_func__expl_use+set} != xset; then
+ if test "${glibcxx_cv_func__expl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _expl(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__expl_use=yes
+else
+ glibcxx_cv_func__expl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__expl_use" >&5
+$as_echo "$glibcxx_cv_func__expl_use" >&6; }
+
+ if test x$glibcxx_cv_func__expl_use = x"yes"; then
+ for ac_func in _expl
+do :
+ ac_fn_c_check_func "$LINENO" "_expl" "ac_cv_func__expl"
+if test "x$ac_cv_func__expl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__EXPL 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fabsl declaration" >&5
+$as_echo_n "checking for fabsl declaration... " >&6; }
+ if test x${glibcxx_cv_func_fabsl_use+set} != xset; then
+ if test "${glibcxx_cv_func_fabsl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ fabsl(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_fabsl_use=yes
+else
+ glibcxx_cv_func_fabsl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_fabsl_use" >&5
+$as_echo "$glibcxx_cv_func_fabsl_use" >&6; }
+
+ if test x$glibcxx_cv_func_fabsl_use = x"yes"; then
+ for ac_func in fabsl
+do :
+ ac_fn_c_check_func "$LINENO" "fabsl" "ac_cv_func_fabsl"
+if test "x$ac_cv_func_fabsl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FABSL 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _fabsl declaration" >&5
+$as_echo_n "checking for _fabsl declaration... " >&6; }
+ if test x${glibcxx_cv_func__fabsl_use+set} != xset; then
+ if test "${glibcxx_cv_func__fabsl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _fabsl(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__fabsl_use=yes
+else
+ glibcxx_cv_func__fabsl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__fabsl_use" >&5
+$as_echo "$glibcxx_cv_func__fabsl_use" >&6; }
+
+ if test x$glibcxx_cv_func__fabsl_use = x"yes"; then
+ for ac_func in _fabsl
+do :
+ ac_fn_c_check_func "$LINENO" "_fabsl" "ac_cv_func__fabsl"
+if test "x$ac_cv_func__fabsl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__FABSL 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fmodl declaration" >&5
+$as_echo_n "checking for fmodl declaration... " >&6; }
+ if test x${glibcxx_cv_func_fmodl_use+set} != xset; then
+ if test "${glibcxx_cv_func_fmodl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ fmodl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_fmodl_use=yes
+else
+ glibcxx_cv_func_fmodl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_fmodl_use" >&5
+$as_echo "$glibcxx_cv_func_fmodl_use" >&6; }
+
+ if test x$glibcxx_cv_func_fmodl_use = x"yes"; then
+ for ac_func in fmodl
+do :
+ ac_fn_c_check_func "$LINENO" "fmodl" "ac_cv_func_fmodl"
+if test "x$ac_cv_func_fmodl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FMODL 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _fmodl declaration" >&5
+$as_echo_n "checking for _fmodl declaration... " >&6; }
+ if test x${glibcxx_cv_func__fmodl_use+set} != xset; then
+ if test "${glibcxx_cv_func__fmodl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _fmodl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__fmodl_use=yes
+else
+ glibcxx_cv_func__fmodl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__fmodl_use" >&5
+$as_echo "$glibcxx_cv_func__fmodl_use" >&6; }
+
+ if test x$glibcxx_cv_func__fmodl_use = x"yes"; then
+ for ac_func in _fmodl
+do :
+ ac_fn_c_check_func "$LINENO" "_fmodl" "ac_cv_func__fmodl"
+if test "x$ac_cv_func__fmodl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__FMODL 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for frexpl declaration" >&5
+$as_echo_n "checking for frexpl declaration... " >&6; }
+ if test x${glibcxx_cv_func_frexpl_use+set} != xset; then
+ if test "${glibcxx_cv_func_frexpl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ frexpl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_frexpl_use=yes
+else
+ glibcxx_cv_func_frexpl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_frexpl_use" >&5
+$as_echo "$glibcxx_cv_func_frexpl_use" >&6; }
+
+ if test x$glibcxx_cv_func_frexpl_use = x"yes"; then
+ for ac_func in frexpl
+do :
+ ac_fn_c_check_func "$LINENO" "frexpl" "ac_cv_func_frexpl"
+if test "x$ac_cv_func_frexpl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FREXPL 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _frexpl declaration" >&5
+$as_echo_n "checking for _frexpl declaration... " >&6; }
+ if test x${glibcxx_cv_func__frexpl_use+set} != xset; then
+ if test "${glibcxx_cv_func__frexpl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _frexpl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__frexpl_use=yes
+else
+ glibcxx_cv_func__frexpl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__frexpl_use" >&5
+$as_echo "$glibcxx_cv_func__frexpl_use" >&6; }
+
+ if test x$glibcxx_cv_func__frexpl_use = x"yes"; then
+ for ac_func in _frexpl
+do :
+ ac_fn_c_check_func "$LINENO" "_frexpl" "ac_cv_func__frexpl"
+if test "x$ac_cv_func__frexpl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__FREXPL 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for hypotl declaration" >&5
+$as_echo_n "checking for hypotl declaration... " >&6; }
+ if test x${glibcxx_cv_func_hypotl_use+set} != xset; then
+ if test "${glibcxx_cv_func_hypotl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ hypotl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_hypotl_use=yes
+else
+ glibcxx_cv_func_hypotl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_hypotl_use" >&5
+$as_echo "$glibcxx_cv_func_hypotl_use" >&6; }
+
+ if test x$glibcxx_cv_func_hypotl_use = x"yes"; then
+ for ac_func in hypotl
+do :
+ ac_fn_c_check_func "$LINENO" "hypotl" "ac_cv_func_hypotl"
+if test "x$ac_cv_func_hypotl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_HYPOTL 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _hypotl declaration" >&5
+$as_echo_n "checking for _hypotl declaration... " >&6; }
+ if test x${glibcxx_cv_func__hypotl_use+set} != xset; then
+ if test "${glibcxx_cv_func__hypotl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _hypotl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__hypotl_use=yes
+else
+ glibcxx_cv_func__hypotl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__hypotl_use" >&5
+$as_echo "$glibcxx_cv_func__hypotl_use" >&6; }
+
+ if test x$glibcxx_cv_func__hypotl_use = x"yes"; then
+ for ac_func in _hypotl
+do :
+ ac_fn_c_check_func "$LINENO" "_hypotl" "ac_cv_func__hypotl"
+if test "x$ac_cv_func__hypotl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__HYPOTL 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldexpl declaration" >&5
+$as_echo_n "checking for ldexpl declaration... " >&6; }
+ if test x${glibcxx_cv_func_ldexpl_use+set} != xset; then
+ if test "${glibcxx_cv_func_ldexpl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ ldexpl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_ldexpl_use=yes
+else
+ glibcxx_cv_func_ldexpl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_ldexpl_use" >&5
+$as_echo "$glibcxx_cv_func_ldexpl_use" >&6; }
+
+ if test x$glibcxx_cv_func_ldexpl_use = x"yes"; then
+ for ac_func in ldexpl
+do :
+ ac_fn_c_check_func "$LINENO" "ldexpl" "ac_cv_func_ldexpl"
+if test "x$ac_cv_func_ldexpl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LDEXPL 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _ldexpl declaration" >&5
+$as_echo_n "checking for _ldexpl declaration... " >&6; }
+ if test x${glibcxx_cv_func__ldexpl_use+set} != xset; then
+ if test "${glibcxx_cv_func__ldexpl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _ldexpl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__ldexpl_use=yes
+else
+ glibcxx_cv_func__ldexpl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__ldexpl_use" >&5
+$as_echo "$glibcxx_cv_func__ldexpl_use" >&6; }
+
+ if test x$glibcxx_cv_func__ldexpl_use = x"yes"; then
+ for ac_func in _ldexpl
+do :
+ ac_fn_c_check_func "$LINENO" "_ldexpl" "ac_cv_func__ldexpl"
+if test "x$ac_cv_func__ldexpl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__LDEXPL 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for logl declaration" >&5
+$as_echo_n "checking for logl declaration... " >&6; }
+ if test x${glibcxx_cv_func_logl_use+set} != xset; then
+ if test "${glibcxx_cv_func_logl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ logl(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_logl_use=yes
+else
+ glibcxx_cv_func_logl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_logl_use" >&5
+$as_echo "$glibcxx_cv_func_logl_use" >&6; }
+
+ if test x$glibcxx_cv_func_logl_use = x"yes"; then
+ for ac_func in logl
+do :
+ ac_fn_c_check_func "$LINENO" "logl" "ac_cv_func_logl"
+if test "x$ac_cv_func_logl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LOGL 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _logl declaration" >&5
+$as_echo_n "checking for _logl declaration... " >&6; }
+ if test x${glibcxx_cv_func__logl_use+set} != xset; then
+ if test "${glibcxx_cv_func__logl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _logl(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__logl_use=yes
+else
+ glibcxx_cv_func__logl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__logl_use" >&5
+$as_echo "$glibcxx_cv_func__logl_use" >&6; }
+
+ if test x$glibcxx_cv_func__logl_use = x"yes"; then
+ for ac_func in _logl
+do :
+ ac_fn_c_check_func "$LINENO" "_logl" "ac_cv_func__logl"
+if test "x$ac_cv_func__logl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__LOGL 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for log10l declaration" >&5
+$as_echo_n "checking for log10l declaration... " >&6; }
+ if test x${glibcxx_cv_func_log10l_use+set} != xset; then
+ if test "${glibcxx_cv_func_log10l_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ log10l(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_log10l_use=yes
+else
+ glibcxx_cv_func_log10l_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_log10l_use" >&5
+$as_echo "$glibcxx_cv_func_log10l_use" >&6; }
+
+ if test x$glibcxx_cv_func_log10l_use = x"yes"; then
+ for ac_func in log10l
+do :
+ ac_fn_c_check_func "$LINENO" "log10l" "ac_cv_func_log10l"
+if test "x$ac_cv_func_log10l" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LOG10L 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _log10l declaration" >&5
+$as_echo_n "checking for _log10l declaration... " >&6; }
+ if test x${glibcxx_cv_func__log10l_use+set} != xset; then
+ if test "${glibcxx_cv_func__log10l_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _log10l(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__log10l_use=yes
+else
+ glibcxx_cv_func__log10l_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__log10l_use" >&5
+$as_echo "$glibcxx_cv_func__log10l_use" >&6; }
+
+ if test x$glibcxx_cv_func__log10l_use = x"yes"; then
+ for ac_func in _log10l
+do :
+ ac_fn_c_check_func "$LINENO" "_log10l" "ac_cv_func__log10l"
+if test "x$ac_cv_func__log10l" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__LOG10L 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for modfl declaration" >&5
+$as_echo_n "checking for modfl declaration... " >&6; }
+ if test x${glibcxx_cv_func_modfl_use+set} != xset; then
+ if test "${glibcxx_cv_func_modfl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ modfl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_modfl_use=yes
+else
+ glibcxx_cv_func_modfl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_modfl_use" >&5
+$as_echo "$glibcxx_cv_func_modfl_use" >&6; }
+
+ if test x$glibcxx_cv_func_modfl_use = x"yes"; then
+ for ac_func in modfl
+do :
+ ac_fn_c_check_func "$LINENO" "modfl" "ac_cv_func_modfl"
+if test "x$ac_cv_func_modfl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_MODFL 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _modfl declaration" >&5
+$as_echo_n "checking for _modfl declaration... " >&6; }
+ if test x${glibcxx_cv_func__modfl_use+set} != xset; then
+ if test "${glibcxx_cv_func__modfl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _modfl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__modfl_use=yes
+else
+ glibcxx_cv_func__modfl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__modfl_use" >&5
+$as_echo "$glibcxx_cv_func__modfl_use" >&6; }
+
+ if test x$glibcxx_cv_func__modfl_use = x"yes"; then
+ for ac_func in _modfl
+do :
+ ac_fn_c_check_func "$LINENO" "_modfl" "ac_cv_func__modfl"
+if test "x$ac_cv_func__modfl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__MODFL 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for powl declaration" >&5
+$as_echo_n "checking for powl declaration... " >&6; }
+ if test x${glibcxx_cv_func_powl_use+set} != xset; then
+ if test "${glibcxx_cv_func_powl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ powl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_powl_use=yes
+else
+ glibcxx_cv_func_powl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_powl_use" >&5
+$as_echo "$glibcxx_cv_func_powl_use" >&6; }
+
+ if test x$glibcxx_cv_func_powl_use = x"yes"; then
+ for ac_func in powl
+do :
+ ac_fn_c_check_func "$LINENO" "powl" "ac_cv_func_powl"
+if test "x$ac_cv_func_powl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_POWL 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _powl declaration" >&5
+$as_echo_n "checking for _powl declaration... " >&6; }
+ if test x${glibcxx_cv_func__powl_use+set} != xset; then
+ if test "${glibcxx_cv_func__powl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _powl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__powl_use=yes
+else
+ glibcxx_cv_func__powl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__powl_use" >&5
+$as_echo "$glibcxx_cv_func__powl_use" >&6; }
+
+ if test x$glibcxx_cv_func__powl_use = x"yes"; then
+ for ac_func in _powl
+do :
+ ac_fn_c_check_func "$LINENO" "_powl" "ac_cv_func__powl"
+if test "x$ac_cv_func__powl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__POWL 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqrtl declaration" >&5
+$as_echo_n "checking for sqrtl declaration... " >&6; }
+ if test x${glibcxx_cv_func_sqrtl_use+set} != xset; then
+ if test "${glibcxx_cv_func_sqrtl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ sqrtl(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_sqrtl_use=yes
+else
+ glibcxx_cv_func_sqrtl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_sqrtl_use" >&5
+$as_echo "$glibcxx_cv_func_sqrtl_use" >&6; }
+
+ if test x$glibcxx_cv_func_sqrtl_use = x"yes"; then
+ for ac_func in sqrtl
+do :
+ ac_fn_c_check_func "$LINENO" "sqrtl" "ac_cv_func_sqrtl"
+if test "x$ac_cv_func_sqrtl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SQRTL 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _sqrtl declaration" >&5
+$as_echo_n "checking for _sqrtl declaration... " >&6; }
+ if test x${glibcxx_cv_func__sqrtl_use+set} != xset; then
+ if test "${glibcxx_cv_func__sqrtl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _sqrtl(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__sqrtl_use=yes
+else
+ glibcxx_cv_func__sqrtl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__sqrtl_use" >&5
+$as_echo "$glibcxx_cv_func__sqrtl_use" >&6; }
+
+ if test x$glibcxx_cv_func__sqrtl_use = x"yes"; then
+ for ac_func in _sqrtl
+do :
+ ac_fn_c_check_func "$LINENO" "_sqrtl" "ac_cv_func__sqrtl"
+if test "x$ac_cv_func__sqrtl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__SQRTL 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sincosl declaration" >&5
+$as_echo_n "checking for sincosl declaration... " >&6; }
+ if test x${glibcxx_cv_func_sincosl_use+set} != xset; then
+ if test "${glibcxx_cv_func_sincosl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ sincosl(0, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_sincosl_use=yes
+else
+ glibcxx_cv_func_sincosl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_sincosl_use" >&5
+$as_echo "$glibcxx_cv_func_sincosl_use" >&6; }
+
+ if test x$glibcxx_cv_func_sincosl_use = x"yes"; then
+ for ac_func in sincosl
+do :
+ ac_fn_c_check_func "$LINENO" "sincosl" "ac_cv_func_sincosl"
+if test "x$ac_cv_func_sincosl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SINCOSL 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _sincosl declaration" >&5
+$as_echo_n "checking for _sincosl declaration... " >&6; }
+ if test x${glibcxx_cv_func__sincosl_use+set} != xset; then
+ if test "${glibcxx_cv_func__sincosl_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _sincosl(0, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__sincosl_use=yes
+else
+ glibcxx_cv_func__sincosl_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__sincosl_use" >&5
+$as_echo "$glibcxx_cv_func__sincosl_use" >&6; }
+
+ if test x$glibcxx_cv_func__sincosl_use = x"yes"; then
+ for ac_func in _sincosl
+do :
+ ac_fn_c_check_func "$LINENO" "_sincosl" "ac_cv_func__sincosl"
+if test "x$ac_cv_func__sincosl" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__SINCOSL 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for finitel declaration" >&5
+$as_echo_n "checking for finitel declaration... " >&6; }
+ if test x${glibcxx_cv_func_finitel_use+set} != xset; then
+ if test "${glibcxx_cv_func_finitel_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ finitel(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_finitel_use=yes
+else
+ glibcxx_cv_func_finitel_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_finitel_use" >&5
+$as_echo "$glibcxx_cv_func_finitel_use" >&6; }
+
+ if test x$glibcxx_cv_func_finitel_use = x"yes"; then
+ for ac_func in finitel
+do :
+ ac_fn_c_check_func "$LINENO" "finitel" "ac_cv_func_finitel"
+if test "x$ac_cv_func_finitel" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FINITEL 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _finitel declaration" >&5
+$as_echo_n "checking for _finitel declaration... " >&6; }
+ if test x${glibcxx_cv_func__finitel_use+set} != xset; then
+ if test "${glibcxx_cv_func__finitel_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _finitel(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func__finitel_use=yes
+else
+ glibcxx_cv_func__finitel_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func__finitel_use" >&5
+$as_echo "$glibcxx_cv_func__finitel_use" >&6; }
+
+ if test x$glibcxx_cv_func__finitel_use = x"yes"; then
+ for ac_func in _finitel
+do :
+ ac_fn_c_check_func "$LINENO" "_finitel" "ac_cv_func__finitel"
+if test "x$ac_cv_func__finitel" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__FINITEL 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+ LIBS="$ac_save_LIBS"
+ CXXFLAGS="$ac_save_CXXFLAGS"
+
+
+ ac_test_CXXFLAGS="${CXXFLAGS+set}"
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS='-fno-builtin -D_GNU_SOURCE'
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strtold declaration" >&5
+$as_echo_n "checking for strtold declaration... " >&6; }
+ if test x${glibcxx_cv_func_strtold_use+set} != xset; then
+ if test "${glibcxx_cv_func_strtold_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+int
+main ()
+{
+ strtold(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_strtold_use=yes
+else
+ glibcxx_cv_func_strtold_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_strtold_use" >&5
+$as_echo "$glibcxx_cv_func_strtold_use" >&6; }
+ if test x$glibcxx_cv_func_strtold_use = x"yes"; then
+ for ac_func in strtold
+do :
+ ac_fn_c_check_func "$LINENO" "strtold" "ac_cv_func_strtold"
+if test "x$ac_cv_func_strtold" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STRTOLD 1
+_ACEOF
+
+fi
+done
+
+ fi
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strtof declaration" >&5
+$as_echo_n "checking for strtof declaration... " >&6; }
+ if test x${glibcxx_cv_func_strtof_use+set} != xset; then
+ if test "${glibcxx_cv_func_strtof_use+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+int
+main ()
+{
+ strtof(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ glibcxx_cv_func_strtof_use=yes
+else
+ glibcxx_cv_func_strtof_use=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_func_strtof_use" >&5
+$as_echo "$glibcxx_cv_func_strtof_use" >&6; }
+ if test x$glibcxx_cv_func_strtof_use = x"yes"; then
+ for ac_func in strtof
+do :
+ ac_fn_c_check_func "$LINENO" "strtof" "ac_cv_func_strtof"
+if test "x$ac_cv_func_strtof" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STRTOF 1
+_ACEOF
+
+fi
+done
+
+ fi
+
+
+
+
+ CXXFLAGS="$ac_save_CXXFLAGS"
+
+ ;;
*-vxworks)
$as_echo "#define HAVE_ACOSF 1" >>confdefs.h
diff --git a/libstdc++-v3/crossconfig.m4 b/libstdc++-v3/crossconfig.m4
index 3850879b67a..e208fbf13a0 100644
--- a/libstdc++-v3/crossconfig.m4
+++ b/libstdc++-v3/crossconfig.m4
@@ -241,6 +241,12 @@ case "${host}" in
AC_DEFINE(HAVE_ISNANL)
fi
;;
+ *-*vms*)
+ # Check for available headers.
+ # Don't call GLIBCXX_CHECK_LINKER_FEATURES, VMS doesn't have a GNU ld
+ GLIBCXX_CHECK_MATH_SUPPORT
+ GLIBCXX_CHECK_STDLIB_SUPPORT
+ ;;
*-vxworks)
AC_DEFINE(HAVE_ACOSF)
AC_DEFINE(HAVE_ASINF)
diff --git a/libstdc++-v3/include/bits/deque.tcc b/libstdc++-v3/include/bits/deque.tcc
index 5b56875b493..fcece60c8bb 100644
--- a/libstdc++-v3/include/bits/deque.tcc
+++ b/libstdc++-v3/include/bits/deque.tcc
@@ -1,7 +1,7 @@
// Deque implementation (out of line) -*- C++ -*-
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-// 2009, 2010, 2011
+// 2009, 2010, 2011, 2012
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -175,12 +175,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
if (__position._M_cur == this->_M_impl._M_start._M_cur)
{
- push_front(std::forward<_Args>(__args)...);
+ emplace_front(std::forward<_Args>(__args)...);
return this->_M_impl._M_start;
}
else if (__position._M_cur == this->_M_impl._M_finish._M_cur)
{
- push_back(std::forward<_Args>(__args)...);
+ emplace_back(std::forward<_Args>(__args)...);
iterator __tmp = this->_M_impl._M_finish;
--__tmp;
return __tmp;
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index 239f8b9dd36..31660d3a22f 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -428,36 +428,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @brief %Vector move assignment operator.
* @param __x A %vector of identical element and allocator types.
*
- * The contents of @a __x are moved into this %vector (without copying).
+ * The contents of @a __x are moved into this %vector (without copying,
+ * if the allocators permit it).
* @a __x is a valid, but unspecified %vector.
*/
vector&
operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
{
- if (_Alloc_traits::_S_propagate_on_move_assign())
- {
- // We're moving the rvalue's allocator so can move the data too.
- const vector __tmp(std::move(*this)); // discard existing data
- this->_M_impl._M_swap_data(__x._M_impl);
- std::__alloc_on_move(_M_get_Tp_allocator(),
- __x._M_get_Tp_allocator());
- }
- else if (_Alloc_traits::_S_always_equal()
- || __x._M_get_Tp_allocator() == this->_M_get_Tp_allocator())
- {
- // The rvalue's allocator can free our storage and vice versa,
- // so can swap the data storage after destroying our contents.
- this->clear();
- this->_M_impl._M_swap_data(__x._M_impl);
- }
- else
- {
- // The rvalue's allocator cannot be moved, or is not equal,
- // so we need to individually move each element.
- this->assign(std::__make_move_if_noexcept_iterator(__x.begin()),
- std::__make_move_if_noexcept_iterator(__x.end()));
- __x.clear();
- }
+ constexpr bool __move_storage =
+ _Alloc_traits::_S_propagate_on_move_assign()
+ || _Alloc_traits::_S_always_equal();
+ _M_move_assign(std::move(__x),
+ integral_constant<bool, __move_storage>());
return *this;
}
@@ -1363,6 +1345,39 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
std::_Destroy(__pos, this->_M_impl._M_finish, _M_get_Tp_allocator());
this->_M_impl._M_finish = __pos;
}
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ private:
+ // Constant-time move assignment when source object's memory can be
+ // moved, either because the source's allocator will move too
+ // or because the allocators are equal.
+ void
+ _M_move_assign(vector&& __x, std::true_type) noexcept
+ {
+ const vector __tmp(std::move(*this));
+ this->_M_impl._M_swap_data(__x._M_impl);
+ if (_Alloc_traits::_S_propagate_on_move_assign())
+ std::__alloc_on_move(_M_get_Tp_allocator(),
+ __x._M_get_Tp_allocator());
+ }
+
+ // Do move assignment when it might not be possible to move source
+ // object's memory, resulting in a linear-time operation.
+ void
+ _M_move_assign(vector&& __x, std::false_type)
+ {
+ if (__x._M_get_Tp_allocator() == this->_M_get_Tp_allocator())
+ _M_move_assign(std::move(__x), std::true_type());
+ else
+ {
+ // The rvalue's allocator cannot be moved and is not equal,
+ // so we need to individually move each element.
+ this->assign(std::__make_move_if_noexcept_iterator(__x.begin()),
+ std::__make_move_if_noexcept_iterator(__x.end()));
+ __x.clear();
+ }
+ }
+#endif
};
diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional
index 14785dd57b7..980c6ab40e7 100644
--- a/libstdc++-v3/include/std/functional
+++ b/libstdc++-v3/include/std/functional
@@ -1716,6 +1716,16 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
__callable_functor(_Member _Class::* const &__p)
{ return std::mem_fn(__p); }
+ template<typename _Member, typename _Class>
+ inline _Mem_fn<_Member _Class::*>
+ __callable_functor(_Member _Class::* volatile &__p)
+ { return std::mem_fn(__p); }
+
+ template<typename _Member, typename _Class>
+ inline _Mem_fn<_Member _Class::*>
+ __callable_functor(_Member _Class::* const volatile &__p)
+ { return std::mem_fn(__p); }
+
template<typename _Signature>
class function;
diff --git a/libstdc++-v3/testsuite/20_util/function/10.cc b/libstdc++-v3/testsuite/20_util/function/10.cc
new file mode 100644
index 00000000000..3776f397180
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/function/10.cc
@@ -0,0 +1,37 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+//
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 20.8.11 polymorphic function object wrapper
+
+#include <functional>
+
+struct X { void f() { } };
+
+void (X::*p)() = &X::f;
+void (X::* volatile& vp)() = p;
+
+typedef std::function<void(X&)> function_type;
+
+void test01()
+{
+ function_type f( vp );
+ function_type f2( std::ref(vp) );
+ function_type f3( std::cref(vp) );
+}
diff --git a/libstdc++-v3/testsuite/23_containers/deque/modifiers/emplace/52799.cc b/libstdc++-v3/testsuite/23_containers/deque/modifiers/emplace/52799.cc
new file mode 100644
index 00000000000..35c4c44ef90
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/deque/modifiers/emplace/52799.cc
@@ -0,0 +1,28 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <deque>
+
+// libstdc++/52799
+int main()
+{
+ std::deque<int> d;
+ d.emplace(d.begin());
+}
diff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/emplace/52799.cc b/libstdc++-v3/testsuite/23_containers/list/modifiers/emplace/52799.cc
new file mode 100644
index 00000000000..314dd4a8044
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/emplace/52799.cc
@@ -0,0 +1,28 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <list>
+
+// libstdc++/52799
+int main()
+{
+ std::list<int> l;
+ l.emplace(l.begin());
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/52591.cc b/libstdc++-v3/testsuite/23_containers/vector/52591.cc
new file mode 100644
index 00000000000..c018c726880
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/52591.cc
@@ -0,0 +1,38 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+
+// libstdc++/52591
+
+#include <vector>
+
+// As an extension we allow move-assignment of std::vector when the element
+// type is not MoveAssignable, as long as the allocator type propagates or
+// is known to always compare equal.
+
+struct C
+{
+ C& operator=(C&&) = delete;
+};
+
+void test01()
+{
+ std::vector<C> a;
+ a = std::vector<C>();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/emplace/52799.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/emplace/52799.cc
new file mode 100644
index 00000000000..f43057e968c
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/emplace/52799.cc
@@ -0,0 +1,28 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <vector>
+
+// libstdc++/52799
+int main()
+{
+ std::vector<int> v;
+ v.emplace(v.begin());
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
index 73de8aed9e8..644750ccfe6 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
@@ -18,7 +18,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1251 }
+// { dg-error "no matching" "" { target *-*-* } 1233 }
#include <vector>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
index fa479c73094..bbd4cfe1829 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
@@ -18,7 +18,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1181 }
+// { dg-error "no matching" "" { target *-*-* } 1163 }
#include <vector>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
index 231cacebb97..d2282ccc05e 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
@@ -18,7 +18,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1181 }
+// { dg-error "no matching" "" { target *-*-* } 1163 }
#include <vector>
#include <utility>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
index b8e18bb4d4b..d2cde66953d 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
@@ -18,7 +18,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1292 }
+// { dg-error "no matching" "" { target *-*-* } 1274 }
#include <vector>